0
1
mirror of https://github.com/radio95-rnt/fm95.git synced 2026-02-27 03:23:54 +01:00
This commit is contained in:
2025-03-27 18:22:40 +01:00
parent 9cb81ff1bd
commit 531e5a6a38
3 changed files with 31 additions and 27 deletions

View File

@@ -15,34 +15,32 @@ float hard_clip(float sample, float threshold) {
return fmaxf(-threshold, fminf(threshold, sample)); return fmaxf(-threshold, fminf(threshold, sample));
} }
void init_lpf(Biquad* filter, float sample_rate, float cutoff_freq) { void init_lpf(Biquad* filter, float sample_rate, float cutoff_freq, float Q) {
float omega = 2.0f * M_PI * cutoff_freq / sample_rate; float omega = 2.0f * M_PI * cutoff_freq / sample_rate;
float alpha = sinf(omega) / (2.0f * 0.707f); float alpha = sinf(omega) / (2.0f * Q);
float cos_omega = cosf(omega); float cos_omega = cosf(omega);
float norm = 1.0f / (1.0f + alpha); float norm = 1.0f / (1.0f + alpha);
filter->b0 = (1.0f - cos_omega) * 0.5f * norm; filter->b0 = (1.0f - cos_omega) * 0.5f * norm;
filter->b1 = (1.0f - cos_omega) * norm; filter->b1 = (1.0f - cos_omega) * norm;
filter->b2 = filter->b0; filter->b2 = filter->b0;
filter->a1 = -2.0f * cos_omega * norm; filter->a1 = -2.0f * cos_omega * norm;
filter->a2 = (1.0f - alpha) * norm; filter->a2 = (1.0f - alpha) * norm;
filter->x1 = filter->x2 = 0.0f; filter->x1 = filter->x2 = 0.0f;
filter->y1 = filter->y2 = 0.0f; filter->y1 = filter->y2 = 0.0f;
} }
float biquad(Biquad *filter, float input) { void init_lpf4(LPF4* filter, float sample_rate, float cutoff_freq) {
float output = filter->b0 * input float Q1 = 1.0f / (2.0f * cosf(M_PI / 8.0f));
+ filter->b1 * filter->x1 init_lpf(&filter->section1, sample_rate, cutoff_freq, Q1);
+ filter->b2 * filter->x2
- filter->a1 * filter->y1 float Q2 = 1.0f / (2.0f * cosf(3.0f * M_PI / 8.0f));
- filter->a2 * filter->y2; init_lpf(&filter->section2, sample_rate, cutoff_freq, Q2);
}
filter->x2 = filter->x1;
filter->x1 = input; float apply_lpf4(LPF4* filter, float input) {
float output = biquad(&filter->section1, input);
filter->y2 = filter->y1; output = biquad(&filter->section2, output);
filter->y1 = output;
return output; return output;
} }

View File

@@ -24,5 +24,11 @@ typedef struct
float x1, x2; float x1, x2;
float y1, y2; float y1, y2;
} Biquad; } Biquad;
void init_lpf(Biquad* filter, float sample_rate, float cutoff_freq); typedef struct {
Biquad section1;
Biquad section2;
} LPF4;
void init_lpf(Biquad* filter, float sample_rate, float cutoff_freq, float Q);
void init_lpf4(LPF4* filter, float sample_rate, float cutoff_freq);
float apply_lpf4(LPF4* filter, float input);
float biquad(Biquad *filter, float input); float biquad(Biquad *filter, float input);

View File

@@ -414,9 +414,9 @@ int main(int argc, char **argv) {
init_preemphasis(&preemp_l, preemphasis_tau, sample_rate); init_preemphasis(&preemp_l, preemphasis_tau, sample_rate);
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate); init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
Biquad lpf_l, lpf_r; LPF4 lpf_l, lpf_r;
init_lpf(&lpf_l, sample_rate, 15000); init_lpf4(&lpf_l, sample_rate, 15000);
init_lpf(&lpf_r, sample_rate, 15000); init_lpf4(&lpf_r, sample_rate, 15000);
signal(SIGINT, stop); signal(SIGINT, stop);
signal(SIGTERM, stop); signal(SIGTERM, stop);
@@ -473,8 +473,8 @@ int main(int argc, char **argv) {
float ready_l = apply_preemphasis(&preemp_l, l_in); float ready_l = apply_preemphasis(&preemp_l, l_in);
float ready_r = apply_preemphasis(&preemp_r, r_in); float ready_r = apply_preemphasis(&preemp_r, r_in);
ready_l = biquad(&lpf_l, ready_l); ready_l = apply_lpf4(&lpf_l, ready_l);
ready_r = biquad(&lpf_r, ready_r); ready_r = apply_lpf4(&lpf_r, ready_r);
ready_l = hard_clip(ready_l*audio_volume, clipper_threshold); ready_l = hard_clip(ready_l*audio_volume, clipper_threshold);
ready_r = hard_clip(ready_r*audio_volume, clipper_threshold); ready_r = hard_clip(ready_r*audio_volume, clipper_threshold);