2025-10-22 09:20:23 +02:00

194 lines
5.7 KiB
C++

/*
==============================================================================
This file contains the basic framework code for a JUCE plugin editor.
==============================================================================
*/
#pragma once
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_audio_utils/juce_audio_utils.h>
#include "PluginProcessor.h"
//==============================================================================
/**
*/
class SpectrumAnalyzer {
public:
SpectrumAnalyzer(AudioFIFO& fifoRef, CrystalizerEQAudioProcessor& processor) : audioFIFO(fifoRef), audioProcessor(processor) {
fftData.resize(2 * FFTSIZE);
magnitudes.resize(BINS);
magnitudesDb.resize(BINS);
emaSmoothedMagnitudesDb.resize(BINS);
freqSmoothedMagnitudesDb.resize(BINS);
sampleRate = audioProcessor.getSampleRate();
deltaF = sampleRate / static_cast<double>(FFTSIZE);
freqPerBin.resize(BINS);
peakHoldMagnitudesDb.resize(BINS);
DELTAT = static_cast<float>(HOPSIZE) / static_cast<float>(sampleRate);
renderValuesDb.resize(BINS);
}
~SpectrumAnalyzer() = default;
AudioFIFO& audioFIFO;
CrystalizerEQAudioProcessor& audioProcessor;
static constexpr int FFTSIZE = 4096;
static constexpr int BINS = FFTSIZE / 2 + 1;
static constexpr int HOPSIZE = FFTSIZE / 2;
juce::Array<float> fftFrame;
//CHANGE FOR LOWER/HIGHER EMA-SMOOTHING //LOWER VALUE -> MORE SMOOTHING/SLOW RESPONSE -- HIGHER VALUE -> LESS SMOOTHING/FAST RESPONSE //MAX VALUE = 1.f
float smoothingFactor = 0.3f;
void processSamples();
void getFftFrame(juce::Array<float> &samples);
void applyWindowOnFftFrame(std::vector<float> &fullFrame);
juce::dsp::WindowingFunction<float> window
{
FFTSIZE,
juce::dsp::WindowingFunction<float>::hann
};
void processWindowedFrame(std::vector<float> &windowedFrame);
static constexpr int FFTORDER = 12;
juce::dsp::FFT fft { FFTORDER };
std::vector<float> fftData;
const float MINDB = -120.f;
const float MAXDB = 96.f;
std::vector<float> magnitudes;
std::vector<float> magnitudesDb;
std::vector<float> emaSmoothedMagnitudesDb;
std::vector<float> freqSmoothedMagnitudesDb;
std::vector<float> peakHoldMagnitudesDb;
std::vector<float> renderValuesDb;
double deltaF = 0;
double sampleRate = 44100;
//CHANGE DENOMINATOR FOR LOWER/HIGHER FREQ-SMOOTHING //HIGHER VALUE -> HIGHER SMOOTHING -- LESS VALUE -> LESS SMOOTHING
const float BANDWIDTHOCT = 1.f / 6.f;
const float OCTAVERADIUS = BANDWIDTHOCT / 2.f;
std::vector<double> freqPerBin;
//CHANGE FOR FASTER FALLOFF -- VALUE IS IN DB/S
const float FALLOFFRATE = 120.f;
float DELTAT = 0.f;
float tempPeakHoldDB = 0.f;
const float MINFREQ = 20.0f;
const float MAXFREQ = static_cast<float>(sampleRate) / 2;
void fillFftDataFromFrame(std::vector<float> &windowedFrame);
void buildMagnitudeSpectrum();
void convertToDb();
void applySmoothing();
void applyEMA();
void applyFreqSmoothing();
void applyPeakHoldAndFalloff();
std::vector<float> getRenderValues();
};
class CrystalizerEQAudioProcessorEditor : public juce::AudioProcessorEditor, private juce::Timer
{
public:
CrystalizerEQAudioProcessorEditor (CrystalizerEQAudioProcessor&);
~CrystalizerEQAudioProcessorEditor() override;
//===================================================================
void timerCallback();
void paint (juce::Graphics&) override;
void resized() override;
private:
// This reference is provided as a quick way for your editor to
// access the processor object that created it.
CrystalizerEQAudioProcessor& audioProcessor;
using SliderAttach = juce::AudioProcessorValueTreeState::SliderAttachment;
using ButtonAttach = juce::AudioProcessorValueTreeState::ButtonAttachment;
using ComboBoxAttach = juce::AudioProcessorValueTreeState::ComboBoxAttachment;
juce::Slider testNoiseSlider,
lowBandFreqSlider, lowBandSlopeSlider, lowBandGainSlider, lowBandQSlider,
peak1FreqSlider, peak1GainSlider, peak1QSlider,
peak2FreqSlider, peak2GainSlider, peak2QSlider,
peak3FreqSlider, peak3GainSlider, peak3QSlider,
highBandFreqSlider, highBandSlopeSlider, highBandGainSlider, highBandQSlider,
inputSlider, outputSlider;
std::unique_ptr<SliderAttach> testNoiseAttach,
lowBandFreqAttach, lowBandSlopeAttach, lowBandGainAttach, lowBandQAttach,
peak1FreqAttach, peak1GainAttach, peak1QAttach,
peak2FreqAttach, peak2GainAttach, peak2QAttach,
peak3FreqAttach, peak3GainAttach, peak3QAttach,
highBandFreqAttach, highBandSlopeAttach, highBandGainAttach, highBandQAttach,
inputAttach, outputAttach;
juce::Label testNoiseLabel,
lowBandFreqLabel, lowBandSlopeLabel, lowBandGainLabel, lowBandQLabel,
peak1FreqLabel, peak1GainLabel, peak1QLabel,
peak2FreqLabel, peak2GainLabel, peak2QLabel,
peak3FreqLabel, peak3GainLabel, peak3QLabel,
highBandFreqLabel, highBandSlopeLabel, highBandGainLabel, highBandQLabel,
inputLabel, outputLabel,
presetBoxLabel;
juce::TextButton testNoiseButton, resetButton, savePresetButton, deletePresetButton;
juce::ToggleButton masterBypassButton, crystalizeButton, peak1BypassButton, peak2BypassButton, peak3BypassButton, presetMenuButton;
juce::ComboBox lowBandModeBox, highBandModeBox, presetBox;
std::unique_ptr<ComboBoxAttach> lowBandModeAttach, highBandModeAttach;
juce::TextEditor presetNameInput;
//SPECRTRUM ANALYZER
SpectrumAnalyzer spectrumAnalyzer;
juce::Rectangle<int> analyzerArea;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CrystalizerEQAudioProcessorEditor)
};