From a2217ecb5e8a386512d6cef7a2b7a22a7c4be51c Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Fri, 31 Jan 2025 19:27:22 +0100 Subject: [PATCH] i hate this with a passion --- lib/filters.c | 52 +++++++-------------------------------------------- lib/filters.h | 13 +++++++++---- src/fm95.c | 2 +- 3 files changed, 17 insertions(+), 50 deletions(-) diff --git a/lib/filters.c b/lib/filters.c index 1712a77..ca1e68f 100644 --- a/lib/filters.c +++ b/lib/filters.c @@ -1,51 +1,13 @@ #include "filters.h" -void init_preemphasis(BiquadFilter *filter, float tau, float sample_rate) { - /* - premphasis should go like this: - cutoff: +0 - 2cutoff: +6 - 3cutoff: +12 - 4cutoff: +18 - ... - */ - - // Calculate the cutoff frequency from tau (f_c = 1/(2πτ)) - float cutoff_freq = 1.0f / (2.0f * M_PI * tau); - - // Pre-warp the cutoff frequency for the bilinear transform - float omega = 2.0f * M_PI * cutoff_freq / sample_rate; - float K = tanf(omega / 2.0f); - - // Calculate filter coefficients for 1st-order high-pass (converted to biquad) - float alpha = 1.0f + K; - filter->b0 = 1.0f / alpha; - filter->b1 = -filter->b0; - filter->b2 = 0.0f; - filter->a1 = (K - 1.0f) / alpha; - filter->a2 = 0.0f; - - // Reset state variables - filter->x1 = 0.0f; - filter->x2 = 0.0f; - filter->y1 = 0.0f; - filter->y2 = 0.0f; +void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate) { + filter->prev_sample = 0.0f; + filter->alpha = exp(-1 / (tau*sample_rate)); } -float apply_preemphasis(BiquadFilter *filter, float input) { - // Direct Form I implementation - float output = filter->b0 * input - + filter->b1 * filter->x1 - + filter->b2 * filter->x2 - - filter->a1 * filter->y1 - - filter->a2 * filter->y2; - - // Update state variables - filter->x2 = filter->x1; - filter->x1 = input; - filter->y2 = filter->y1; - filter->y1 = output; - - return output; +float apply_preemphasis(ResistorCapacitor *filter, float sample) { + float out = sample-filter->alpha*filter->prev_sample; + filter->prev_sample = sample; + return out; } void init_lpf(BiquadFilter* filter, float cutoffFreq, float qFactor, float sampleRate) { diff --git a/lib/filters.h b/lib/filters.h index 89d01ba..710199d 100644 --- a/lib/filters.h +++ b/lib/filters.h @@ -5,16 +5,21 @@ #include #include "constants.h" +typedef struct +{ + float alpha; + float prev_sample; +} ResistorCapacitor; + +void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate); +float apply_preemphasis(ResistorCapacitor *filter, float sample); + typedef struct { float b0, b1, b2; float a1, a2; float x1, x2; float y1, y2; } BiquadFilter; - -void init_preemphasis(BiquadFilter *filter, float tau, float sample_rate); -float apply_preemphasis(BiquadFilter *filter, float input); - void init_lpf(BiquadFilter* filter, float cutoffFreq, float qFactor, float sampleRate); void init_hpf(BiquadFilter* filter, float cutoffFreq, float qFactor, float sampleRate); float apply_frequency_filter(BiquadFilter* filter, float input); diff --git a/src/fm95.c b/src/fm95.c index e2c0cf8..7294fef 100644 --- a/src/fm95.c +++ b/src/fm95.c @@ -396,7 +396,7 @@ int main(int argc, char **argv) { DelayLine monoDelay; // Hilbert introduces a delay, this should be here to sync the mono with stereo to a sample init_delay_line(&monoDelay, (HILBERT_TAPS-1)/2); - BiquadFilter preemp_l, preemp_r; + ResistorCapacitor preemp_l, preemp_r; init_preemphasis(&preemp_l, preemphasis_tau, SAMPLE_RATE); init_preemphasis(&preemp_r, preemphasis_tau, SAMPLE_RATE);