#pragma once #include namespace gelyk { // A single peaking/shelf filter band with smoothed coefficients. struct FilterBand { enum class Type { lowShelf, peak, highShelf }; Type type = Type::peak; float gainDb = 0.0f; // target gain in dB float freq = 1000.0f; // centre/corner frequency float q = 1.0f; void prepare(double sampleRate, int blockSize); void reset(); void process(juce::dsp::AudioBlock& block); using Filter = juce::dsp::IIR::Filter; using Coeffs = juce::dsp::IIR::Coefficients; Filter left, right; }; // Simple background "realtime" analyser: it keeps a circular ring buffer // of the most recent input, computes an FFT magnitude spectrum periodically // in a background thread, and exposes the result thread-safely for the UI. class SpectrumAnalyser : public juce::Timer { public: SpectrumAnalyser(); void prepare(double sampleRate, int maxBlockSize); void push(const float* const* channels, int numChannels, int numSamples); void startBackground(); void stopBackground(); // Copies the latest spectrum into `dest` (size destSize) with equal // log-spaced bands, returning the number of bins written. int copySpectrum(juce::Array& dest, juce::Array& freqBins, int maxBins) const; void setEnabled(bool enabled); private: void timerCallback() override; void runAnalysis(); mutable juce::CriticalSection spectrumLock; juce::Array readySpectrum; // dB magnitudes per bin juce::AudioBuffer ring; int ringFill = 0; int ringChannels = 0; double sampleRate = 44100.0; std::atomic enabled { true }; }; } // namespace gelyk