LCOV - code coverage report
Current view: top level - src/audio/effects/amp_cab - cabinet_sim.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 85.7 % 7 6
Test Date: 2026-06-07 15:51:50 Functions: 85.7 % 7 6

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : // Lightweight speaker cabinet filtering for guitar amp output shaping.
       4              : // Approximates speaker response as H(z)=H_hp(z) * H_peak(z) * H_lp(z): a low
       5              : // cut removes rumble, a resonant biquad models cabinet/body emphasis, and a
       6              : // low-pass rolloff attenuates harsh high-frequency content.
       7              : 
       8              : #include <atomic>
       9              : #include <memory>
      10              : #include <string>
      11              : #include <vector>
      12              : 
      13              : #include "audio/dsp/biquad.h"
      14              : #include "audio/dsp/convolution_engine.h"
      15              : #include "audio/effects/core/effect.h"
      16              : 
      17              : namespace Amplitron {
      18              : 
      19              : class CabinetSim : public Effect {
      20              :    public:
      21              :     CabinetSim();
      22              :     ~CabinetSim() override;
      23              :     void process(float* buffer, int num_samples) override;
      24              :     void set_sample_rate(int sample_rate) override;
      25              :     void reset() override;
      26           95 :     const char* name() const override { return "Cabinet"; }
      27            3 :     const char* type_id() const override { return "Cabinet"; }
      28           27 :     std::vector<EffectParam>& params() override { return params_; }
      29            0 :     const std::vector<EffectParam>& params() const override { return params_; }
      30              : 
      31              :     // --- IR management (called from GUI thread) ---
      32              :     bool load_ir(const std::string& filepath);
      33              :     void clear_ir();
      34              :     bool has_ir() const;
      35           19 :     const std::string& ir_path() const { return ir_path_; }
      36           13 :     const std::string& ir_name() const { return ir_name_; }
      37           23 :     float ir_duration_ms() const { return ir_duration_ms_; }
      38              : 
      39              :    private:
      40              :     std::vector<EffectParam> params_;
      41              : 
      42              :     Biquad lp_;    // speaker rolloff
      43              :     Biquad hp_;    // low cut
      44              :     Biquad peak_;  // resonance bump
      45              : 
      46              :     // --- Optional IR-based cabinet convolution ---
      47              : 
      48              :     // Atomic kernel swap: GUI thread stores, audio thread consumes
      49              :     std::atomic<ConvolutionKernel*> pending_kernel_{nullptr};
      50              :     const ConvolutionKernel* active_kernel_ = nullptr;
      51              :     mutable std::atomic<const ConvolutionKernel*> old_kernel_to_delete_{nullptr};
      52              :     std::atomic<bool> clear_pending_{false};
      53              : 
      54              :     ConvolutionEngine conv_engine_;
      55              : 
      56              :     // Dry signal buffer for process() to avoid per-call allocations in audio callback
      57              :     std::vector<float> dry_buffer_;
      58              : 
      59              :     // Raw IR samples for rebuilding kernel on sample rate / block size changes
      60              :     std::vector<float> raw_ir_samples_;
      61              : 
      62              :     // IR file metadata
      63              :     std::string ir_path_;
      64              :     std::string ir_name_;
      65              :     float ir_duration_ms_ = 0.0f;
      66              : 
      67              :     // Brightness one-pole smoother
      68              :     float bright_smooth_ = 0.5f;
      69              :     float bright_alpha_ = 0.0f;
      70              : 
      71              :     // Expected block size for the current kernel (atomic: read by audio thread, written by both)
      72              :     std::atomic<int> expected_block_size_{0};
      73              : 
      74              :     // Pending block size when audio callback detects a mismatch
      75              :     std::atomic<int> pending_block_size_{0};
      76              : 
      77              :     // Max IR length: 500ms worth of samples at current sample rate
      78              :     int max_ir_samples() const;
      79              : 
      80              :     // Check and consume pending kernel (called at start of process())
      81              :     void check_pending_kernel();
      82              : 
      83              :     // Build kernel from raw_ir_samples_ for a given block size
      84              :     void build_kernel(int block_size);
      85              : };
      86              : 
      87              : }  // namespace Amplitron
        

Generated by: LCOV version 2.0-1