LCOV - code coverage report
Current view: top level - src/audio/effects - tuner.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 3 3
Test Date: 2026-06-03 09:13:19 Functions: 100.0 % 3 3

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : // Chromatic tuner based on pitch detection from the input signal.
       4              : // Uses the YIN difference d(tau)=sum_j(x[j]-x[j+tau])^2 and cumulative mean
       5              : // normalized difference to estimate period tau; frequency is Fs/tau and cents
       6              : // error is 1200*log2(freq / nearest_note_freq).
       7              : 
       8              : #include "audio/effects/effect.h"
       9              : #include <atomic>
      10              : 
      11              : namespace Amplitron {
      12              : 
      13              : class TunerPedal : public Effect {
      14              : public:
      15              :     TunerPedal();
      16              :     void process(float* buffer, int num_samples) override;
      17              :     void set_sample_rate(int sample_rate) override;
      18              :     void reset() override;
      19           29 :     const char* name() const override { return "Tuner"; }
      20            3 :     const char* type_id() const override { return "Tuner"; }
      21          103 :     std::vector<EffectParam>& params() override { return params_; }
      22              : 
      23              :     // Tuner detection results (audio thread writes, UI thread reads)
      24              :     std::atomic<float> detected_freq{0.0f};
      25              :     std::atomic<float> detected_cents{0.0f};
      26              :     std::atomic<int> detected_note{-1};    // 0=C, 1=C#, 2=D, ... 11=B
      27              :     std::atomic<int> detected_octave{-1};
      28              :     std::atomic<bool> signal_detected{false};
      29              : 
      30              :     static const char* note_name(int note_index);
      31              : 
      32              : private:
      33              :     std::vector<EffectParam> params_;
      34              : 
      35              :     // YIN pitch detection buffer
      36              :     // 4096 samples at 48kHz gives ~85ms window, ample headroom for E2 (82.41Hz, period ~582 samples)
      37              :     static constexpr int YIN_BUFFER_SIZE = 4096;
      38              :     std::vector<float> yin_buffer_;
      39              :     int yin_write_pos_ = 0;
      40              :     bool yin_buffer_full_ = false;
      41              : 
      42              :     // YIN internals
      43              :     float yin_detect_pitch(float a4_ref);
      44              :     void freq_to_note(float freq, float a4_ref);
      45              : 
      46              :     // Preallocated work buffers for yin_detect_pitch() (avoids RT heap allocs)
      47              :     std::vector<float> yin_buf_;   // linearized circular buffer (YIN_BUFFER_SIZE)
      48              :     std::vector<float> yin_d_;     // cumulative mean normalized difference (YIN_BUFFER_SIZE/2)
      49              : 
      50              :     // Update rate control (~15 updates/sec)
      51              :     int samples_since_update_ = 0;
      52              :     int update_interval_ = 0;
      53              :     void recalc_update_interval();
      54              : };
      55              : 
      56              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1