5 #include "smpandaresampler.hh"
12 namespace SpectMorph {
27 std::unique_ptr<Resampler2> res_up;
28 std::unique_ptr<Resampler2> res_down;
30 std::array<Channel, 2> channels_;
33 float freq_scale_factor_ = 0;
34 float frequency_range_min_ = 0;
35 float frequency_range_max_ = 0;
36 float clamp_freq_min_ = 0;
37 float clamp_freq_max_ = 0;
41 float global_volume_ = 1;
43 bool test_linear_ =
false;
45 static constexpr uint MAX_BLOCK_SIZE = 1024;
54 bool fparams_valid_ =
false;
59 for (
auto& channel : channels_)
61 channel.res_up = std::make_unique<Resampler2> (Resampler2::UP, over_, Resampler2::PREC_72DB);
62 channel.res_down = std::make_unique<Resampler2> (Resampler2::DOWN, over_, Resampler2::PREC_72DB);
66 set_frequency_range (10, 24000);
70 set_mode (Mode new_mode)
83 fparams_valid_ =
false;
86 set_drive (
float drive)
89 fparams_valid_ =
false;
92 set_global_volume (
float global_volume)
99 global_volume_ = global_volume;
100 fparams_valid_ =
false;
103 set_test_linear (
bool test_linear)
105 test_linear_ = test_linear;
106 fparams_valid_ =
false;
112 freq_scale_factor_ = 2 * M_PI / (rate_ * over_);
114 update_frequency_range();
117 set_frequency_range (
float min_freq,
float max_freq)
119 frequency_range_min_ = min_freq;
120 frequency_range_max_ = max_freq;
122 update_frequency_range();
127 for (
auto& c : channels_)
129 c.x1 = c.x2 = c.x3 = c.x4 = 0;
130 c.y1 = c.y2 = c.y3 = c.y4 = 0;
135 fparams_valid_ =
false;
140 return channels_[0].res_up->delay() / over_ + channels_[0].res_down->delay();
144 update_frequency_range()
149 clamp_freq_min_ = frequency_range_min_;
150 clamp_freq_max_ = std::min (frequency_range_max_, rate_ * over_ * 0.49f);
153 setup_reso_drive (FParams& fparams,
float reso,
float drive)
155 reso = std::clamp (reso, 0.001f, 1.f);
159 const float scale = 1e-5;
160 fparams.pre_scale = scale;
161 fparams.post_scale = 1 / scale;
162 fparams.reso = reso * 4;
166 const float db_x2_factor = 0.166096404744368;
169 float negative_drive_vol = 1;
172 negative_drive_vol = exp2f (drive * db_x2_factor);
177 reso += drive * sqrt (reso) * reso * 0.03f;
179 float vol = exp2f ((drive + -12 * sqrt (reso)) * db_x2_factor);
180 fparams.pre_scale = negative_drive_vol * vol * global_volume_;
181 fparams.post_scale = std::max (1 / vol, 1.0f) / global_volume_;
182 fparams.reso = sqrt (reso) * 4;
185 tanh_approx (
float x)
188 x = std::clamp (x, -3.0f, 3.0f);
190 return x * (27.0f + x * x) / (27.0f + 9.0f * x * x);
199 template<Mode MODE,
bool STEREO>
inline void
200 run (
float *left,
float *right,
float freq, uint n_samples)
202 const float fc = std::clamp (freq, clamp_freq_min_, clamp_freq_max_) * freq_scale_factor_;
203 const float g = 0.9892f * fc - 0.4342f * fc * fc + 0.1381f * fc * fc * fc - 0.0202f * fc * fc * fc * fc;
204 const float b0 = g * (1 / 1.3f);
205 const float b1 = g * (0.3f / 1.3f);
206 const float a1 = g - 1;
208 float res = fparams_.reso;
209 res *= 1.0029f + 0.0526f * fc - 0.0926f * fc * fc + 0.0218f * fc * fc * fc;
211 for (uint os = 0; os < n_samples; os++)
213 for (uint i = 0; i < (STEREO ? 2 : 1); i++)
215 float &value = i == 0 ? left[os] : right[os];
217 Channel& c = channels_[i];
218 const float x = value * fparams_.pre_scale;
219 const float g_comp = 0.5f;
220 const float x0 = tanh_approx (x - (c.y4 - g_comp * x) * res);
222 c.y1 = b0 * x0 + b1 * c.x1 - a1 * c.y1;
225 c.y2 = b0 * c.y1 + b1 * c.x2 - a1 * c.y2;
228 c.y3 = b0 * c.y2 + b1 * c.x3 - a1 * c.y3;
231 c.y4 = b0 * c.y3 + b1 * c.x4 - a1 * c.y4;
237 value = c.y1 * fparams_.post_scale;
240 value = c.y2 * fparams_.post_scale;
243 value = c.y3 * fparams_.post_scale;
246 value = c.y4 * fparams_.post_scale;
254 template<Mode MODE,
bool STEREO>
inline void
255 do_process_block (uint n_samples,
258 const float *freq_in,
259 const float *reso_in,
260 const float *drive_in)
262 float over_samples_left[over_ * n_samples];
263 float over_samples_right[over_ * n_samples];
265 channels_[0].res_up->process_block (left, n_samples, over_samples_left);
267 channels_[1].res_up->process_block (right, n_samples, over_samples_right);
271 setup_reso_drive (fparams_, reso_in ? reso_in[0] : reso_, drive_in ? drive_in[0] : drive_);
272 fparams_valid_ =
true;
275 if (reso_in || drive_in)
280 float *left_blk = over_samples_left;
281 float *right_blk = over_samples_right;
283 uint n_remaining_samples = n_samples;
284 while (n_remaining_samples)
286 const uint todo = std::min<uint> (n_remaining_samples, 64);
289 setup_reso_drive (fparams_end, reso_in ? reso_in[todo - 1] : reso_, drive_in ? drive_in[todo - 1] : drive_);
291 float todo_inv = 1.f / todo;
292 float delta_pre_scale = (fparams_end.pre_scale - fparams_.pre_scale) * todo_inv;
293 float delta_post_scale = (fparams_end.post_scale - fparams_.post_scale) * todo_inv;
294 float delta_reso = (fparams_end.reso - fparams_.reso) * todo_inv;
297 for (uint i = 0; i < todo * over_; i += over_)
299 fparams_.pre_scale += delta_pre_scale;
300 fparams_.post_scale += delta_post_scale;
301 fparams_.reso += delta_reso;
303 float freq = freq_in ? freq_in[j++] : freq_;
305 run<MODE, STEREO> (left_blk + i, right_blk + i, freq, over_);
308 n_remaining_samples -= todo;
309 left_blk += todo * over_;
310 right_blk += todo * over_;
324 for (uint i = 0; i < n_samples; i++)
326 run<MODE, STEREO> (over_samples_left + over_pos, over_samples_right + over_pos, freq_in[i], over_);
332 run<MODE, STEREO> (over_samples_left, over_samples_right, freq_, n_samples * over_);
334 channels_[0].res_down->process_block (over_samples_left, over_ * n_samples, left);
336 channels_[1].res_down->process_block (over_samples_right, over_ * n_samples, right);
338 template<Mode MODE>
inline void
339 process_block_mode (uint n_samples,
342 const float *freq_in,
343 const float *reso_in,
344 const float *drive_in)
347 do_process_block<MODE, true> (n_samples, left, right, freq_in, reso_in, drive_in);
349 do_process_block<MODE, false> (n_samples, left, right, freq_in, reso_in, drive_in);
353 process_block (uint n_samples,
355 float *right =
nullptr,
356 const float *freq_in =
nullptr,
357 const float *reso_in =
nullptr,
358 const float *drive_in =
nullptr)
362 const uint todo = std::min (n_samples, MAX_BLOCK_SIZE);
366 case LP4: process_block_mode<LP4> (todo, left, right, freq_in, reso_in, drive_in);
368 case LP3: process_block_mode<LP3> (todo, left, right, freq_in, reso_in, drive_in);
370 case LP2: process_block_mode<LP2> (todo, left, right, freq_in, reso_in, drive_in);
372 case LP1: process_block_mode<LP1> (todo, left, right, freq_in, reso_in, drive_in);
Definition: smpandaresampler.hh:99
Definition: smladdervcf.hh:17