290 lines
8.5 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"
#include "AXIOMDesignSystem.h"
//==============================================================================
/**
*/
using AXIOM::DesignSystem;
using Components = DesignSystem::Components;
using SliderStyles = Components::SliderStyles;
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 paintAnalyzer(juce::Graphics &g);
void paintBorderLines(juce::Graphics& g);
//===================================================================
void timerCallback();
void paint (juce::Graphics&) override;
void resized() override;
void resetAllCheckboxes();
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;
const juce::Array<juce::Slider*> sliders = {
&lowBandGainSlider, &lowBandFreqSlider, &lowBandQSlider, &lowBandSlopeSlider,
&peak1GainSlider, &peak1FreqSlider, &peak1QSlider,
&peak2GainSlider, &peak2FreqSlider, &peak2QSlider,
&peak3GainSlider, &peak3FreqSlider, &peak3QSlider,
&highBandGainSlider, &highBandFreqSlider, &highBandQSlider, &highBandSlopeSlider,
&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 titleLabel, testNoiseLabel,
lowBandFreqLabel, lowBandSlopeLabel, lowBandGainLabel, lowBandQLabel,
peak1FreqLabel, peak1GainLabel, peak1QLabel,
peak2FreqLabel, peak2GainLabel, peak2QLabel,
peak3FreqLabel, peak3GainLabel, peak3QLabel,
highBandFreqLabel, highBandSlopeLabel, highBandGainLabel, highBandQLabel,
inputLabel, outputLabel,
presetBoxLabel;
const juce::Array<juce::Label*> sliderLabels = {
&lowBandFreqLabel, &lowBandSlopeLabel, &lowBandGainLabel, &lowBandQLabel,
&peak1FreqLabel, &peak1GainLabel, &peak1QLabel,
&peak2FreqLabel, &peak2GainLabel, &peak2QLabel,
&peak3FreqLabel, &peak3GainLabel, &peak3QLabel,
&highBandFreqLabel, &highBandSlopeLabel, &highBandGainLabel, &highBandQLabel,
&inputLabel, &outputLabel
};
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;
void setKnobVisibility();
void setupModeBoxes();
void setupSliders();
void setupAttachments();
void setupDisplayNames();
void setupToggleButtons();
void addComponentsToLayout();
void setupLabels();
void setupFontsWithColours();
void setupEventListeners();
void initPresetSystem();
//SPECRTRUM ANALYZER
SpectrumAnalyzer spectrumAnalyzer;
juce::Rectangle<int> analyzerRect;
Component headerBar;
Component mainPanel;
Component footerBar;
Component presetArea;
Component presetMenu;
Component analyzerArea;
Component filterArea;
Component lowFilterArea;
Component lowMidFilterArea;
Component midFilterArea;
Component highMidFilterArea;
Component highFilterArea;
const juce::Array<juce::Component*> filterAreas {
&lowFilterArea, &lowMidFilterArea, &midFilterArea, &highMidFilterArea, &highFilterArea
};
Component globalControlArea;
void scalePluginWindow(juce::Rectangle<int> area);
void setupMainGrid(juce::Rectangle<int> area);
void setupLowBandLayout();
void setupLowMidBandLayout();
void setupMidBandLayout();
void setupHighMidBandLayout();
void setupHighBandLayout();
void setupHeader();
void setupBody();
void setupFooter();
juce::Array<float> getReferenceCell();
const float gainMod = SliderStyles::Size::getSliderSizeMod(SliderStyles::Size::SizeMode::Gain);
const float freqMod = SliderStyles::Size::getSliderSizeMod(SliderStyles::Size::SizeMode::Freq);
const float qMod = SliderStyles::Size::getSliderSizeMod(SliderStyles::Size::SizeMode::Q);
const float slopeMod = SliderStyles::Size::getSliderSizeMod(SliderStyles::Size::SizeMode::Slope);
const float globalMod = SliderStyles::Size::getSliderSizeMod(SliderStyles::Size::SizeMode::Global);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CrystalizerEQAudioProcessorEditor)
};