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

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <memory>
       4              : #include <string>
       5              : #include <vector>
       6              : 
       7              : // Forward-declare kiss_fft types to avoid exposing the C header
       8              : struct kiss_fft_state;
       9              : typedef struct kiss_fft_state* kiss_fft_cfg;
      10              : 
      11              : namespace Amplitron {
      12              : 
      13              : // =============================================================================
      14              : // ConvolutionKernel — immutable, prepared on the GUI thread
      15              : // =============================================================================
      16              : 
      17              : class ConvolutionKernel {
      18              :    public:
      19              :     // Construct from time-domain IR samples.
      20              :     // block_size is the audio buffer size (e.g. 64, 128, 256).
      21              :     ConvolutionKernel(const std::vector<float>& ir_samples, int block_size);
      22              :     ~ConvolutionKernel();
      23              : 
      24         3120 :     int block_size() const { return block_size_; }
      25         3072 :     int fft_size() const { return fft_size_; }
      26         3075 :     int num_partitions() const { return num_partitions_; }
      27         5092 :     int ir_length() const { return ir_length_; }
      28              : 
      29              :     // Access the i-th partition in frequency domain.
      30              :     // Returns fft_size complex values as kiss_fft_cpx array.
      31              :     const void* partition_freq(int index) const;
      32              : 
      33              :     // Time-domain IR (for direct convolution fallback)
      34         3033 :     const std::vector<float>& ir_time_domain() const { return ir_time_; }
      35              : 
      36              :     // Metadata
      37              :     std::string source_path;
      38              :     std::string source_name;  // filename only
      39              :     float duration_ms = 0.0f;
      40              : 
      41              :    private:
      42              :     int block_size_;
      43              :     int fft_size_;  // = 2 * block_size (for linear convolution via overlap-add)
      44              :     int num_partitions_;
      45              :     int ir_length_;
      46              : 
      47              :     std::vector<float> ir_time_;  // original IR (for direct convolution fallback)
      48              : 
      49              :     // Frequency-domain partitions: each is fft_size kiss_fft_cpx values
      50              :     std::vector<std::vector<char>> partitions_freq_;  // raw storage
      51              : 
      52              :     kiss_fft_cfg fft_cfg_ = nullptr;
      53              : };
      54              : 
      55              : // =============================================================================
      56              : // ConvolutionEngine — mutable state for the audio thread
      57              : // =============================================================================
      58              : 
      59              : class ConvolutionEngine {
      60              :    public:
      61              :     ConvolutionEngine();
      62              :     ~ConvolutionEngine();
      63              : 
      64              :     // Set the active kernel. Resets internal state if kernel changes.
      65              :     void set_kernel(const ConvolutionKernel* kernel);
      66              : 
      67              :     // Process a block of audio in-place.
      68              :     void process(float* buffer, int num_samples);
      69              : 
      70              :     // Reset all internal state.
      71              :     void reset();
      72              : 
      73         6050 :     bool has_kernel() const { return kernel_ != nullptr; }
      74              : 
      75              :    private:
      76              :     const ConvolutionKernel* kernel_ = nullptr;
      77              : 
      78              :     // Frequency-domain delay line (circular buffer of past input blocks in freq domain)
      79              :     std::vector<std::vector<char>> fdl_;  // raw storage for kiss_fft_cpx arrays
      80              :     int fdl_index_ = 0;
      81              : 
      82              :     // Overlap-add tail from previous block
      83              :     std::vector<float> overlap_;
      84              : 
      85              :     // FFT workspace
      86              :     kiss_fft_cfg fft_cfg_ = nullptr;   // forward
      87              :     kiss_fft_cfg ifft_cfg_ = nullptr;  // inverse
      88              : 
      89              :     int current_fft_size_ = 0;
      90              : 
      91              :     // Preallocated FFT buffers (raw storage for kiss_fft_cpx arrays)
      92              :     // Kept here to avoid per-block allocations in the audio callback.
      93              :     std::vector<char> input_cpx_;
      94              :     std::vector<char> accum_cpx_;
      95              :     std::vector<char> ifft_out_cpx_;
      96              : 
      97              :     void init_fft(int fft_size);
      98              :     void cleanup_fft();
      99              : 
     100              :     // Direct time-domain convolution fallback
     101              :     void process_direct(float* buffer, int num_samples);
     102              :     std::vector<float> direct_input_;    // scratch copy of input (allocation-free in callback)
     103              :     std::vector<float> direct_overlap_;  // tail from direct convolution
     104              : };
     105              : 
     106              : }  // namespace Amplitron
        

Generated by: LCOV version 2.0-1