Add LFO start and end parameters and change slider range to slider settings cog

new-features-1
James H Ball 2025-02-15 15:35:38 +00:00
rodzic 274430deb8
commit 90e30ba52a
5 zmienionych plików z 99 dodań i 18 usunięć

Wyświetl plik

@ -396,7 +396,7 @@ void OscirenderLookAndFeel::drawCallOutBoxBackground(juce::CallOutBox& box, juce
g.setColour(juce::Colours::black);
g.drawImageAt(cachedImage, 0, 0);
g.setColour(Colours::dark);
g.setColour(Colours::darker);
g.fillPath(path);
g.setColour(juce::Colours::black);

Wyświetl plik

@ -36,10 +36,16 @@ void Effect::animateValues(double volume) {
auto parameter = parameters[i];
float minValue = parameter->min;
float maxValue = parameter->max;
bool lfoEnabled = parameter->lfo != nullptr && parameter->lfo->getValueUnnormalised() != (int)LfoType::Static;
bool lfoEnabled = parameter->isLfoEnabled() && parameter->lfo->getValueUnnormalised() != (int)LfoType::Static;
float phase = lfoEnabled ? nextPhase(parameter) : 0.0;
float percentage = phase / (2 * std::numbers::pi);
LfoType type = lfoEnabled ? (LfoType)(int)parameter->lfo->getValueUnnormalised() : LfoType::Static;
if (lfoEnabled) {
double originalMin = minValue;
minValue = originalMin + (parameter->lfoStartPercent->getValueUnnormalised() / 100.0) * (maxValue - originalMin);
maxValue = originalMin + (parameter->lfoEndPercent->getValueUnnormalised() / 100.0) * (maxValue - originalMin);
}
switch (type) {
case LfoType::Sine:

Wyświetl plik

@ -337,6 +337,8 @@ public:
std::atomic<double> smoothValueChange = SMOOTHING_SPEED_CONSTANT;
LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", paramID + "Lfo", getVersionHint(), 1);
FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", paramID + "LfoRate", getVersionHint(), 1.0f, 0.0f, 10000.0f, 0.001f, "Hz");
FloatParameter* lfoStartPercent = new FloatParameter(name + " LFO Start", paramID + "LfoStart", getVersionHint(), 0.0f, 0.0f, 100.0f, 0.0001f, "%");
FloatParameter* lfoEndPercent = new FloatParameter(name + " LFO End", paramID + "LfoEnd", getVersionHint(), 100.0f, 0.0f, 100.0f, 0.0001f, "%");
BooleanParameter* sidechain = new BooleanParameter(name + " Sidechain Enabled", paramID + "Sidechain", getVersionHint(), false, "Toggles " + name + " Sidechain.");
std::atomic<float> phase = 0.0f;
juce::String description;
@ -350,6 +352,12 @@ public:
if (lfoRate != nullptr) {
parameters.push_back(lfoRate);
}
if (lfoStartPercent != nullptr) {
parameters.push_back(lfoStartPercent);
}
if (lfoEndPercent != nullptr) {
parameters.push_back(lfoEndPercent);
}
if (sidechain != nullptr) {
parameters.push_back(sidechain);
}
@ -357,10 +365,15 @@ public:
}
void disableLfo() {
lfoEnabled = false;
delete lfo;
delete lfoRate;
delete lfoStartPercent;
delete lfoEndPercent;
lfo = nullptr;
lfoRate = nullptr;
lfoStartPercent = nullptr;
lfoEndPercent = nullptr;
}
void disableSidechain() {
@ -371,10 +384,14 @@ public:
void save(juce::XmlElement* xml) {
FloatParameter::save(xml);
if (lfo != nullptr && lfoRate != nullptr) {
if (lfoEnabled) {
auto lfoXml = xml->createNewChildElement("lfo");
lfo->save(lfoXml);
lfoRate->save(lfoXml);
auto lfoStartXml = xml->createNewChildElement("lfoStart");
lfoStartPercent->save(lfoStartXml);
auto lfoEndXml = xml->createNewChildElement("lfoEnd");
lfoEndPercent->save(lfoEndXml);
}
if (sidechain != nullptr) {
@ -386,7 +403,7 @@ public:
void load(juce::XmlElement* xml) {
FloatParameter::load(xml);
if (lfo != nullptr && lfoRate != nullptr) {
if (lfoEnabled) {
auto lfoXml = xml->getChildByName("lfo");
if (lfoXml != nullptr) {
lfo->load(lfoXml);
@ -395,6 +412,20 @@ public:
lfo->setValueNotifyingHost(lfo->getValueForText("Static"));
lfoRate->setUnnormalisedValueNotifyingHost(1.0f);
}
auto lfoStartXml = xml->getChildByName("lfoStart");
if (lfoStartXml != nullptr) {
lfoStartPercent->load(lfoStartXml);
} else {
lfoStartPercent->setUnnormalisedValueNotifyingHost(0.0f);
}
auto lfoEndXml = xml->getChildByName("lfoEnd");
if (lfoEndXml != nullptr) {
lfoEndPercent->load(lfoEndXml);
} else {
lfoEndPercent->setUnnormalisedValueNotifyingHost(100.0f);
}
}
if (sidechain != nullptr) {
@ -406,6 +437,13 @@ public:
}
}
}
bool isLfoEnabled() {
return lfoEnabled;
}
EffectParameter(juce::String name, juce::String description, juce::String id, int versionHint, float value, float min, float max, float step = 0.0001, double smoothValueChange = SMOOTHING_SPEED_CONSTANT) : FloatParameter(name, id, versionHint, value, min, max, step), smoothValueChange(smoothValueChange), description(description) {}
private:
bool lfoEnabled = true;
};

Wyświetl plik

@ -6,7 +6,7 @@ EffectComponent::EffectComponent(Effect& effect, int index) : effect(effect), in
addChildComponent(lfoSlider);
addAndMakeVisible(lfo);
addAndMakeVisible(label);
addAndMakeVisible(rangeButton);
addAndMakeVisible(settingsButton);
sidechainEnabled = effect.parameters[index]->sidechain != nullptr;
if (sidechainEnabled) {
@ -40,12 +40,13 @@ EffectComponent::EffectComponent(Effect& effect, int index) : effect(effect), in
lfo.addItem("Reverse Sawtooth", static_cast<int>(LfoType::ReverseSawtooth));
lfo.addItem("Noise", static_cast<int>(LfoType::Noise));
rangeButton.setTooltip("Click to change the range of the slider.");
settingsButton.setTooltip("Click to change the slider settings, including range.");
rangeButton.onClick = [this] {
auto range = std::make_unique<EffectRangeComponent>(this);
range->setSize(200, 110);
auto& myBox = juce::CallOutBox::launchAsynchronously(std::move(range), rangeButton.getScreenBounds(), nullptr);
settingsButton.onClick = [this] {
auto settings = std::make_unique<EffectSettingsComponent>(this);
settings->setLookAndFeel(&getLookAndFeel());
settings->setSize(200, 220);
auto& myBox = juce::CallOutBox::launchAsynchronously(std::move(settings), settingsButton.getScreenBounds(), nullptr);
};
effect.addListener(index, this);
@ -152,6 +153,10 @@ void EffectComponent::resized() {
if (sidechainEnabled) {
sidechainButton->setBounds(bounds.removeFromRight(20));
}
if (settingsButton.isVisible()) {
settingsButton.setBounds(bounds.removeFromRight(20));
}
bool drawingSmall = bounds.getWidth() < 3.5 * TEXT_WIDTH;
@ -159,10 +164,8 @@ void EffectComponent::resized() {
lfo.setBounds(bounds.removeFromRight(drawingSmall ? 70 : 100).reduced(0, 5));
}
if (rangeButton.isVisible()) {
rangeButton.setBounds(bounds.removeFromRight(20));
}
bounds.removeFromRight(2);
bounds.removeFromLeft(5);
label.setBounds(bounds.removeFromLeft(drawingSmall ? SMALL_TEXT_WIDTH : TEXT_WIDTH));
@ -198,7 +201,7 @@ void EffectComponent::handleAsyncUpdate() {
}
void EffectComponent::setRangeEnabled(bool enabled) {
rangeButton.setVisible(enabled);
settingsButton.setVisible(enabled);
}
void EffectComponent::setComponent(std::shared_ptr<juce::Component> component) {

Wyświetl plik

@ -27,12 +27,16 @@ public:
int index = 0;
juce::ComboBox lfo;
class EffectRangeComponent : public juce::Component {
class EffectSettingsComponent : public juce::Component {
public:
EffectRangeComponent(EffectComponent* parent) {
EffectSettingsComponent(EffectComponent* parent) {
addAndMakeVisible(popupLabel);
addAndMakeVisible(min);
addAndMakeVisible(max);
addAndMakeVisible(lfoStartLabel);
addAndMakeVisible(lfoEndLabel);
addAndMakeVisible(lfoStartSlider);
addAndMakeVisible(lfoEndSlider);
EffectParameter* parameter = parent->effect.parameters[parent->index];
@ -61,6 +65,28 @@ public:
parent->slider.setRange(parameter->min, parameter->max, parameter->step);
};
lfoStartLabel.setText("LFO Start", juce::dontSendNotification);
lfoStartLabel.setJustificationType(juce::Justification::centred);
lfoStartLabel.setFont(juce::Font(14.0f, juce::Font::bold));
lfoEndLabel.setText("LFO End", juce::dontSendNotification);
lfoEndLabel.setJustificationType(juce::Justification::centred);
lfoEndLabel.setFont(juce::Font(14.0f, juce::Font::bold));
lfoStartSlider.setRange(parameter->lfoStartPercent->min, parameter->lfoStartPercent->max, parameter->lfoStartPercent->step);
lfoStartSlider.setValue(parameter->lfoStartPercent->getValueUnnormalised(), juce::dontSendNotification);
lfoStartSlider.setTextValueSuffix("%");
lfoStartSlider.onValueChange = [this, parameter]() {
parameter->lfoStartPercent->setUnnormalisedValueNotifyingHost(lfoStartSlider.getValue());
};
lfoEndSlider.setRange(parameter->lfoEndPercent->min, parameter->lfoEndPercent->max, parameter->lfoEndPercent->step);
lfoEndSlider.setValue(parameter->lfoEndPercent->getValueUnnormalised(), juce::dontSendNotification);
lfoEndSlider.setTextValueSuffix("%");
lfoEndSlider.onValueChange = [this, parameter]() {
parameter->lfoEndPercent->setUnnormalisedValueNotifyingHost(lfoEndSlider.getValue());
};
popupLabel.setText(parameter->name + " Range", juce::dontSendNotification);
popupLabel.setJustificationType(juce::Justification::centred);
popupLabel.setFont(juce::Font(14.0f, juce::Font::bold));
@ -71,12 +97,20 @@ public:
popupLabel.setBounds(bounds.removeFromTop(30));
min.setBounds(bounds.removeFromTop(40));
max.setBounds(bounds.removeFromTop(40));
lfoStartLabel.setBounds(bounds.removeFromTop(20));
lfoStartSlider.setBounds(bounds.removeFromTop(40));
lfoEndLabel.setBounds(bounds.removeFromTop(20));
lfoEndSlider.setBounds(bounds.removeFromTop(40));
}
private:
juce::Label popupLabel;
LabelledTextBox min{"Min"};
LabelledTextBox max{"Max"};
juce::Label lfoStartLabel;
juce::Label lfoEndLabel;
juce::Slider lfoStartSlider;
juce::Slider lfoEndSlider;
};
std::function<void()> updateToggleState;
@ -98,7 +132,7 @@ private:
juce::Label label;
SvgButton rangeButton = { "rangeButton", BinaryData::range_svg, juce::Colours::white };
SvgButton settingsButton = { "settingsButton", BinaryData::cog_svg, juce::Colours::white };
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EffectComponent)
};