Upload files to "Source"
This commit is contained in:
@@ -25,6 +25,8 @@ public:
|
||||
attachments.push_back(std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment>(
|
||||
tree, paramGroup + "_" + name, *sliders.back()));
|
||||
|
||||
paramNames.push_back(name);
|
||||
|
||||
labels.back()->setText(sliderDetail.label, juce::dontSendNotification);
|
||||
sliders.back()->setRange(sliderDetail.min, sliderDetail.max);
|
||||
}
|
||||
@@ -55,12 +57,74 @@ public:
|
||||
addAndMakeVisible(titleLabel);
|
||||
}
|
||||
|
||||
// Bypass toggle (per panel), id "<group>_on"
|
||||
bypassButton.setButtonText("On");
|
||||
bypassButton.setClickingTogglesState(true);
|
||||
addAndMakeVisible(bypassButton);
|
||||
bypassAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(
|
||||
treeRef, paramGroupId + "_on", bypassButton);
|
||||
if (tree.getParameter(paramGroupId + "_on") != nullptr)
|
||||
{
|
||||
hasBypass = true;
|
||||
bypassButton.setButtonText("On");
|
||||
bypassButton.setClickingTogglesState(true);
|
||||
addAndMakeVisible(bypassButton);
|
||||
bypassAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(
|
||||
treeRef, paramGroupId + "_on", bypassButton);
|
||||
}
|
||||
}
|
||||
|
||||
void setTitleText(const juce::String& text)
|
||||
{
|
||||
if (titleLabel.isVisible())
|
||||
titleLabel.setText(text, juce::dontSendNotification);
|
||||
}
|
||||
|
||||
void setTopBarAccessory(juce::Component* component, int preferredWidth = 120)
|
||||
{
|
||||
topBarAccessory = component;
|
||||
accessoryPreferredWidth = preferredWidth;
|
||||
if (topBarAccessory != nullptr)
|
||||
addAndMakeVisible(*topBarAccessory);
|
||||
}
|
||||
|
||||
void reassignParamGroup(const std::string& newGroup)
|
||||
{
|
||||
if (newGroup == paramGroupId)
|
||||
return;
|
||||
|
||||
const auto& sliderDetails = PARAM_SETTINGS.at(newGroup);
|
||||
jassert(sliderDetails.size() == sliders.size());
|
||||
jassert(sliderDetails.size() == labels.size());
|
||||
jassert(sliderDetails.size() == paramNames.size());
|
||||
|
||||
for (size_t i = 0; i < sliderDetails.size(); ++i)
|
||||
{
|
||||
const auto& [name, detail] = sliderDetails[i];
|
||||
paramNames[i] = name;
|
||||
sliders[i]->setRange(detail.min, detail.max, detail.interval);
|
||||
labels[i]->setText(detail.label, juce::dontSendNotification);
|
||||
}
|
||||
|
||||
attachments.clear();
|
||||
attachments.reserve(sliderDetails.size());
|
||||
for (size_t i = 0; i < sliderDetails.size(); ++i)
|
||||
{
|
||||
const auto paramId = newGroup + "_" + paramNames[i];
|
||||
attachments.push_back(std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment>(
|
||||
treeRef, paramId, *sliders[i]));
|
||||
}
|
||||
|
||||
if (hasBypass)
|
||||
{
|
||||
bypassAttachment.reset();
|
||||
if (treeRef.getParameter(newGroup + "_on") != nullptr)
|
||||
{
|
||||
bypassAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(
|
||||
treeRef, newGroup + "_on", bypassButton);
|
||||
bypassButton.setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bypassButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
paramGroupId = newGroup;
|
||||
}
|
||||
|
||||
void enableSampleScope(AudioBufferQueue<float>& audioBufferQueue) {
|
||||
@@ -76,7 +140,17 @@ public:
|
||||
addAndMakeVisible(*graphScope);
|
||||
}
|
||||
|
||||
juce::Slider* getSlider(const std::string& name) { return findSlider(name); }
|
||||
|
||||
private:
|
||||
juce::Slider* findSlider(const std::string& name)
|
||||
{
|
||||
for (size_t i = 0; i < paramNames.size(); ++i)
|
||||
if (paramNames[i] == name)
|
||||
return sliders[i].get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void paint(juce::Graphics& g) override
|
||||
{
|
||||
g.fillAll(juce::Colours::darkgrey);
|
||||
@@ -89,9 +163,22 @@ private:
|
||||
// --- Top bar (manual) ----------------------------------------------
|
||||
auto area = getLocalBounds().reduced(10);
|
||||
auto top = area.removeFromTop(22);
|
||||
auto btnW = 46;
|
||||
bypassButton.setBounds(top.removeFromRight(btnW).reduced(2, 1));
|
||||
titleLabel.setBounds(top);
|
||||
if (hasBypass)
|
||||
{
|
||||
auto btnW = 46;
|
||||
auto buttonArea = top.removeFromRight(btnW);
|
||||
bypassButton.setBounds(buttonArea.reduced(2, 1));
|
||||
}
|
||||
|
||||
if (topBarAccessory != nullptr)
|
||||
{
|
||||
const int widthLimit = juce::jmax(60, juce::jmin(accessoryPreferredWidth, top.getWidth()));
|
||||
auto accessoryArea = top.removeFromRight(widthLimit);
|
||||
topBarAccessory->setBounds(accessoryArea.reduced(2, 1));
|
||||
}
|
||||
|
||||
if (titleLabel.isVisible())
|
||||
titleLabel.setBounds(top);
|
||||
|
||||
// --- Rest (grid) ----------------------------------------------------
|
||||
juce::Grid grid;
|
||||
@@ -146,9 +233,14 @@ private:
|
||||
std::vector<std::unique_ptr<juce::Slider>> sliders;
|
||||
std::vector<std::unique_ptr<juce::Label>> labels;
|
||||
std::vector<std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>> attachments;
|
||||
std::vector<std::string> paramNames;
|
||||
|
||||
juce::Component* topBarAccessory{ nullptr };
|
||||
int accessoryPreferredWidth{ 120 };
|
||||
|
||||
juce::ToggleButton bypassButton;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::ButtonAttachment> bypassAttachment;
|
||||
bool hasBypass{ false };
|
||||
|
||||
juce::Label titleLabel;
|
||||
|
||||
@@ -254,34 +346,6 @@ private:
|
||||
juce::Label titleLabel;
|
||||
};
|
||||
|
||||
//============================== Waveform List Model ===========================
|
||||
struct WaveformSelectorContents final : public juce::ListBoxModel
|
||||
{
|
||||
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));
|
||||
|
||||
juce::Font f; f.setHeight((float)height * 0.7f);
|
||||
g.setFont(f);
|
||||
g.drawText(waves[(size_t)rowNumber], 5, 0, width, height,
|
||||
juce::Justification::centredLeft, true);
|
||||
}
|
||||
|
||||
void selectedRowsChanged (int lastRowSelected) override
|
||||
{
|
||||
if (onSelect) onSelect(lastRowSelected);
|
||||
}
|
||||
|
||||
std::function<void (int)> onSelect;
|
||||
|
||||
std::vector<juce::String> waves { "Sine", "Saw", "Square", "Triangle" };
|
||||
};
|
||||
|
||||
//============================== MasterVolumeComponent =========================
|
||||
class MasterVolumeComponent : public juce::Component
|
||||
{
|
||||
@@ -290,6 +354,7 @@ public:
|
||||
{
|
||||
slider.setSliderStyle(juce::Slider::LinearBarVertical);
|
||||
slider.setTextBoxStyle(juce::Slider::NoTextBox, false, 20, 20);
|
||||
slider.setRange(-24.0f, 24.0f, 0.1f);
|
||||
addAndMakeVisible(slider);
|
||||
}
|
||||
|
||||
@@ -302,7 +367,8 @@ public:
|
||||
};
|
||||
|
||||
//============================== Editor =======================================
|
||||
class NeuralSynthAudioProcessorEditor : public juce::AudioProcessorEditor
|
||||
class NeuralSynthAudioProcessorEditor : public juce::AudioProcessorEditor,
|
||||
private juce::Timer
|
||||
{
|
||||
public:
|
||||
NeuralSynthAudioProcessorEditor (NeuralSynthAudioProcessor&);
|
||||
@@ -310,13 +376,18 @@ public:
|
||||
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
void timerCallback() override;
|
||||
|
||||
private:
|
||||
NeuralSynthAudioProcessor& audioProcessor;
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NeuralSynthAudioProcessorEditor)
|
||||
|
||||
juce::ListBox waveformSelector;
|
||||
WaveformSelectorContents waveformContents;
|
||||
void updatePresetButtonLabel();
|
||||
void showPresetMenu();
|
||||
void handleLayerSelectionChanged();
|
||||
|
||||
juce::TextButton presetMenuButton;
|
||||
int lastPresetIndex { -1 };
|
||||
|
||||
std::optional<ScopeSliderComponent> adsrComponent; // Amp Env
|
||||
std::optional<ScopeSliderComponent> chorusComponent;
|
||||
@@ -327,6 +398,7 @@ private:
|
||||
std::optional<ScopeSliderComponent> distortionComponent;
|
||||
std::optional<ScopeSliderComponent> filterComponent;
|
||||
std::optional<ScopeSliderComponent> filterEnvComponent; // Filter Env panel
|
||||
std::optional<ScopeSliderComponent> wtComponent; // Wavetable panel
|
||||
|
||||
MasterVolumeComponent masterLevelSlider;
|
||||
juce::Label masterLevelLabel;
|
||||
@@ -336,6 +408,6 @@ private:
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> gainAttachment;
|
||||
|
||||
ScopeComponent<float> mainScopeComponent;
|
||||
|
||||
juce::Component blankPanel;
|
||||
juce::ComboBox layerSelector;
|
||||
bool controllingLayerB { false };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user