23
23
24
24
#include < algorithm>
25
25
#include < cmath>
26
-
26
+ #include < iostream>
27
+ #include < iomanip>
27
28
28
29
// Calculate the filter coefficients with single precision
29
30
typedef float IIR_COEFF_T;
@@ -56,6 +57,30 @@ extern "C" void fluid_iir_filter_init_table(fluid_real_t sample_rate)
56
57
}
57
58
}
58
59
60
+ template <typename R>
61
+ static R interp_lin (R y0, R y1, R x0, R x1, R x)
62
+ {
63
+ return (y0 * (x1 - x) + y1 * (x - x0)) / (x1 - x0);
64
+ }
65
+
66
+ template <typename R>
67
+ static void interp_sin_cos (R fres, sincos_t *coeff)
68
+ {
69
+ R diff = (fres - 1500 .0f ) / CENTS_STEP;
70
+
71
+ unsigned idx_prev = std::max (std::min (static_cast <int >(std::floor (diff)), SINCOS_TAB_SIZE - 1 ), 0 );
72
+ unsigned idx_next = std::max (std::min (static_cast <int >(std::ceil (diff)), SINCOS_TAB_SIZE - 1 ), 0 );
73
+
74
+ sincos_t prev = sincos_table[idx_prev];
75
+ sincos_t next = sincos_table[idx_next];
76
+
77
+ R x0 = idx_prev * CENTS_STEP + 1500 ;
78
+ R x1 = idx_next * CENTS_STEP + 1500 ;
79
+
80
+ coeff->sin = interp_lin<R>(prev.sin , next.sin , x0, x1, fres);
81
+ coeff->cos = interp_lin<R>(prev.cos , next.cos , x0, x1, fres);
82
+ }
83
+
59
84
60
85
template <typename R, bool GAIN_NORM, enum fluid_iir_filter_type TYPE>
61
86
static inline void fluid_iir_filter_calculate_coefficients (R fres,
@@ -77,10 +102,32 @@ static inline void fluid_iir_filter_calculate_coefficients(R fres,
77
102
* into account for both significant frequency relocation and for
78
103
* bandwidth readjustment'. */
79
104
80
- unsigned tab_idx = (fres - 1500 ) / CENTS_STEP;
81
- R sin_coeff = sincos_table[tab_idx].sin ;
82
- R cos_coeff = sincos_table[tab_idx].cos ;
83
- R alpha_coeff = sin_coeff / (2 .0f * q);
105
+ sincos_t coeff;
106
+ interp_sin_cos<R>(fres, &coeff);
107
+
108
+ #ifdef DBG_FILTER
109
+ {
110
+ sincos_t coeff_accurate;
111
+ fluid_real_t fres_hz = fluid_ct2hz (fres);
112
+ R omega = (R)(2.0 * M_PI) * (fres_hz / output_rate);
113
+ coeff_accurate.sin = std::sin (omega);
114
+ coeff_accurate.cos = std::cos (omega);
115
+
116
+ std::cerr << " fres: " << std::fixed << std::setprecision (2 ) << fres_hz << " Hz | "
117
+ << " fres: " << std::fixed << std::setprecision (2 ) << fres << " Cents | "
118
+ << " sin: " << std::fixed << std::setprecision (6 ) << coeff.sin << " | "
119
+ << " sin_accurate: " << std::fixed << std::setprecision (6 ) << coeff_accurate.sin << " | "
120
+ << " abs(sin_diff): " << std::fixed << std::setprecision (6 )
121
+ << std::fabs (coeff.sin - coeff_accurate.sin ) << " | "
122
+ << " cos: " << std::fixed << std::setprecision (6 ) << coeff.cos << " | "
123
+ << " cos_accurate: " << std::fixed << std::setprecision (6 ) << coeff_accurate.cos << " | "
124
+ << " abs(cos_diff): " << std::fixed << std::setprecision (6 )
125
+ << std::fabs (coeff.cos - coeff_accurate.cos ) << std::endl;
126
+ }
127
+ #endif
128
+
129
+
130
+ R alpha_coeff = coeff.sin / (2 .0f * q);
84
131
R a0_inv = 1 .0f / (1 .0f + alpha_coeff);
85
132
86
133
/* Calculate the filter coefficients. All coefficients are
@@ -93,7 +140,7 @@ static inline void fluid_iir_filter_calculate_coefficients(R fres,
93
140
* iir_filter->b2=(1.-cos_coeff)*a0_inv*0.5*filter_gain; */
94
141
95
142
/* "a" coeffs are same for all 3 available filter types */
96
- R a1_temp = -2 .0f * cos_coeff * a0_inv;
143
+ R a1_temp = -2 .0f * coeff. cos * a0_inv;
97
144
R a2_temp = (1 .0f - alpha_coeff) * a0_inv;
98
145
R b02_temp, b1_temp;
99
146
@@ -116,7 +163,7 @@ static inline void fluid_iir_filter_calculate_coefficients(R fres,
116
163
switch (TYPE)
117
164
{
118
165
case FLUID_IIR_HIGHPASS:
119
- b1_temp = (1 .0f + cos_coeff ) * a0_inv * filter_gain;
166
+ b1_temp = (1 .0f + coeff. cos ) * a0_inv * filter_gain;
120
167
121
168
/* both b0 -and- b2 */
122
169
b02_temp = b1_temp * 0 .5f ;
@@ -125,7 +172,7 @@ static inline void fluid_iir_filter_calculate_coefficients(R fres,
125
172
break ;
126
173
127
174
case FLUID_IIR_LOWPASS:
128
- b1_temp = (1 .0f - cos_coeff ) * a0_inv * filter_gain;
175
+ b1_temp = (1 .0f - coeff. cos ) * a0_inv * filter_gain;
129
176
130
177
/* both b0 -and- b2 */
131
178
b02_temp = b1_temp * 0 .5f ;
@@ -259,7 +306,7 @@ fluid_iir_filter_apply_local(fluid_iir_filter_t *iir_filter, fluid_real_t *dsp_b
259
306
q += q_incr;
260
307
}
261
308
262
- LOG_FILTER (" last_fres: %.2f Hz | target_fres: %.2f Hz |---| last_q: %.4f | target_q: %.4f" , iir_filter->last_fres , iir_filter->target_fres , iir_filter->last_q , iir_filter->target_q );
309
+ LOG_FILTER (" last_fres: %.2f Cents | target_fres: %.2f Cents |---| last_q: %.4f | target_q: %.4f" , iir_filter->last_fres , iir_filter->target_fres , iir_filter->last_q , iir_filter->target_q );
263
310
264
311
fluid_iir_filter_calculate_coefficients<IIR_COEFF_T, GAIN_NORM, TYPE>(fres, q, output_rate, &dsp_a1, &dsp_a2, &dsp_b02, &dsp_b1);
265
312
}
0 commit comments