#pragma once #include #include "../concurrency/BufferConsumer.h" class OscirenderAudioProcessor; class PitchDetector : public juce::Thread, public juce::AsyncUpdater { public: PitchDetector(OscirenderAudioProcessor& audioProcessor); ~PitchDetector(); void run() override; void handleAsyncUpdate() override; int addCallback(std::function callback); void removeCallback(int index); void setSampleRate(float sampleRate); std::atomic frequency = 0.0f; private: static constexpr int fftOrder = 15; static constexpr int fftSize = 1 << fftOrder; std::shared_ptr consumer; std::vector buffer = std::vector(2 * fftSize); juce::dsp::FFT forwardFFT{fftOrder}; std::array fftData; OscirenderAudioProcessor& audioProcessor; std::vector> callbacks; juce::SpinLock lock; float sampleRate = 192000.0f; float frequencyFromIndex(int index); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PitchDetector) };