Remove LFO support for Lua and remove 'infinite' lua sliders as you cannot dynamically add parameters

pull/170/head
James Ball 2023-07-21 11:08:55 +01:00
rodzic 4520771b15
commit 34adbc767d
11 zmienionych plików z 87 dodań i 68 usunięć

Wyświetl plik

@ -23,7 +23,7 @@ private:
EffectsListBoxModel listBoxModel;
DraggableListBox listBox;
EffectComponent frequency = EffectComponent(*audioProcessor.frequencyEffect, false);
EffectComponent frequency = EffectComponent(audioProcessor, *audioProcessor.frequencyEffect, false);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EffectsComponent)
};

Wyświetl plik

@ -17,11 +17,11 @@ private:
OscirenderAudioProcessor& audioProcessor;
OscirenderAudioProcessorEditor& pluginEditor;
EffectComponent focalLength{*audioProcessor.focalLength, false};
EffectComponent rotateX{*audioProcessor.rotateX, false};
EffectComponent rotateY{*audioProcessor.rotateY, false};
EffectComponent rotateZ{*audioProcessor.rotateZ, false};
EffectComponent rotateSpeed{*audioProcessor.rotateSpeed, false};
EffectComponent focalLength{audioProcessor, *audioProcessor.focalLength, false};
EffectComponent rotateX{audioProcessor, *audioProcessor.rotateX, false};
EffectComponent rotateY{audioProcessor, *audioProcessor.rotateY, false};
EffectComponent rotateZ{audioProcessor, *audioProcessor.rotateZ, false};
EffectComponent rotateSpeed{audioProcessor, *audioProcessor.rotateSpeed, false};
juce::TextButton resetRotation{"Reset Rotation"};
juce::ToggleButton mouseRotate{"Rotate with Mouse (Esc to disable)"};

Wyświetl plik

@ -97,7 +97,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
permanentEffects.push_back(rotateZ);
permanentEffects.push_back(focalLength);
for (int i = 0; i < 5; i++) {
for (int i = 0; i < 26; i++) {
addLuaSlider();
}
@ -218,6 +218,9 @@ void OscirenderAudioProcessor::addLuaSlider() {
std::make_shared<LuaEffect>(sliderName, *this),
new EffectParameter("Lua " + sliderName, "lua" + sliderName, 0.0, 0.0, 1.0, 0.001, false)
));
auto& effect = luaEffects.back();
effect->parameters[0]->disableLfo();
}
// effectsLock should be held when calling this

Wyświetl plik

@ -162,7 +162,7 @@ public:
obj->setRotationSpeed(values[0]);
}
return input;
}, new EffectParameter("Rotate Speed", "rotateSpeed", 0.0, -1.0, 1.0)
}, new EffectParameter("Rotate Speed", "rotateSpeed3D", 0.0, -1.0, 1.0)
);
std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>();

Wyświetl plik

