Parameters are now controllable from DAW

pull/170/head
James Ball 2023-07-17 20:09:13 +01:00
rodzic 707715bc2e
commit de3ab79052
5 zmienionych plików z 58 dodań i 16 usunięć

Wyświetl plik

@ -86,6 +86,16 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
for (int i = 0; i < 5; i++) {
addLuaSlider();
}
auto effects = allEffects;
effects.insert(effects.end(), permanentEffects.begin(), permanentEffects.end());
effects.insert(effects.end(), luaEffects.begin(), luaEffects.end());
for (auto effect : effects) {
for (auto& parameter : effect->parameters) {
addParameter(&parameter);
}
}
}
OscirenderAudioProcessor::~OscirenderAudioProcessor() {}

Wyświetl plik

@ -15,7 +15,7 @@ Effect::Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, d
Vector2 Effect::apply(int index, Vector2 input) {
for (int i = 0; i < parameters.size(); i++) {
double weight = parameters[i].smoothValueChange ? 0.0005 : 1.0;
smoothValues[i] = (1.0 - weight) * smoothValues[i] + weight * parameters[i].value;
smoothValues[i] = (1.0 - weight) * smoothValues[i] + weight * parameters[i].getValueUnnormalised();
}
if (application) {
return application(index, input, smoothValues, sampleRate);
@ -30,7 +30,7 @@ void Effect::apply() {
}
double Effect::getValue(int index) {
return parameters[index].value;
return parameters[index].getValueUnnormalised();
}
double Effect::getValue() {
@ -38,7 +38,7 @@ double Effect::getValue() {
}
void Effect::setValue(int index, double value) {
parameters[index].value = value;
parameters[index].setUnnormalisedValueNotifyingHost(value);
}
void Effect::setValue(double value) {

Wyświetl plik

@ -6,14 +6,13 @@ class EffectParameter : public juce::AudioProcessorParameter {
public:
juce::String name;
juce::String id;
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
std::atomic<double> value = 0.0;
std::atomic<double> min = 0.0;
std::atomic<double> max = 1.0;
std::atomic<double> step = 0.001;
std::atomic<float> min = 0.0;
std::atomic<float> max = 1.0;
std::atomic<float> step = 0.001;
std::atomic<bool> smoothValueChange = true;
EffectParameter(juce::String name, juce::String id, double value, double min, double max, double step = 0.001, bool smoothValueChange = true) : name(name), id(id), value(value), min(min), max(max), step(step), smoothValueChange(smoothValueChange) {}
EffectParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, bool smoothValueChange = true) : name(name), id(id), value(value), min(min), max(max), step(step), smoothValueChange(smoothValueChange) {}
// COPY CONSTRUCTOR SHOULD ONLY BE USED BEFORE
// THE OBJECT IS USED IN MULTIPLE THREADS
@ -34,13 +33,42 @@ public:
juce::String getLabel() const override {
return juce::String();
}
// returns value in range [0, 1]
float getNormalisedValue(float value) const {
// clip value to valid range
auto min = this->min.load();
auto max = this->max.load();
value = juce::jlimit(min, max, value);
// normalize value to range [0, 1]
return (value - min) / (max - min);
}
float getUnnormalisedValue(float value) const {
value = juce::jlimit(0.0f, 1.0f, value);
auto min = this->min.load();
auto max = this->max.load();
return min + value * (max - min);
}
float getValue() const override {
return value.load();
return getNormalisedValue(value.load());
}
float getValueUnnormalised() const {
return value.load();
}
void setValue(float newValue) override {
value.store(newValue);
value = getUnnormalisedValue(newValue);
}
void setValueUnnormalised(float newValue) {
value = newValue;
}
void setUnnormalisedValueNotifyingHost(float newValue) {
setValueNotifyingHost(getNormalisedValue(newValue));
}
float getDefaultValue() const override {
@ -64,12 +92,12 @@ public:
}
juce::String getText(float value, int maximumStringLength) const override {
auto string = juce::String(value, 3);
auto string = juce::String(getUnnormalisedValue(value), 3);
return string.substring(0, maximumStringLength);
}
float getValueForText(const juce::String& text) const override {
return text.getFloatValue();
return getNormalisedValue(text.getFloatValue());
}
bool isAutomatable() const override {
@ -83,6 +111,10 @@ public:
juce::AudioProcessorParameter::Category getCategory() const override {
return juce::AudioProcessorParameter::genericParameter;
}
private:
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
std::atomic<float> value = 0.0;
};
class EffectApplication {

Wyświetl plik

@ -18,10 +18,10 @@ void EffectComponent::componentSetup() {
addAndMakeVisible(slider);
addAndMakeVisible(selected);
EffectParameter parameter = effect.parameters[index];
EffectParameter& parameter = effect.parameters[index];
slider.setRange(parameter.min, parameter.max, parameter.step);
slider.setValue(parameter.value, juce::dontSendNotification);
slider.setValue(parameter.getValueUnnormalised(), juce::dontSendNotification);
slider.setSliderStyle(juce::Slider::LinearHorizontal);
slider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 90, slider.getTextBoxHeight());

Wyświetl plik

@ -6,7 +6,7 @@ EffectsListComponent::EffectsListComponent(DraggableListBox& lb, AudioEffectList
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(*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].value, juce::dontSendNotification);
effectComponent->slider.setValue(parameters[i].getValueUnnormalised(), juce::dontSendNotification);
effectComponent->slider.onValueChange = [this, i, weakEffectComponent] {
if (auto effectComponent = weakEffectComponent.lock()) {
this->effect->setValue(i, effectComponent->slider.getValue());