diff --git a/filter/iir.c b/filter/iir.c index 3a6c63b..18d7c5c 100644 --- a/filter/iir.c +++ b/filter/iir.c @@ -15,17 +15,24 @@ inline float apply_preemphasis(ResistorCapacitor *filter, float sample) { return out; } -void tilt_init(TiltCorrectionFilter* filter, float correction_strength) { - filter->tilt = correction_strength; - filter->prev_in = 0.0f; - filter->prev_out = 0.0f; +void tilt_init(TiltCorrectionFilter* f, float correction_strength, float sr) { + float cutoff = 1000.0f; // fixed split point + + // one-pole lowpass setup + float alpha = expf(-2.0f * (float)M_PI * cutoff / sr); + f->a1 = alpha; + f->a0 = 1.0f - alpha; + f->lp = 0.0f; + + // simple low/high gains from tilt + float t = (tilt < -1.0f) ? -1.0f : (tilt > 1.0f ? 1.0f : tilt); + f->low_gain = 1.0f - t; + f->high_gain = 1.0f + t; } -float tilt(TiltCorrectionFilter* filter, float input) { - float out = input + filter->tilt * (input - filter->prev_in); - - filter->prev_in = input; - filter->prev_out = out; - - return out; +float tilt(TiltCorrectionFilter* f, float in) { + // lowpass + f->lp = f->a0 * in + f->a1 * f->lp; + float hp = in - f->lp; + return f->lp * f->low_gain + hp * f->high_gain; } \ No newline at end of file diff --git a/filter/iir.h b/filter/iir.h index 5d925f0..16283f3 100644 --- a/filter/iir.h +++ b/filter/iir.h @@ -14,10 +14,11 @@ void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate, f float apply_preemphasis(ResistorCapacitor *filter, float sample); typedef struct { - float tilt; // Tilt amount (-1.0 to +1.0 typical) - float prev_in; // Previous input sample - float prev_out; // Previous output sample + float a0, a1; // lowpass coeffs + float lp; // lowpass state + float low_gain; // gain for low frequencies + float high_gain; // gain for high frequencies } TiltCorrectionFilter; -void tilt_init(TiltCorrectionFilter* filter, float alpha); -float tilt(TiltCorrectionFilter *filter, float input); +void tilt_init(TiltCorrectionFilter* f, float correction_strength, float sr); +float tilt(TiltCorrectionFilter *f, float in); diff --git a/src/fm95.c b/src/fm95.c index 998eda4..c08b563 100644 --- a/src/fm95.c +++ b/src/fm95.c @@ -439,7 +439,7 @@ int setup_audio(FM95_Runtime* runtime, const FM95_DeviceNames dv_names, const FM } void init_runtime(FM95_Runtime* runtime, const FM95_Config config) { - if(config.tilt != 0) tilt_init(&runtime->tilter, config.tilt); + if(config.tilt != 0) tilt_init(&runtime->tilter, config.tilt, config.sample_rate); if(config.calibration != 0) { init_oscillator(&runtime->osc, (config.calibration == 2) ? 60 : 400, config.sample_rate);