0
1
mirror of https://github.com/radio95-rnt/fm95.git synced 2026-02-26 19:23:51 +01:00

remove lpf

This commit is contained in:
2025-03-27 21:36:44 +01:00
parent 3238e156dd
commit 7b78cf6264
4 changed files with 1 additions and 65 deletions

View File

@@ -3,7 +3,6 @@
FM95 is a audio processor for FM, it does:
- Pre-Emphasis
- Low Pass Filter
- Stereo
- Polar Stereo
- SCA
@@ -34,7 +33,7 @@ Done!
## CPU Usage?
Should run completly fine on a pi 5, right now with the preemp and rds2, on a pi 3b, its 50-70% (without lpf its more like 25%-27%, lpf with neon optimization is about 50%)
Should run completly fine on a pi 5, fine on a pi 3b
## Other Apps

View File

@@ -14,48 +14,3 @@ float apply_preemphasis(ResistorCapacitor *filter, float sample) {
float hard_clip(float sample, float threshold) {
return fmaxf(-threshold, fminf(threshold, sample));
}
void init_lpf(LPFFilter *filter, float cutoff, int sample_rate) {
float a = tanf(M_PI * cutoff / sample_rate);
float a2 = a * a;
float r, e;
for (int i = 0; i < LPF_ORDER; i++) {
r = sinf(M_PI * (2.0f * i + 1.0f) / (4.0f * LPF_ORDER));
e = a2 + 2.0f * a * r + 1.0f;
float inv_e = 1.0f / e;
filter->A[i] = a2 * inv_e;
filter->d1[i] = 2.0f * (1.0f - a2) * inv_e;
filter->d2[i] = -(a2 - 2.0f * a * r + 1.0f) * inv_e;
}
}
float process_lpf(LPFFilter *filter, float x) {
#if USE_NEON
float32x4_t y_vec = vdupq_n_f32(x);
for (int i = 0; i < LPF_ORDER; i += 4) {
float32x4_t d1_vec = vld1q_f32(&filter->d1[i]);
float32x4_t d2_vec = vld1q_f32(&filter->d2[i]);
float32x4_t w1_vec = vld1q_f32(&filter->w1[i]);
float32x4_t w2_vec = vld1q_f32(&filter->w2[i]);
float32x4_t A_vec = vld1q_f32(&filter->A[i]);
float32x4_t w0_new_vec = vmlaq_f32(vmlaq_f32(y_vec, d1_vec, w1_vec), d2_vec, w2_vec);
y_vec = vmulq_f32(A_vec, vaddq_f32(vaddq_f32(w0_new_vec, w1_vec), vaddq_f32(w1_vec, w2_vec)));
vst1q_f32(&filter->w2[i], w1_vec);
vst1q_f32(&filter->w1[i], w0_new_vec);
}
return vgetq_lane_f32(y_vec, 0);
#else
float y = x;
for (int i = 0; i < LPF_ORDER; i++) {
float w0_new = filter->d1[i] * filter->w1[i] + filter->d2[i] * filter->w2[i] + y;
y = filter->A[i] * (w0_new + 2.0f * filter->w1[i] + filter->w2[i]);
filter->w2[i] = filter->w1[i];
filter->w1[i] = w0_new;
}
return y;
#endif
}

View File

@@ -24,15 +24,3 @@ void init_preemphasis(ResistorCapacitor *filter, float tau, float sample_rate);
float apply_preemphasis(ResistorCapacitor *filter, float sample);
float hard_clip(float sample, float threshold);
typedef struct
{
float A[LPF_ORDER];
float d1[LPF_ORDER];
float d2[LPF_ORDER];
float w0[LPF_ORDER];
float w1[LPF_ORDER];
float w2[LPF_ORDER];
} LPFFilter;
void init_lpf(LPFFilter *filter, float cutoff, int sample_rate);
float process_lpf(LPFFilter *filter, float x);

View File

@@ -414,10 +414,6 @@ int main(int argc, char **argv) {
init_preemphasis(&preemp_l, preemphasis_tau, sample_rate);
init_preemphasis(&preemp_r, preemphasis_tau, sample_rate);
LPFFilter lpf_l, lpf_r;
init_lpf(&lpf_l, 15000, sample_rate);
init_lpf(&lpf_r, 15000, sample_rate);
signal(SIGINT, stop);
signal(SIGTERM, stop);
@@ -473,8 +469,6 @@ int main(int argc, char **argv) {
float ready_l = apply_preemphasis(&preemp_l, l_in);
float ready_r = apply_preemphasis(&preemp_r, r_in);
ready_l = process_lpf(&lpf_l, ready_l);
ready_r = process_lpf(&lpf_r, ready_r);
ready_l = hard_clip(ready_l*audio_volume, clipper_threshold);
ready_r = hard_clip(ready_r*audio_volume, clipper_threshold);