@ -28,10 +28,11 @@ void Effect::animateValues() {
auto parameter = parameters[i];
float minValue = parameter->min;
float maxValue = parameter->max;
float phase = nextPhase(parameter);
float phase = parameter->lfo != nullptr ? nextPhase(parameter) : 0.0;
float percentage = phase / (2 * std::numbers::pi);
LfoType type = parameter->lfo != nullptr ? (LfoType)(int)parameter->lfo->getValueUnnormalised() : LfoType::Static;
switch ((LfoType)(int) parameter->lfo->getValueUnnormalised()) {
switch (type) {
case LfoType::Sine:
actualValues[i] = std::sin(phase) * 0.5 + 0.5;
actualValues[i] = actualValues[i] * (maxValue - minValue) + minValue;
@ -56,11 +57,8 @@ void Effect::animateValues() {
actualValues[i] = (1 - percentage) * (maxValue - minValue) + minValue;
break;
case LfoType::Noise:
{
float noise = (float)rand() / RAND_MAX;
actualValues[i] = noise * (maxValue - minValue) + minValue;
actualValues[i] = ((float)rand() / RAND_MAX) * (maxValue - minValue) + minValue;
break;
}
default:
double weight = parameter->smoothValueChange ? 0.0005 : 1.0;
actualValues[i] = (1.0 - weight) * actualValues[i] + weight * parameter->getValueUnnormalised();
@ -110,8 +108,12 @@ void Effect::setPrecedence(int precedence) {
void Effect::addListener(int index, juce::AudioProcessorParameter::Listener* listener) {
parameters[index]->addListener(listener);
parameters[index]->lfo->addListener(listener);
parameters[index]->lfoRate->addListener(listener);
if (parameters[index]->lfo != nullptr) {
parameters[index]->lfo->addListener(listener);
}
if (parameters[index]->lfoRate != nullptr) {
parameters[index]->lfoRate->addListener(listener);
}
if (enabled != nullptr) {
enabled->addListener(listener);
}
@ -121,8 +123,12 @@ void Effect::removeListener(int index, juce::AudioProcessorParameter::Listener*
if (enabled != nullptr) {
enabled->removeListener(listener);
}
parameters[index]->lfoRate->removeListener(listener);
parameters[index]->lfo->removeListener(listener);
if (parameters[index]->lfoRate != nullptr) {
parameters[index]->lfoRate->removeListener(listener);
}
if (parameters[index]->lfo != nullptr) {
parameters[index]->lfo->removeListener(listener);
}
parameters[index]->removeListener(listener);
}
@ -135,7 +141,7 @@ void Effect::markEnableable(bool enable) {
}
juce::String Effect::getId() {
return parameters[0]->id;
return parameters[0]->paramID;
}
juce::String Effect::getName() {

Wyświetl plik

@ -2,16 +2,13 @@
#include "../shape/Vector2.h"
#include <JuceHeader.h>
class FloatParameter : public juce::AudioProcessorParameter {
class FloatParameter : public juce::AudioProcessorParameterWithID {
public:
juce::String name;
juce::String id;
std::atomic<float> min = 0.0;
std::atomic<float> max = 1.0;
std::atomic<float> step = 0.001;
FloatParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, juce::String label = "") : name(name), id(id), value(value), min(min), max(max), step(step), label(label) {}
FloatParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, juce::String label = "") : juce::AudioProcessorParameterWithID(id, name), value(value), min(min), max(max), step(step), label(label) {}
juce::String getName(int maximumStringLength) const override {
return name.substring(0, maximumStringLength);
@ -105,15 +102,12 @@ private:
juce::String label;
};
class IntParameter : public juce::AudioProcessorParameter {
class IntParameter : public juce::AudioProcessorParameterWithID {
public:
juce::String name;
juce::String id;
std::atomic<int> min = 0;
std::atomic<int> max = 10;
IntParameter(juce::String name, juce::String id, int value, int min, int max) : name(name), id(id), value(value), min(min), max(max) {}
IntParameter(juce::String name, juce::String id, int value, int min, int max) : AudioProcessorParameterWithID(name, id), value(value), min(min), max(max) {}
juce::String getName(int maximumStringLength) const override {
return name.substring(0, maximumStringLength);
@ -270,13 +264,28 @@ public:
class EffectParameter : public FloatParameter {
public:
std::atomic<bool> smoothValueChange = true;
LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", id + "Lfo", 1);
FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", id + "LfoRate", 1.0f, 0.0f, 100.0f, 0.1f, "Hz");
LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", paramID + "Lfo", 1);
FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", paramID + "LfoRate", 1.0f, 0.0f, 100.0f, 0.1f, "Hz");
std::atomic<float> phase = 0.0f;
std::vector<juce::AudioProcessorParameter*> getParameters() {
return { this, lfo, lfoRate };
std::vector<juce::AudioProcessorParameter*> parameters;
parameters.push_back(this);
if (lfo != nullptr) {
parameters.push_back(lfo);
}
if (lfoRate != nullptr) {
parameters.push_back(lfoRate);
}
return parameters;
}
void disableLfo() {
delete lfo;
delete lfoRate;
lfo = nullptr;
lfoRate = nullptr;
}
EffectParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, bool smoothValueChange = true) : FloatParameter(name, id, value, min, max, step), smoothValueChange(smoothValueChange) {}
};

Wyświetl plik

@ -1,6 +1,6 @@
#include "EffectComponent.h"
EffectComponent::EffectComponent(Effect& effect, int index) : effect(effect), index(index) {
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index) : effect(effect), index(index), audioProcessor(p) {
addAndMakeVisible(slider);
addAndMakeVisible(selected);
addAndMakeVisible(lfo);
@ -20,13 +20,13 @@ EffectComponent::EffectComponent(Effect& effect, int index) : effect(effect), in
setupComponent();
}
EffectComponent::EffectComponent(Effect& effect, int index, bool checkboxVisible) : EffectComponent(effect, index) {
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index, bool checkboxVisible) : EffectComponent(p, effect, index) {
setCheckboxVisible(checkboxVisible);
}
EffectComponent::EffectComponent(Effect& effect) : EffectComponent(effect, 0) {}
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect) : EffectComponent(p, effect, 0) {}
EffectComponent::EffectComponent(Effect& effect, bool checkboxVisible) : EffectComponent(effect) {
EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, bool checkboxVisible) : EffectComponent(p, effect) {
setCheckboxVisible(checkboxVisible);
}
@ -42,14 +42,17 @@ void EffectComponent::setupComponent() {
bool enabled = effect.enabled == nullptr || effect.enabled->getValue();
selected.setToggleState(enabled, juce::dontSendNotification);
lfo.setSelectedId(parameter->lfo->getValueUnnormalised(), juce::dontSendNotification);
lfo.onChange = [this]() {
if (lfo.getSelectedId() != 0) {
effect.parameters[index]->lfo->setUnnormalisedValueNotifyingHost(lfo.getSelectedId());
}
};
lfoEnabled = parameter->lfo != nullptr && parameter->lfoRate != nullptr;
if (lfoEnabled) {
lfo.setSelectedId(parameter->lfo->getValueUnnormalised(), juce::dontSendNotification);
lfo.onChange = [this]() {
if (lfo.getSelectedId() != 0) {
effect.parameters[index]->lfo->setUnnormalisedValueNotifyingHost(lfo.getSelectedId());
}
};
}
min.textBox.setValue(parameter->min, juce::dontSendNotification);
max.textBox.setValue(parameter->max, juce::dontSendNotification);
@ -92,7 +95,9 @@ void EffectComponent::resized() {
component->setBounds(componentBounds);
}
lfo.setBounds(bounds.removeFromRight(100).reduced(5));
if (lfoEnabled) {
lfo.setBounds(bounds.removeFromRight(100).reduced(5));
}
auto checkboxLabel = bounds.removeFromLeft(110);
@ -132,6 +137,11 @@ void EffectComponent::parameterGestureChanged(int parameterIndex, bool gestureIs
void EffectComponent::handleAsyncUpdate() {
setupComponent();
juce::SpinLock::ScopedLockType lock1(audioProcessor.parsersLock);
juce::SpinLock::ScopedLockType lock2(audioProcessor.effectsLock);
if (effect.getId().contains("lua")) {
effect.apply();
}
}
void EffectComponent::setComponent(std::shared_ptr<juce::Component> component) {

Wyświetl plik

@ -34,10 +34,10 @@ class SmallComboBoxArrow : public juce::LookAndFeel_V4 {
class EffectComponent : public juce::Component, public juce::AudioProcessorParameter::Listener, juce::AsyncUpdater {
public:
EffectComponent(Effect& effect, int index);
EffectComponent(Effect& effect, int index, bool checkboxVisible);
EffectComponent(Effect& effect);
EffectComponent(Effect& effect, bool checkboxVisible);
EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index);
EffectComponent(OscirenderAudioProcessor& p, Effect& effect, int index, bool checkboxVisible);
EffectComponent(OscirenderAudioProcessor& p, Effect& effect);
EffectComponent(OscirenderAudioProcessor& p, Effect& effect, bool checkboxVisible);
~EffectComponent();
void resized() override;
@ -60,8 +60,10 @@ public:
private:
void setupComponent();
bool checkboxVisible = true;
bool lfoEnabled = true;
juce::Rectangle<int> textBounds;
std::shared_ptr<juce::Component> component;
OscirenderAudioProcessor& audioProcessor;
juce::Label popupLabel;
LabelledTextBox min{"Min"};

Wyświetl plik

@ -3,7 +3,7 @@
EffectsListComponent::EffectsListComponent(DraggableListBox& lb, AudioEffectListBoxItemData& data, int rn, std::shared_ptr<Effect> effect) : DraggableListBoxItem(lb, data, rn), effect(effect) {
auto parameters = effect->parameters;
for (int i = 0; i < parameters.size(); i++) {
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(*effect, i, i == 0);
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(data.audioProcessor, *effect, i, i == 0);
// using weak_ptr to avoid circular reference and memory leak
std::weak_ptr<EffectComponent> weakEffectComponent = effectComponent;
effectComponent->slider.setValue(parameters[i]->getValueUnnormalised(), juce::dontSendNotification);

Wyświetl plik

@ -1,7 +1,7 @@
#include "LuaListComponent.h"
LuaListComponent::LuaListComponent(OscirenderAudioProcessor& p, Effect& effect) {
effectComponent = std::make_shared<EffectComponent>(effect);
effectComponent = std::make_shared<EffectComponent>(p, effect);
effectComponent->setCheckboxVisible(false);
effectComponent->slider.onValueChange = [this, &effect, &p] {
@ -21,27 +21,16 @@ void LuaListComponent::resized() {
void paintListBoxItem(int sliderNum, juce::Graphics& g, int width, int height, bool rowIsSelected) {}
int LuaListBoxModel::getNumRows() {
return audioProcessor.luaEffects.size() + 1;
return audioProcessor.luaEffects.size();
}
void LuaListBoxModel::paintListBoxItem(int rowNumber, juce::Graphics& g, int width, int height, bool rowIsSelected) {}
juce::Component* LuaListBoxModel::refreshComponentForRow(int rowNum, bool isRowSelected, juce::Component *existingComponentToUpdate) {
if (rowNum < getNumRows() - 1) {
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
std::unique_ptr<LuaListComponent> item(dynamic_cast<LuaListComponent*>(existingComponentToUpdate));
if (juce::isPositiveAndBelow(rowNum, getNumRows())) {
item = std::make_unique<LuaListComponent>(audioProcessor, *audioProcessor.luaEffects[rowNum]);
}
return item.release();
} else {
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
std::unique_ptr<juce::TextButton> item(dynamic_cast<juce::TextButton*>(existingComponentToUpdate));
item = std::make_unique<juce::TextButton>("+");
item->onClick = [this]() {
audioProcessor.addLuaSlider();
listBox.updateContent();
};
return item.release();
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
std::unique_ptr<LuaListComponent> item(dynamic_cast<LuaListComponent*>(existingComponentToUpdate));
if (juce::isPositiveAndBelow(rowNum, getNumRows())) {
item = std::make_unique<LuaListComponent>(audioProcessor, *audioProcessor.luaEffects[rowNum]);
}
return item.release();
}

Wyświetl plik

@ -28,7 +28,7 @@ public:
juce::Component* refreshComponentForRow(int sliderNum, bool isRowSelected, juce::Component *existingComponentToUpdate) override;
private:
int numSliders = 5;
int numSliders = 26;
juce::ListBox& listBox;
OscirenderAudioProcessor& audioProcessor;
};