Files
InstaLPEQ/Source/FIREngine.h
hariel1985 aa546c7357 v1.3: Auto makeup gain, spectrum analyzer, FIR normalization, README overhaul
- Auto makeup gain: RMS-based loudness compensation from actual FIR response
- Real-time FFT spectrum analyzer behind EQ curves
- FIR normalization fix: flat settings now produce exact 0 dB passthrough
- Brickwall limiter (0 dB ceiling) with toggle
- Drag-and-drop signal chain reordering
- Low FIR tap count warning for 512/1024
- Double-click reset on all knobs
- Comprehensive README with linear phase EQ explanation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:28:31 +01:00

53 sor
1.5 KiB
C++

#pragma once
#include <JuceHeader.h>
#include "EQBand.h"
class FIREngine : private juce::Thread
{
public:
static constexpr int defaultFFTOrder = 11; // 2048 taps
static constexpr int maxBands = 8;
FIREngine();
~FIREngine() override;
void start (double sampleRate);
void stop();
// Called from GUI thread
void setBands (const std::vector<EQBand>& newBands);
void setFFTOrder (int order);
// Called from audio thread — returns new FIR if available, nullptr otherwise
std::unique_ptr<juce::AudioBuffer<float>> getNewFIR();
// Get magnitude response in dB for display (thread-safe copy)
std::vector<float> getMagnitudeResponseDb() const;
int getFIRLength() const { return 1 << fftOrder.load(); }
int getLatencySamples() const { return getFIRLength() / 2; }
// Auto makeup gain: A-weighted RMS loudness compensation (dB)
float getAutoMakeupGainDb() const { return autoMakeupDb.load(); }
private:
void run() override;
juce::AudioBuffer<float> generateFIR (const std::vector<EQBand>& bands, double sr, int order);
std::atomic<double> sampleRate { 44100.0 };
std::atomic<int> fftOrder { defaultFFTOrder };
std::atomic<bool> needsUpdate { true };
std::vector<EQBand> currentBands;
mutable juce::SpinLock bandLock;
std::unique_ptr<juce::AudioBuffer<float>> pendingFIR;
juce::SpinLock firLock;
std::vector<float> magnitudeDb;
mutable juce::SpinLock magLock;
std::atomic<float> autoMakeupDb { 0.0f };
static float aWeighting (float freq);
};