34 float freq_scale_factor_ = 0;
35 float frequency_range_min_ = 0;
36 float frequency_range_max_ = 0;
37 float clamp_freq_min_ = 0;
38 float clamp_freq_max_ = 0;
42 float global_volume_ = 1;
44 bool test_linear_ =
false;
46 static constexpr uint MAX_BLOCK_SIZE = 1024;
55 bool fparams_valid_ =
false;
60 for (
auto& channel : channels_)
67 set_frequency_range (10, 24000);
71 set_mode (Mode new_mode)
84 fparams_valid_ =
false;
87 set_drive (
float drive)
90 fparams_valid_ =
false;
93 set_global_volume (
float global_volume)
100 global_volume_ = global_volume;
101 fparams_valid_ =
false;
104 set_test_linear (
bool test_linear)
106 test_linear_ = test_linear;
107 fparams_valid_ =
false;
113 freq_scale_factor_ = 2 * M_PI / (rate_ * over_);
115 update_frequency_range();
118 set_frequency_range (
float min_freq,
float max_freq)
120 frequency_range_min_ = min_freq;
121 frequency_range_max_ = max_freq;
123 update_frequency_range();
128 for (
auto& c : channels_)
130 c.x1 = c.x2 = c.x3 = c.x4 = 0;
131 c.y1 = c.y2 = c.y3 = c.y4 = 0;
136 fparams_valid_ =
false;
141 return channels_[0].res_up->delay() / over_ + channels_[0].res_down->delay();
145 update_frequency_range()
150 clamp_freq_min_ = frequency_range_min_;
151 clamp_freq_max_ =
std::min (frequency_range_max_, rate_ * over_ * 0.49f);
154 setup_reso_drive (FParams& fparams,
float reso,
float drive)
160 const float scale = 1e-5;
161 fparams.pre_scale = scale;
162 fparams.post_scale = 1 / scale;
163 fparams.reso = reso * 4;
167 const float db_x2_factor = 0.166096404744368;
170 float negative_drive_vol = 1;
173 negative_drive_vol =
exp2f (drive * db_x2_factor);
178 reso += drive *
sqrt (reso) * reso * 0.03f;
180 float vol =
exp2f ((drive + -12 *
sqrt (reso)) * db_x2_factor);
181 fparams.pre_scale = negative_drive_vol * vol * global_volume_;
182 fparams.post_scale =
std::max (1 / vol, 1.0f) / global_volume_;
183 fparams.reso =
sqrt (reso) * 4;
186 tanh_approx (
float x)
191 return x * (27.0f + x * x) / (27.0f + 9.0f * x * x);
200 template<Mode MODE,
bool STEREO>
inline void
201 run (
float *left,
float *right,
float freq,
uint n_samples)
203 const float fc =
std::clamp (freq, clamp_freq_min_, clamp_freq_max_) * freq_scale_factor_;
204 const float g = 0.9892f * fc - 0.4342f * fc * fc + 0.1381f * fc * fc * fc - 0.0202f * fc * fc * fc * fc;
205 const float b0 = g * (1 / 1.3f);
206 const float b1 = g * (0.3f / 1.3f);
207 const float a1 = g - 1;
209 float res = fparams_.reso;
210 res *= 1.0029f + 0.0526f * fc - 0.0926f * fc * fc + 0.0218f * fc * fc * fc;
212 for (
uint os = 0; os < n_samples; os++)
214 for (
uint i = 0; i < (STEREO ? 2 : 1); i++)
216 float &value = i == 0 ? left[os] : right[os];
218 Channel& c = channels_[i];
219 const float x = value * fparams_.pre_scale;
220 const float g_comp = 0.5f;
221 const float x0 = tanh_approx (x - (c.y4 - g_comp * x) * res);
223 c.y1 = b0 * x0 + b1 * c.x1 - a1 * c.y1;
226 c.y2 = b0 * c.y1 + b1 * c.x2 - a1 * c.y2;
229 c.y3 = b0 * c.y2 + b1 * c.x3 - a1 * c.y3;
232 c.y4 = b0 * c.y3 + b1 * c.x4 - a1 * c.y4;
238 value = c.y1 * fparams_.post_scale;
241 value = c.y2 * fparams_.post_scale;
244 value = c.y3 * fparams_.post_scale;
247 value = c.y4 * fparams_.post_scale;
255 template<Mode MODE,
bool STEREO>
inline void
256 do_process_block (
uint n_samples,
259 const float *freq_in,
260 const float *reso_in,
261 const float *drive_in)
263 float over_samples_left[over_ * n_samples];
264 float over_samples_right[over_ * n_samples];
266 channels_[0].res_up->process_block (left, n_samples, over_samples_left);
268 channels_[1].res_up->process_block (right, n_samples, over_samples_right);
272 setup_reso_drive (fparams_, reso_in ? reso_in[0] : reso_, drive_in ? drive_in[0] : drive_);
273 fparams_valid_ =
true;
276 if (reso_in || drive_in)
281 float *left_blk = over_samples_left;
282 float *right_blk = over_samples_right;
284 uint n_remaining_samples = n_samples;
285 while (n_remaining_samples)
290 setup_reso_drive (fparams_end, reso_in ? reso_in[todo - 1] : reso_, drive_in ? drive_in[todo - 1] : drive_);
292 float todo_inv = 1.f / todo;
293 float delta_pre_scale = (fparams_end.pre_scale - fparams_.pre_scale) * todo_inv;
294 float delta_post_scale = (fparams_end.post_scale - fparams_.post_scale) * todo_inv;
295 float delta_reso = (fparams_end.reso - fparams_.reso) * todo_inv;
298 for (
uint i = 0; i < todo * over_; i += over_)
300 fparams_.pre_scale += delta_pre_scale;
301 fparams_.post_scale += delta_post_scale;
302 fparams_.reso += delta_reso;
304 float freq = freq_in ? freq_in[j++] : freq_;
306 run<MODE, STEREO> (left_blk + i, right_blk + i, freq, over_);
309 n_remaining_samples -= todo;
310 left_blk += todo * over_;
311 right_blk += todo * over_;
325 for (
uint i = 0; i < n_samples; i++)
327 run<MODE, STEREO> (over_samples_left + over_pos, over_samples_right + over_pos, freq_in[i], over_);
333 run<MODE, STEREO> (over_samples_left, over_samples_right, freq_, n_samples * over_);
335 channels_[0].res_down->process_block (over_samples_left, over_ * n_samples, left);
337 channels_[1].res_down->process_block (over_samples_right, over_ * n_samples, right);
339 template<Mode MODE>
inline void
340 process_block_mode (
uint n_samples,
343 const float *freq_in,
344 const float *reso_in,
345 const float *drive_in)
348 do_process_block<MODE, true> (n_samples, left, right, freq_in, reso_in, drive_in);
350 do_process_block<MODE, false> (n_samples, left, right, freq_in, reso_in, drive_in);
354 process_block (
uint n_samples,
356 float *right =
nullptr,
357 const float *freq_in =
nullptr,
358 const float *reso_in =
nullptr,
359 const float *drive_in =
nullptr)
367 case LP4: process_block_mode<LP4> (todo, left, right, freq_in, reso_in, drive_in);
369 case LP3: process_block_mode<LP3> (todo, left, right, freq_in, reso_in, drive_in);
371 case LP2: process_block_mode<LP2> (todo, left, right, freq_in, reso_in, drive_in);
373 case LP1: process_block_mode<LP1> (todo, left, right, freq_in, reso_in, drive_in);