#pragma once #include "buffer.h" #include "fft/pffft.h" constexpr static int METER_MAX_CHANNELS = 2; class FFTObserver { const int stride; uint32_t enabled; BufferF32 inputQueue; BufferF32 windowFunction; int inputQueueWriteIndex; float decayAlpha; void doFrame(); PFFFT_Setup *setup; public: FFTObserver(int channelCount, int binCount, int stride, float decayAlpha); ~FFTObserver(); void update(const BufferF32 &buf); bool getEnabled() const; void setEnabled(bool enabled); float getDecayAlpha() const; void setDecayAlpha(float decayAlpha); const std::shared_ptr buffer; }; class Meter { const int channelCount; const int sampleRate; const float ppmHoldUpdateHz; const int ppmHoldKeepPeriods; const float vuAlpha; BufferF32 ppmHoldValues; int ppmHoldValuesWriteIndex; BufferF32 ppmHoldBuffer; BufferF32 ppmHoldBufferRemaining; float lastVuValue[METER_MAX_CHANNELS]; float ppmHoldIndicated[METER_MAX_CHANNELS]; float ppmIndicated[METER_MAX_CHANNELS]; float vuIndicated[METER_MAX_CHANNELS]; FFTObserver fftObserver; public: Meter(int channelCount, int sampleRate, float ppmHoldUpdateHz, int ppmHoldKeepPeriods, float vuAlpha); void update(const BufferF32 &buf); float getPpmHoldIndicated(int channel) const { assert(channel >= 0 && channel < channelCount); return ppmHoldIndicated[channel]; } float getPpmIndicated(int channel) const { assert(channel >= 0 && channel < channelCount); return ppmIndicated[channel]; } float getVuIndicated(int channel) const { assert(channel >= 0 && channel < channelCount); return vuIndicated[channel]; } std::shared_ptr getFFTObserverBuffer() const; bool getFFTObserverEnabled() const; void setFFTObserverEnabled(bool enabled); float getFFTObserverDecayAlpha() const; void setFFTObserverDecayAlpha(float decayAlpha); };