/* ============================================================================== This file contains the basic framework code for a JUCE plugin editor. ============================================================================== */ #pragma once #include #include #include "PluginProcessor.h" #include "AXIOMDesignSystem.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(FFTSIZE); freqPerBin.resize(BINS); peakHoldMagnitudesDb.resize(BINS); DELTAT = static_cast(HOPSIZE) / static_cast(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 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 &samples); void applyWindowOnFftFrame(std::vector &fullFrame); juce::dsp::WindowingFunction window { FFTSIZE, juce::dsp::WindowingFunction::hann }; void processWindowedFrame(std::vector &windowedFrame); static constexpr int FFTORDER = 12; juce::dsp::FFT fft { FFTORDER }; std::vector fftData; const float MINDB = -120.f; const float MAXDB = 96.f; std::vector magnitudes; std::vector magnitudesDb; std::vector emaSmoothedMagnitudesDb; std::vector freqSmoothedMagnitudesDb; std::vector peakHoldMagnitudesDb; std::vector 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 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(sampleRate) / 2; void fillFftDataFromFrame(std::vector &windowedFrame); void buildMagnitudeSpectrum(); void convertToDb(); void applySmoothing(); void applyEMA(); void applyFreqSmoothing(); void applyPeakHoldAndFalloff(); std::vector 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 testNoiseAttach, lowBandFreqAttach, lowBandSlopeAttach, lowBandGainAttach, lowBandQAttach, peak1FreqAttach, peak1GainAttach, peak1QAttach, peak2FreqAttach, peak2GainAttach, peak2QAttach, peak3FreqAttach, peak3GainAttach, peak3QAttach, highBandFreqAttach, highBandSlopeAttach, highBandGainAttach, highBandQAttach, inputAttach, outputAttach; juce::Label titleLabel, 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 lowBandModeAttach, highBandModeAttach; juce::TextEditor presetNameInput; //SPECRTRUM ANALYZER SpectrumAnalyzer spectrumAnalyzer; juce::Rectangle analyzerArea; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CrystalizerEQAudioProcessorEditor) };