LCOV - code coverage report
Current view: top level - src/audio/effects - cabinet_sim.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 6 6
Test Date: 2026-06-03 09:13:19 Functions: 100.0 % 6 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 "audio/effects/effect.h"
       9              : #include "audio/dsp/biquad.h"
      10              : #include "audio/dsp/convolution_engine.h"
      11              : #include <atomic>
      12              : #include <string>
      13              : #include <vector>
      14              : #include <memory>
      15              : 
      16              : namespace Amplitron {
      17              : 
      18              : class CabinetSim : public Effect {
      19              : public:
      20              :     CabinetSim();
      21              :     ~CabinetSim() override;
      22              :     void process(float* buffer, int num_samples) override;
      23              :     void set_sample_rate(int sample_rate) override;
      24              :     void reset() override;
      25           95 :     const char* name() const override { return "Cabinet"; }
      26            3 :     const char* type_id() const override { return "Cabinet"; }
      27           27 :     std::vector<EffectParam>& params() override { return params_; }
      28              : 
      29              :     // --- IR management (called from GUI thread) ---
      30              :     bool load_ir(const std::string& filepath);
      31              :     void clear_ir();
      32              :     bool has_ir() const;
      33           19 :     const std::string& ir_path() const { return ir_path_; }
      34           13 :     const std::string& ir_name() const { return ir_name_; }
      35           23 :     float ir_duration_ms() const { return ir_duration_ms_; }
      36              : 
      37              : private:
      38              :     std::vector<EffectParam> params_;
      39              : 
      40              :     Biquad lp_;   // speaker rolloff
      41              :     Biquad hp_;   // low cut
      42              :     Biquad peak_; // resonance bump
      43              : 
      44              :     // --- Optional IR-based cabinet convolution ---
      45              : 
      46              :     // Atomic kernel swap: GUI thread stores, audio thread consumes
      47              :     std::atomic<ConvolutionKernel*> pending_kernel_{nullptr};
      48              :     const ConvolutionKernel* active_kernel_ = nullptr;
      49              :     mutable std::atomic<const ConvolutionKernel*> old_kernel_to_delete_{nullptr};
      50              :     std::atomic<bool> clear_pending_{false};
      51              : 
      52              :     ConvolutionEngine conv_engine_;
      53              : 
      54              :     // Dry signal buffer for process() to avoid per-call allocations in audio callback
      55              :     std::vector<float> dry_buffer_;
      56              : 
      57              :     // Raw IR samples for rebuilding kernel on sample rate / block size changes
      58              :     std::vector<float> raw_ir_samples_;
      59              : 
      60              :     // IR file metadata
      61              :     std::string ir_path_;
      62              :     std::string ir_name_;
      63              :     float ir_duration_ms_ = 0.0f;
      64              : 
      65              :     // Brightness one-pole smoother
      66              :     float bright_smooth_ = 0.5f;
      67              :     float bright_alpha_ = 0.0f;
      68              : 
      69              :     // Expected block size for the current kernel (atomic: read by audio thread, written by both)
      70              :     std::atomic<int> expected_block_size_{0};
      71              : 
      72              :     // Pending block size when audio callback detects a mismatch
      73              :     std::atomic<int> pending_block_size_{0};
      74              : 
      75              :     // Max IR length: 500ms worth of samples at current sample rate
      76              :     int max_ir_samples() const;
      77              : 
      78              :     // Check and consume pending kernel (called at start of process())
      79              :     void check_pending_kernel();
      80              : 
      81              :     // Build kernel from raw_ir_samples_ for a given block size
      82              :     void build_kernel(int block_size);
      83              : };
      84              : 
      85              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1