diff --git a/Resources/svg/random.svg b/Resources/svg/random.svg index d69aa6d..c673a2f 100644 --- a/Resources/svg/random.svg +++ b/Resources/svg/random.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Source/EffectsComponent.cpp b/Source/EffectsComponent.cpp index d0dcd0c..de565dc 100644 --- a/Source/EffectsComponent.cpp +++ b/Source/EffectsComponent.cpp @@ -23,6 +23,13 @@ EffectsComponent::EffectsComponent(OscirenderAudioProcessor& p, OscirenderAudioP }; addAndMakeVisible(addBtn);*/ + addAndMakeVisible(randomiseButton); + + randomiseButton.onClick = [this] { + itemData.randomise(); + listBox.updateContent(); + }; + { juce::MessageManagerLock lock; audioProcessor.broadcaster.addChangeListener(this); @@ -38,7 +45,10 @@ EffectsComponent::~EffectsComponent() { } void EffectsComponent::resized() { - auto area = getLocalBounds().withTrimmedTop(20).reduced(20); + auto area = getLocalBounds(); + auto titleBar = area.removeFromTop(20); + randomiseButton.setBounds(titleBar.removeFromRight(20)); + area = area.reduced(20); frequency.setBounds(area.removeFromTop(30)); area.removeFromTop(6); diff --git a/Source/EffectsComponent.h b/Source/EffectsComponent.h index 986bad4..071ee7c 100644 --- a/Source/EffectsComponent.h +++ b/Source/EffectsComponent.h @@ -1,6 +1,7 @@ #pragma once #include +#include "LookAndFeel.h" #include "audio/BitCrushEffect.h" #include "PluginProcessor.h" #include "components/DraggableListBox.h" @@ -20,6 +21,8 @@ private: // juce::TextButton addBtn; + SvgButton randomiseButton{ "randomise", juce::String(BinaryData::random_svg), Colours::accentColor }; + AudioEffectListBoxItemData itemData; EffectsListBoxModel listBoxModel; DraggableListBox listBox; diff --git a/Source/audio/WobbleEffect.cpp b/Source/audio/WobbleEffect.cpp index c89ac40..f7619d6 100644 --- a/Source/audio/WobbleEffect.cpp +++ b/Source/audio/WobbleEffect.cpp @@ -8,7 +8,7 @@ Point WobbleEffect::apply(int index, Point input, const std::vector& val // TODO: this doesn't consider sample rate smoothedFrequency = smoothedFrequency * 0.99995 + pitchDetector.frequency * 0.00005; double theta = nextPhase(smoothedFrequency, sampleRate); - double delta = values[0] * std::sin(theta); + double delta = 0.5 * values[0] * std::sin(theta); return input + delta; } diff --git a/Source/components/EffectsListComponent.h b/Source/components/EffectsListComponent.h index 8b1e202..78feebd 100644 --- a/Source/components/EffectsListComponent.h +++ b/Source/components/EffectsListComponent.h @@ -5,6 +5,7 @@ #include "../audio/Effect.h" #include "EffectComponent.h" #include "ComponentList.h" +#include // Application-specific data container class OscirenderAudioProcessorEditor; @@ -18,6 +19,43 @@ struct AudioEffectListBoxItemData : public DraggableListBoxItemData resetData(); } + void randomise() { + juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock); + for (int i = 0; i < data.size(); i++) { + auto effect = data[i]; + auto id = effect->getId(); + + if (id.contains("scale") || id.contains("translate")) { + continue; + } + + for (auto& parameter : effect->parameters) { + parameter->setValueNotifyingHost(juce::Random::getSystemRandom().nextFloat()); + if (parameter->lfo != nullptr) { + parameter->lfo->setUnnormalisedValueNotifyingHost((int) LfoType::Static); + parameter->lfoRate->setUnnormalisedValueNotifyingHost(1); + + if (juce::Random::getSystemRandom().nextFloat() > 0.8) { + parameter->lfo->setUnnormalisedValueNotifyingHost((int)(juce::Random::getSystemRandom().nextFloat() * (int)LfoType::Noise)); + parameter->lfoRate->setValueNotifyingHost(juce::Random::getSystemRandom().nextFloat() * 0.1); + } + } + } + effect->enabled->setValueNotifyingHost(juce::Random::getSystemRandom().nextFloat() > 0.8); + } + + // shuffle precedence + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(data.begin(), data.end(), g); + + for (int i = 0; i < data.size(); i++) { + data[i]->setPrecedence(i); + } + + audioProcessor.updateEffectPrecedence(); + } + void resetData() { juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock); data.clear();