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);