/* ============================================================================== This file contains the basic framework code for a JUCE plugin editor. ============================================================================== */ #pragma once #include #include "PluginProcessor.h" #include "GraphComponent.h" #include "ScopeComponent.h" class ScopeSliderComponent : public juce::Component { static const int fontSize = 11; public: ScopeSliderComponent(juce::AudioProcessorValueTreeState& tree, const std::string paramGroup) { const auto& sliderDetails = PARAM_SETTINGS.at(paramGroup); for (const auto& [name, sliderDetail] : sliderDetails) { sliders.push_back(std::make_unique()); labels.push_back(std::make_unique()); attachments.push_back(std::make_unique( tree, paramGroup + "_" + name, *sliders.back())); labels.back()->setText(sliderDetail.label, juce::NotificationType::dontSendNotification); sliders.back()->setRange(sliderDetail.min, sliderDetail.max); } for (auto& slider : sliders) { slider->setSliderStyle(juce::Slider::Rotary); slider->setTextBoxStyle(juce::Slider::TextBoxBelow, false, 50, 20); addAndMakeVisible(*slider); } for (auto& label : labels) { label->setFont(juce::Font((float)fontSize, juce::Font::bold)); label->setColour(juce::Label::textColourId, juce::Colours::lightgreen); label->setJustificationType(juce::Justification::centred); //label->setBoundsToFit() addAndMakeVisible(*label); } } void enableSampleScope(AudioBufferQueue& audioBufferQueue) { scope.emplace(audioBufferQueue); useGraphScope = false; addAndMakeVisible(*scope); } void enableGraphScope(const std::function& func) { graphScope.emplace(0.0f, 1.0f, 100); graphScope->setFunction(func); useGraphScope = true; addAndMakeVisible(*graphScope); } private: void paint(juce::Graphics& g) override { //juce::Random rng; //g.fillAll(juce::Colour::fromFloatRGBA(rng.nextFloat(), rng.nextFloat(), rng.nextFloat(), 1.0f)); g.fillAll(juce::Colours::darkgrey); g.setColour(juce::Colours::white); g.drawRect(getLocalBounds()); } void resized() override { juce::Grid grid; grid.templateRows = { juce::Grid::TrackInfo(juce::Grid::Fr(50)), juce::Grid::TrackInfo(juce::Grid::Fr(30)), juce::Grid::TrackInfo(juce::Grid::Fr(10)), juce::Grid::TrackInfo(juce::Grid::Fr(10)) }; grid.templateColumns.resize(sliders.size()); for (int i = 0; i < sliders.size(); i++) { grid.templateColumns.getReference(i) = juce::Grid::TrackInfo(juce::Grid::Fr(1)); } std::optional scopeGridItem; scopeGridItem.emplace(useGraphScope ? juce::GridItem(*graphScope).withArea({}, juce::GridItem::Span(sliders.size())) : juce::GridItem(*scope).withArea({}, juce::GridItem::Span(sliders.size()))); grid.items.resize(1 + 2 * sliders.size()); grid.items.getReference(0) = *scopeGridItem; for (int i = 0; i < sliders.size(); i++) { grid.items.getReference(i + 1) = juce::GridItem(*sliders[i]); } for (int i = 0; i < sliders.size(); i++) { grid.items.getReference(i + sliders.size() + 1) = juce::GridItem(*labels[i]); }; auto bounds = getLocalBounds().reduced(10); grid.performLayout(bounds); } bool useGraphScope{ false }; std::optional > scope; std::optional > graphScope; std::vector > sliders; std::vector > labels; std::vector > attachments; }; class EqualizerComponent : public juce::Component { static const int fontSize = 11; public: EqualizerComponent(juce::AudioProcessorValueTreeState& tree) { setupSlider(lowGainSlider); setupSlider(midGainSlider); setupSlider(highGainSlider); setupLabel(lowGainLabel, "L"); setupLabel(midGainLabel, "M"); setupLabel(highGainLabel, "H"); lowGainAttachment = std::make_unique(tree, "lowEQ", lowGainSlider); midGainAttachment = std::make_unique(tree, "midEQ", midGainSlider); highGainAttachment = std::make_unique(tree, "highEQ", highGainSlider); } void setupSlider(juce::Slider& slider) { slider.setRange(-24.0f, 24.0f, 0.1f); slider.setSliderStyle(juce::Slider::LinearBarVertical); slider.setTextBoxStyle(juce::Slider::TextBoxBelow, false, 50, 20); addAndMakeVisible(slider); } void setupLabel(juce::Label &lbl, juce::String txt) { lbl.setFont(juce::Font((float)fontSize, juce::Font::bold)); lbl.setColour(juce::Label::textColourId, juce::Colours::lightgreen); lbl.setJustificationType(juce::Justification::centred); lbl.setText(txt, juce::NotificationType::dontSendNotification); addAndMakeVisible(lbl); } private: void paint(juce::Graphics& g) override { g.fillAll(juce::Colours::darkgrey); g.setColour(juce::Colours::white); g.drawRect(getLocalBounds()); } void resized() override { juce::Grid grid; grid.templateRows = { juce::Grid::TrackInfo(juce::Grid::Fr(1)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) }; grid.templateColumns = { juce::Grid::TrackInfo(juce::Grid::Fr(1)), juce::Grid::TrackInfo(juce::Grid::Fr(1)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) }; grid.items = { lowGainSlider, midGainSlider, highGainSlider, lowGainLabel, midGainLabel, highGainLabel }; auto bounds = getLocalBounds().reduced(10); grid.performLayout(bounds); } juce::Slider lowGainSlider, midGainSlider, highGainSlider; juce::Label lowGainLabel, midGainLabel, highGainLabel; std::unique_ptr lowGainAttachment, midGainAttachment, highGainAttachment; }; struct WaveformSelectorContents final : public juce::ListBoxModel { // The following methods implement the necessary virtual functions from ListBoxModel, // telling the listbox how many rows there are, painting them, etc. int getNumRows() override { return 4; } void paintListBoxItem(int rowNumber, juce::Graphics& g, int width, int height, bool rowIsSelected) override { if (rowIsSelected) g.fillAll(juce::Colours::lightblue); g.setColour(juce::LookAndFeel::getDefaultLookAndFeel().findColour(juce::Label::textColourId)); g.setFont((float)height * 0.7f); g.drawText(waves[rowNumber], 5, 0, width, height, juce::Justification::centredLeft, true); } std::vector waves = { "Sine", "Saw", "Square", "Triangle" }; }; class MasterVolumeComponent : public juce::Component { public: MasterVolumeComponent() { slider.setSliderStyle(juce::Slider::LinearBarVertical); slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 20, 20); // Optional addAndMakeVisible(slider); } void resized() override { auto padded = getLocalBounds().reduced(30); // Adjust padding here slider.setBounds(padded); } juce::Slider slider; }; //============================================================================== /** */ class NeuralSynthAudioProcessorEditor : public juce::AudioProcessorEditor { public: NeuralSynthAudioProcessorEditor (NeuralSynthAudioProcessor&); ~NeuralSynthAudioProcessorEditor() override; //============================================================================== 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. NeuralSynthAudioProcessor& audioProcessor; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NeuralSynthAudioProcessorEditor) juce::ListBox waveformSelector; WaveformSelectorContents waveformContents; //std::unique_ptr waveformAttachment; //============================================================================== // ADSR /*void createADSR(int xCoord, int yCoord); juce::Slider attackSlider, decaySlider, sustainSlider, releaseSlider; juce::Label attackLabel, decayLabel, sustainLabel, releaseLabel; std::unique_ptr attackAttachment; std::unique_ptr decayAttachment; std::unique_ptr sustainAttachment; std::unique_ptr releaseAttachment;*/ //============================================================================== std::optional adsrComponent; std::optional chorusComponent; std::optional delayComponent; std::optional reverbComponent; std::optional flangerComponent; std::optional distortionComponent; std::optional filterComponent; /*//============================================================================== // Chorus void createChorus(int xCoord, int yCoord); juce::Slider chorusRateSlider, chorusDepthSlider, chorusCentreSlider, chorusFeedbackSlider, chorusMixSlider; juce::Label chorusRateLabel, chorusDepthLabel, chorusCentreLabel, chorusFeedbackLabel, chorusMixLabel; std::unique_ptr chorusRateAttachment; std::unique_ptr chorusDepthAttachment; std::unique_ptr chorusCentreAttachment; std::unique_ptr chorusFeedbackAttachment; std::unique_ptr chorusMixAttachment; //============================================================================== //============================================================================== // Delay void createDelay(int xCoord, int yCoord); juce::Slider delayDelaySlider; juce::Label delayDelayLabel; std::unique_ptr delayDelayAttachment; //============================================================================== //============================================================================== // Reverb void createReverb(int xCoord, int yCoord); juce::Slider reverbRoomSizeSlider, reverbDampingSlider, reverbWetLevelSlider, reverbDryLevelSlider, reverbWidthSlider, reverbFreezeModeSlider; juce::Label reverbRoomSizeLabel, reverbDampingLabel, reverbWetLevelLabel, reverbDryLevelLabel, reverbWidthLabel, reverbFreezeModeLabel; std::unique_ptr reverbRoomSizeAttachment; std::unique_ptr reverbDampingAttachment; std::unique_ptr reverbWetLevelAttachment; std::unique_ptr reverbDryLevelAttachment; std::unique_ptr reverbWidthAttachment; std::unique_ptr reverbFreezeModeAttachment;*/ //============================================================================== // Master MasterVolumeComponent masterLevelSlider; juce::Label masterLevelLabel; //============================================================================== //============================================================================== // EQ //void updateEQFromSliders(); std::optional eqComponent; //============================================================================== //============================================================================== // Master juce::Slider gainSlider; juce::Label gainLabel; std::unique_ptr gainAttachment; //============================================================================== //juce::MidiKeyboardState midiKeyboardState; //juce::MidiKeyboardComponent midiKeyboardComponent{ midiKeyboardState, juce::MidiKeyboardComponent::horizontalKeyboard }; ScopeComponent mainScopeComponent; /*ScopeComponent chorusScopeComponent; ScopeComponent delayScopeComponent; ScopeComponent reverbScopeComponent; GraphComponent adsrGraph;*/ };