kopia lustrzana https://github.com/jameshball/osci-render
Add LFO start and end parameters and change slider range to slider settings cog
rodzic
274430deb8
commit
90e30ba52a
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
Ładowanie…
Reference in New Issue