LCOV - code coverage report
Current view: top level - src/audio/effects/core - effect.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 98.3 % 60 59
Test Date: 2026-06-07 15:51:50 Functions: 88.9 % 18 16

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <atomic>
       4              : #include <cstring>
       5              : #include <memory>
       6              : #include <nlohmann/json.hpp>
       7              : #include <string>
       8              : #include <vector>
       9              : 
      10              : #include "audio/effects/core/effect_param.h"
      11              : #include "audio/effects/core/i_metadata.h"
      12              : #include "audio/effects/core/i_parameterizable.h"
      13              : #include "audio/effects/core/i_processor.h"
      14              : #include "audio/effects/core/i_serializable.h"
      15              : #include "common.h"
      16              : 
      17              : namespace Amplitron {
      18              : 
      19              : // Common interface for all mono/stereo audio effects in the pedal chain.
      20         1172 : class Effect : public IProcessor, public IParameterizable, public ISerializable, public IMetadata {
      21              :    public:
      22         1251 :     virtual ~Effect() = default;
      23              : 
      24              :     // Process a mono buffer in place.
      25              :     virtual void process(float* buffer, int num_samples) override = 0;
      26              : 
      27              :     // Stereo processing. Default fans mono left channel to both outputs.
      28              :     // Stereo-capable effects override this to produce true stereo.
      29            3 :     virtual void process_stereo(float* left, float* right, int num_samples) override {
      30            3 :         process(left, num_samples);
      31            3 :         std::memcpy(right, left, static_cast<size_t>(num_samples) * sizeof(float));
      32            3 :     }
      33              : 
      34              :     // Update the processing sample rate before audio starts or after device changes.
      35         2103 :     virtual void set_sample_rate(int sample_rate) override { sample_rate_ = sample_rate; }
      36              : 
      37              :     // Clear delay lines, envelopes, filters, and other effect state.
      38              :     virtual void reset() override = 0;
      39              : 
      40              :     // Tempo broadcast receiver.
      41           42 :     virtual void set_transport_state(float /*bpm*/) {}
      42              : 
      43              :     // Display name used by the pedal board and preset serialization.
      44              :     virtual const char* name() const override = 0;
      45              : 
      46            0 :     virtual const char* type_id() const override { return name(); }
      47              : 
      48              :     // Mutable parameter list used by controls and automation.
      49              :     virtual std::vector<EffectParam>& params() override = 0;
      50              :     virtual const std::vector<EffectParam>& params() const override = 0;
      51              : 
      52          636 :     void set_enabled(bool enabled) { enabled_ = enabled; }
      53         1459 :     bool is_enabled() const { return enabled_; }
      54              : 
      55          525 :     void set_mix(float mix) { mix_.store(clamp(mix, 0.0f, 1.0f), std::memory_order_relaxed); }
      56         1018 :     float get_mix() const { return mix_.load(std::memory_order_relaxed); }
      57              : 
      58              :     virtual std::shared_ptr<Effect> clone() const;
      59              : 
      60            3 :     std::vector<std::string> get_param_names() override {
      61            3 :         std::vector<std::string> names;
      62           15 :         for (const auto& p : params()) {
      63           12 :             names.push_back(p.name);
      64              :         }
      65            3 :         return names;
      66            1 :     }
      67              : 
      68           15 :     float get_param_value(const std::string& name) override {
      69           24 :         for (const auto& p : params()) {
      70           21 :             if (p.name == name) {
      71           12 :                 return p.value;
      72              :             }
      73              :         }
      74            2 :         return 0.0f;
      75            5 :     }
      76              : 
      77            9 :     void set_param_by_name(const std::string& name, float value) override {
      78            9 :         for (auto& p : params()) {
      79            9 :             if (p.name == name) {
      80            9 :                 p.value = clamp(value, p.min_val, p.max_val);
      81            9 :                 return;
      82              :             }
      83              :         }
      84            3 :     }
      85              : 
      86            3 :     virtual const char* get_display_name() const override { return name(); }
      87              : 
      88              :     // --- AUTOMATED SERIALIZATION LOGIC ---
      89              :     // These methods automatically handle saving/loading for any effect
      90              :     // that uses the EffectParam vector.
      91              : 
      92            9 :     virtual nlohmann::json get_params() const override {
      93            9 :         nlohmann::json j;
      94            9 :         const auto& p_list = params();
      95           36 :         for (const auto& p : p_list) {
      96           36 :             j[p.name] = p.value;
      97              :         }
      98            9 :         j["enabled"] = enabled_.load();
      99            9 :         j["mix"] = mix_.load(std::memory_order_relaxed);
     100            9 :         return j;
     101            3 :     }
     102              : 
     103           12 :     virtual void set_params(const nlohmann::json& j) override {
     104           12 :         if (j.contains("enabled")) enabled_.store(j["enabled"].get<bool>());
     105           12 :         if (j.contains("mix")) mix_.store(j["mix"].get<float>(), std::memory_order_relaxed);
     106              : 
     107           12 :         auto& p_list = params();
     108           48 :         for (auto& p : p_list) {
     109           36 :             if (j.contains(p.name)) {
     110           27 :                 p.value = j[p.name];
     111            9 :             }
     112              :         }
     113           12 :     }
     114              : 
     115              :    protected:
     116          586 :     int sample_rate_ = DEFAULT_SAMPLE_RATE;
     117          586 :     std::atomic<bool> enabled_{true};
     118          586 :     std::atomic<float> mix_{1.0f};
     119              : 
     120              :     // Wet/dry mix helper
     121            6 :     void apply_mix(const float* dry, float* wet, int num_samples) {
     122            6 :         float current_mix = mix_.load(std::memory_order_relaxed);
     123            6 :         if (current_mix >= 1.0f) return;
     124           15 :         for (int i = 0; i < num_samples; ++i) {
     125           12 :             wet[i] = dry[i] * (1.0f - current_mix) + wet[i] * current_mix;
     126            4 :         }
     127            2 :     }
     128              : };
     129              : 
     130              : }  // namespace Amplitron
        

Generated by: LCOV version 2.0-1