LCOV - code coverage report
Current view: top level - src/audio/effects - delay.cpp (source / functions) Coverage Total Hit
Test: merged.info Lines: 93.8 % 65 61
Test Date: 2026-06-01 11:15:25 Functions: 100.0 % 5 5

            Line data    Source code
       1              : #include "audio/effects/delay.h"
       2              : #include "audio/effects/effect_factory.h"
       3              : 
       4              : namespace Amplitron {
       5              : 
       6            2 : static EffectRegistrar<Delay> reg("Delay");
       7              : 
       8          164 : Delay::Delay() {
       9          451 :     params_ = {
      10          123 :         {"Time",     350.0f, 10.0f, 2000.0f, 350.0f, "ms", "Time interval between each echo. Sets the tempo of the delay repeats."},
      11           41 :         {"Feedback",   0.4f,  0.0f,    0.95f,  0.4f, "", "Amount of the delayed signal fed back into the input. Higher values create more repeats."},
      12           41 :         {"Tone",       0.7f,  0.0f,    1.0f,   0.7f, "", "High-frequency damping on the repeats. Lower values create darker, tape-like echoes."},
      13           41 :         {"Level",      0.5f,  0.0f,    1.0f,   0.5f, "", "Mix volume of the delay repeats added to your dry signal."},
      14          451 :     };
      15          123 :     set_sample_rate(DEFAULT_SAMPLE_RATE);
      16          246 : }
      17              : 
      18          264 : void Delay::set_sample_rate(int sample_rate) {
      19          264 :     Effect::set_sample_rate(sample_rate);
      20          264 :     max_delay_samples_ = static_cast<int>(sample_rate * 2.5f); // max 2.5s
      21          264 :     delay_buffer_.resize(max_delay_samples_, 0.0f);
      22          264 :     write_pos_ = 0;
      23          264 : }
      24              : 
      25           24 : void Delay::process(float* buffer, int num_samples) {
      26           24 :     if (!enabled_) return;
      27              : 
      28           24 :     const float alpha = 1.0f - std::exp(-1.0f / (sample_rate_ * 0.020f)); // 20 ms
      29           24 :     smoothed_time_ms_ += alpha * (params_[0].value - smoothed_time_ms_);
      30           24 :     smoothed_feedback_ += alpha * (params_[1].value - smoothed_feedback_);
      31           24 :     smoothed_tone_     += alpha * (params_[2].value - smoothed_tone_);
      32           24 :     smoothed_level_    += alpha * (params_[3].value - smoothed_level_);
      33              : 
      34           24 :     float time_ms = smoothed_time_ms_;
      35           24 :     float feedback = smoothed_feedback_;
      36           24 :     float tone = smoothed_tone_;
      37           24 :     float level = smoothed_level_;
      38              : 
      39           24 :     int delay_samples = static_cast<int>(time_ms * 0.001f * sample_rate_);
      40           24 :     delay_samples = std::min(delay_samples, max_delay_samples_ - 1);
      41           24 :     float lp_coeff = 0.1f + tone * 0.85f;
      42              : 
      43        16920 :     for (int i = 0; i < num_samples; ++i) {
      44        16896 :         float dry = buffer[i];
      45              : 
      46        16896 :         int read_pos = write_pos_ - delay_samples;
      47        16896 :         if (read_pos < 0) read_pos += max_delay_samples_;
      48              : 
      49        16896 :         float delayed = delay_buffer_[read_pos];
      50              : 
      51              :         // Tone filter on feedback path
      52        16896 :         float filtered = tone_lp_.lp(delayed, lp_coeff);
      53              : 
      54              :         // Write to delay buffer: input + filtered feedback
      55        16896 :         delay_buffer_[write_pos_] = buffer[i] + filtered * feedback;
      56              : 
      57        16896 :         write_pos_++;
      58        16896 :         if (write_pos_ >= max_delay_samples_) write_pos_ = 0;
      59              : 
      60        16896 :         buffer[i] = dry + delayed * level;
      61         5632 :     }
      62            8 : }
      63              : 
      64          144 : void Delay::reset() {
      65          144 :     std::fill(delay_buffer_.begin(), delay_buffer_.end(), 0.0f);
      66          144 :     write_pos_ = 0;
      67          144 :     tone_lp_.reset();
      68          144 : }
      69              : 
      70            3 : void Delay::set_transport_state(float bpm){
      71            3 :     if(bpm <= 0.0f || !std::isfinite(bpm)) return;
      72            3 :     if(bpm == last_bpm_) return;
      73            3 :     last_bpm_=bpm;
      74              : 
      75              :     //Quarter-note duration
      76            3 :     float quarter_note_ms = 60000.0f / bpm;
      77              :     //Check current knob
      78            3 :     float current_knob_time = params_[0].value;
      79              :     //Distance to nearest subdivisions
      80            3 :     float diff_quarter = std::fabs(current_knob_time - quarter_note_ms);
      81            3 :     float diff_eighth = std::fabs(current_knob_time - (quarter_note_ms * 0.5f));
      82            3 :     float diff_sixteenth = std::fabs(current_knob_time - (quarter_note_ms * 0.25f));
      83              :     //Check closest
      84            3 :     float target_time = quarter_note_ms; //default to 1/4 note
      85            3 :     if(diff_eighth < diff_quarter && diff_eighth < diff_sixteenth){
      86            0 :         target_time = quarter_note_ms * 0.5f; // 1/8 note
      87            0 :     }
      88            3 :     else if(diff_sixteenth < diff_quarter && diff_sixteenth < diff_eighth){
      89            0 :         target_time = quarter_note_ms * 0.25f; // 1/16 note
      90            0 :     }
      91              :     
      92              :     //Set knob
      93            3 :     params_[0].value = clamp(target_time, params_[0].min_val, params_[0].max_val);
      94            1 : }
      95              : 
      96              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1