Skip to content

Commit

Permalink
Modulating modulators (#34)
Browse files Browse the repository at this point in the history
* work

* cp

* handle lfo seconds/tempo

* cp

* cp

* make column controls not crash on modulation

* cp

* cp

* introduce new inspector file (wip)

* cp

* cp

* rename box slider to blocks slider

* rename box slider to blocks slider

* work

* worky work

* work

* work

* worky work

* worky work

* work

* fix tempo for various models

* worky work

* worky work

* worky work

* work

* work

* add try catch to update button and comment out orbit effect

* try catch party

* thanks emma

* cleanup
  • Loading branch information
dan-german committed May 4, 2024
1 parent 9717708 commit cbdd1e1
Show file tree
Hide file tree
Showing 79 changed files with 1,545 additions and 859 deletions.
6 changes: 3 additions & 3 deletions Assets/plus.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions Assets/x.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
319 changes: 196 additions & 123 deletions Source/MainComponent.cpp

Large diffs are not rendered by default.

46 changes: 33 additions & 13 deletions Source/MainComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
#include "gui/column_controls_container.h"
#include "selection_rect.h"
#include "gui/controls/SavePopup.h"
#include "gui/slider_container.h"
#include "gui/modulation_state_manager.h"

namespace gui {
class MainComponent final: public Component,
InspectorComponent::Listener,
Slider::Listener,
Expand All @@ -30,13 +33,15 @@ class MainComponent final: public Component,
GridComponent::Listener,
NoteLogger::Listener,
ColumnControlsContainer::Listener,
BlocksSlider::Listener,
ModulationStateManager::Listener,
KeyListener {
public:
struct Delegate;
Delegate* delegate;
MainComponent(juce::MidiKeyboardState& keyboard_state, Delegate* delegate);
void setupColumnControls();
~MainComponent() override;
void mouseDrag(const MouseEvent& event) override;

BlocksLookAndFeel blocks_laf_;
UILayer ui_layer_;
Expand All @@ -50,20 +55,25 @@ class MainComponent final: public Component,
// MouseListener
void mouseDown(const MouseEvent& event) override;
void mouseUp(const MouseEvent& event) override;
void mouseDrag(const MouseEvent& event) override;

void handlePastePopup(const juce::MouseEvent& event);
bool keyPressed (const KeyPress& key, Component* originatingComponent) override;
bool keyPressed(const KeyPress& key, Component* originatingComponent) override;
private:
DarkBackground dark_background_;
DarkBackground grid_dark_background_;
BlockGridComponent block_grid_;
TabContainerComponent tab_grid_;
InspectorComponent inspector_;
SliderContainer inspector_v2_;
SavePopup save_popup_;
GraphicsTimer timer_;
ColumnControlsContainer column_controls_;
SelectionRect selection_rect_;
ModulationStateManager modulation_state_manager_;
std::vector<model::Block> copied_blocks_;
std::vector<GridItemComponent*> currently_selected_items_;
bool is_modulator_adjusting_ = false;
bool is_parameter_adjusting = false;

Array<BlockComponent*> blocks;
GridItemComponent* focused_grid_item_ = nullptr;
Expand All @@ -82,21 +92,27 @@ class MainComponent final: public Component,
ButtonGridPopup presets_popup_;
ButtonGridPopup copy_delete_popup_;
ButtonGridPopup paste_popup_;

bool multiple_selection_ = false;
bool is_adjusting_inspector_ = false;

void hovered(BlocksSlider* blocks_slider, const ModulatorComponent* modulator_component) override;
void unhovered(BlocksSlider* blocks_slider, const ModulatorComponent* modulator_component) override;

void handleUpdateButton();
void setupInspector();
void clear();
void resizeGrid();
void resizeTabContainer();
void ResizeInspector();
void resizeInspector();
void clickOnModulatorsPopup(Index index);
void loadPreset(int index);
void setupPopupMenus();
void darkBackgroundClicked(Component* darkBackground);
void setupDarkBackground(DarkBackground* component, int layer);
void resetDownFlowingDots();
void copy();
void highlightModulatableSliders(bool highlight, Colour color);

void resizeSelectionRect(const juce::MouseEvent& event);
void toggleGridItemSelection(GridComponent* grid, GridItemComponent* item, bool selected);
Expand All @@ -123,6 +139,10 @@ class MainComponent final: public Component,
void notesStarted(Array<int> notes) override;
void notesEnded(Array<int> notes) override;

// BlocksSlider::Listener
void sliderAdjusted(BlocksSlider* slider, float value) override;
void sliderGestureChanged(BlocksSlider* slider, bool started) override;

// InspectorComponent::Listener
void inspectorChangedParameter(int sliderIndex, float value) override;
void inspectorGestureChanged(std::string parameter_name, bool started) override;
Expand All @@ -148,8 +168,6 @@ class MainComponent final: public Component,
void modulatorEndedDrag(ModulatorComponent* modulatorComponent, const MouseEvent& event) override;
void modulatorIsDragging(ModulatorComponent* modulatorComponent, const MouseEvent& event) override;
void modulatorStartedDrag(ModulatorComponent* component, const MouseEvent& event) override;
void modulatorStartedAdjusting(ModulatorComponent* modulatorComponent, int index) override;
void modulatorEndedAdjusting(ModulatorComponent* modulatorComponent, int index) override;
void modulatorIsAdjusting(ModulatorComponent* component, std::string parameter_name, float value) override;
void modulatorGestureChanged(ModulatorComponent* modulatorComponent, std::string parameter_name, bool started) override;

Expand All @@ -165,8 +183,6 @@ class MainComponent final: public Component,
void presetButtonClicked();

void sliderValueChanged(Slider* slider) override;
// void sliderDragStarted(Slider* slider) override;
// void sliderDragEnded(Slider* slider) override;

void columnControlAdjusted(ColumnControlsContainer::ControlType control, int column, float value) override;
void columnControlStartedAdjusting(ColumnControlsContainer::ControlType control, int column) override;
Expand All @@ -187,14 +203,18 @@ struct MainComponent::Delegate {
virtual void editorAdjustedTab(int column, int parameterIndex, float value) = 0;
virtual void editorAdjustedModulator(std::string parameter_name, int index, float value) = 0;
virtual void editorConnectedModulation(int modulator_index, std::string target_name, std::string parameter) = 0;
virtual void editorChangedModulationMagnitude(int modulationConnectionIndex, float magnitude) = 0;
virtual void editorChangedModulationPolarity(int index, bool bipolar) = 0;
virtual void editorDisconnectedModulation(int index) = 0;
virtual void editorDisconnectedModulation(ID source_id, std::string target_name, std::string paramter) = 0;

virtual void editorStartedAdjustingParameter(ID& id, std::string& parameter_name, bool started) = 0;
virtual void editorAdjustedParameter(ID& id, std::string& parameter_name, float value) = 0;

virtual void editorStartedAdjustingColumn(std::string control, int column) = 0;
virtual void editorEndedAdjustingColumn(std::string control, int column) = 0;
virtual void editorAdjustedColumn(std::string contorl, int column, float value) = 0;

virtual void editorChangedModulationMagnitude(int modulationConnectionIndex, float magnitude) = 0;
virtual void editorChangedModulationPolarity(int index, bool bipolar) = 0;
virtual void editorDisconnectedModulation(int index) = 0;
virtual void editorParameterGestureChanged(std::string module_name, std::string paramter_name, bool started) = 0;
virtual void editorRemovedModulator(int index) = 0;
virtual void editorChangedBlockLength(Index index, int times) = 0;
Expand All @@ -217,8 +237,8 @@ struct MainComponent::Delegate {
virtual Array<int> editorRequestsActiveColumns() = 0;
virtual std::vector<std::shared_ptr<model::Module>> getModulators2() = 0;
virtual std::vector<std::shared_ptr<model::Connection>> getModulations() = 0;
// virtual Array<std::shared_ptr<Modulation>> getConnectionsOfSource(std::shared_ptr<Module> source) = 0;
virtual const vital::StatusOutput* editorRequestsStatusOutput(std::string name) = 0;

virtual ~Delegate() = default;
};
};
}
10 changes: 3 additions & 7 deletions Source/ModuleContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ struct ModuleContainer {
std::map<std::string, juce::Array<std::shared_ptr<M>>> map;
juce::Array<std::shared_ptr<M>> all;

void spawn(juce::Array<std::string> types, std::function<std::shared_ptr<M>(std::string, int)> spawner) {
void spawn(juce::Array<std::string> types, std::function<std::shared_ptr<M>(std::string, int)> spawner, int count = model::MAX_MODULES_PER_TYPE) {
for (const auto& type : types) {
juce::Array<std::shared_ptr<M>> array;

for (int i = 1; i <= model::MAX_MODULES_PER_TYPE; i++) {
for (int i = 1; i <= count; i++) {
array.add(std::shared_ptr<M>(spawner(type, i)));
}

Expand All @@ -24,11 +24,7 @@ struct ModuleContainer {
void retire(std::shared_ptr<M> module) {
module->reset();
map[module->id.type].add(module);

struct Sorter {
bool operator() (const std::shared_ptr<M> a, const std::shared_ptr<M> b) const noexcept { return a->id.number < b->id.number; }
};

struct Sorter { bool operator() (const std::shared_ptr<M> a, const std::shared_ptr<M> b) const noexcept { return a->id.number < b->id.number; } };
std::sort(map[module->id.type].begin(), map[module->id.type].end(), Sorter());
}

Expand Down
2 changes: 1 addition & 1 deletion Source/PluginEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class PluginEditor: public AudioProcessorEditor, juce::Timer {
PluginProcessor& processor;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginEditor)
public:
MainComponent mainComponent;
gui::MainComponent mainComponent;
PluginEditor(juce::MidiKeyboardState& keyboard_state, PluginProcessor& processor);
void paint(Graphics&) override;
void resized() override;
Expand Down
61 changes: 34 additions & 27 deletions Source/blocks_plugin_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ PluginProcessor::PluginProcessor(): juce::AudioProcessor(BusesProperties().withO

// for getVoiceHandler()->column_nodes_
for (auto column_control : synth_->getModuleManager().pool.column_controls_) {
auto processor = getVoiceHandler()->column_nodes_[column_control->id.number - 1];
auto processor = getVoiceHandler()->column_controls_[column_control->id.number - 1];
for (auto& pair : column_control->parameter_map_) {
column_control->parameter_map_[pair.first]->value_processor = processor->control_map_[pair.first];
}
Expand Down Expand Up @@ -320,15 +320,7 @@ juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() {
// MainComponent::Delegate
void PluginProcessor::editorAdjustedModulator(std::string parameter_name, int index, float value) {
auto modulator = synth_->getModuleManager().getModulator(index);

if (modulator->id.type != "envelope" && parameter_name == "tempo") {
bool is_changing_seconds = modulator->parameter_map_["sync"]->value_processor->value() == 0.0f;
parameter_name = is_changing_seconds ? "frequency" : "tempo";
modulator->parameter_map_[parameter_name]->set(value);
return;
}

modulator->parameter_map_[parameter_name]->set(value);
modulator->parameter_map_[modulator->getParameterName(parameter_name)]->set(value);
}

void PluginProcessor::editorAdjustedBlock(Index index, int parameter, float value) {
Expand All @@ -349,26 +341,25 @@ void PluginProcessor::editorAdjustedBlock(Index index, int parameter, float valu
bool is_changing_delay_tempo = block->id.type == "delay" && parameter == 4;
bool is_changing_mod_tempo = (block->id.type == "phaser" || block->id.type == "chorus" || block->id.type == "flanger") && parameter == 3;
if (is_changing_delay_tempo || is_changing_mod_tempo) {
auto sync = block->parameter_map_["sync"]->value_processor->value();
bool is_changing_seconds = block->parameter_map_["sync"]->value_processor->value() == 0.0f;
if (is_changing_seconds) {
block->parameter_map_["frequency"]->value_processor->set(value);
} else {
block->parameter_map_["tempo"]->value_processor->set(value);
}
return;
auto sync = block->parameter_map_["sync"]->value_processor->value();
bool is_changing_seconds = block->parameter_map_["sync"]->value_processor->value() == 0.0f;
if (is_changing_seconds) {
block->parameter_map_["frequency"]->value_processor->set(value);
} else {
block->parameter_map_["tempo"]->value_processor->set(value);
}
return;
}

block->parameters_[parameter]->set(value);
}

void PluginProcessor::editorChangedModulationMagnitude(int index, float magnitude) {
synth_->getModuleManager().getConnection(index)->amount_parameter_->set(magnitude);
// synth_->getModuleManager().getConnection(index)->amount_parameter_->set(magnitude);
}

void PluginProcessor::editorChangedModulationPolarity(int index, bool bipolar) {
synth_->getModuleManager().getConnection(index)->bipolar_parameter_->set(bipolar);
// moduleManager.getConnection(index)->setPolarity(bipolar);
synth_->getModuleManager().getConnection(index)->getParameter("bipolar")->set(bipolar);
}

void PluginProcessor::editorAdjustedTab(int column, int parameter, float value) {
Expand Down Expand Up @@ -432,8 +423,11 @@ void PluginProcessor::editorRepositionedBlock(Index from, Index to) {

void PluginProcessor::editorConnectedModulation(int modulatorIndex, std::string target_name, std::string parameter) {
synth_->connectModulation(modulatorIndex, target_name, parameter);
// Analytics::shared()->countAction("Modulation Connected");
// connect(modulatorIndex, targetName, parameter);
}

void PluginProcessor::editorDisconnectedModulation(ID source_id, std::string target_name, std::string parameter) { // remove modulator index and add source id
auto connection = synth_->getModuleManager().getConnection(source_id, target_name, parameter);
disconnect(connection);
}

void PluginProcessor::editorDisconnectedModulation(int index) {
Expand Down Expand Up @@ -492,8 +486,10 @@ void PluginProcessor::loadPreset(Preset preset) {

auto target = synth_->getModuleManager().getModule(presetConnection.target);
auto model = synth_->getModuleManager().addConnection(modulator, target, presetConnection.parameter, presetConnection.number);
model->amount_parameter_->value = presetConnection.amount;
model->bipolar_parameter_->value = presetConnection.bipolar;

model->parameter_map_["amount"]->value = presetConnection.amount;
model->parameter_map_["bipolar"]->value = presetConnection.bipolar;

connectModulationFromModel(model);
}

Expand Down Expand Up @@ -789,11 +785,22 @@ std::vector<std::shared_ptr<model::Block>> PluginProcessor::editorPastedIndices(
auto modulator = synth_->getModuleManager().getModule(connection->source->name);
auto target = synth_->getModuleManager().getModule(new_block->name);
auto model = synth_->getModuleManager().addConnection(modulator, target, connection->parameter_name_);
model->amount_parameter_->value = connection->amount_parameter_->value;
model->bipolar_parameter_->value = connection->bipolar_parameter_->value;
model->parameter_map_["amount"]->value_processor->set(connection->parameter_map_["amount"]->value);
model->parameter_map_["bipolar"]->value_processor->set(connection->parameter_map_["bipolar"]->value);
connectModulationFromModel(model);
}
}
block_updates_++;
return new_blocks;
}

void PluginProcessor::editorStartedAdjustingParameter(ID& id, std::string& parameter_name, bool started) {

}

void PluginProcessor::editorAdjustedParameter(ID& id, std::string& parameter_name, float value) {
auto m = synth_->getModuleManager().getModule(id);
auto pname = m->getParameterName(parameter_name);
auto parameter = m->parameter_map_[pname];
parameter->value_processor->set(value);
}
10 changes: 7 additions & 3 deletions Source/blocks_plugin_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

class ValueBridge;

class PluginProcessor: public SynthBase, public juce::AudioProcessor, public ValueBridge::Listener, public MainComponent::Delegate, public SynthGuiInterface {
class PluginProcessor: public SynthBase, public juce::AudioProcessor, public ValueBridge::Listener, public gui::MainComponent::Delegate, public SynthGuiInterface {
public:
static constexpr int kSetProgramWaitMilliseconds = 500;

Expand Down Expand Up @@ -94,19 +94,23 @@ class PluginProcessor: public SynthBase, public juce::AudioProcessor, public Val
void editorParameterGestureChanged(std::string module_name, std::string paramter_name, bool started) override;
void editorChangedModulationPolarity(int index, bool bipolar) override;
void editorDisconnectedModulation(int index) override;
void editorDisconnectedModulation(ID source_id, std::string target_name, std::string parameter) override;
void editorSavedPreset(std::string name) override;
void editorConnectedModulation(int modulatorIndex, std::string target_name, std::string parameter) override;
void editorChangedBlockLength(Index index, int length) override;
void editorAdjustedModulator(std::string parameter_name, int modulator, float value) override;
void editorRemovedModulator(int index) override;
std::optional<Preset> editorNavigatedPreset(bool next) override;
std::optional<Preset> editorNavigatedPreset(bool next) override;

void editorStartedAdjustingColumn(std::string control, int column) override;
void editorEndedAdjustingColumn(std::string control, int column) override;
void editorAdjustedColumn(std::string contorl, int column, float value) override;

void disconnect(std::shared_ptr<model::Connection>& connection);

void editorStartedAdjustingParameter(ID& id, std::string& parameter_name, bool started) override;
void editorAdjustedParameter(ID& id, std::string& parameter_name, float value) override;

std::shared_ptr<model::Block> getBlock2(Index index) override;
// std::shared_ptr<Tab> getTab(int column) override;
std::shared_ptr<model::Block> editorAddedBlock2(std::string code, Index index) override;
Expand Down Expand Up @@ -135,7 +139,7 @@ class PluginProcessor: public SynthBase, public juce::AudioProcessor, public Val
ValueBridge* bypass_parameter_;
double last_seconds_time_;
MidiKeyboardState keyboard_state_;
MainComponent* main_component_;
gui::MainComponent* main_component_;
PresetManager preset_manager_;
void loadPreset(Preset preset);
void setValue(std::string module_id, std::string parameter, float value);
Expand Down
9 changes: 7 additions & 2 deletions Source/chorus_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace model {
class ChorusModule: public Block {
public:
ChorusModule(int number): Block("chorus", number) {
add({ .name = "voices", .min = 1.0, .max = 4.0, .display_multiply = 4.0, .value_scale = ValueScale::kIndexed });
add({ .name = "voices", .min = 1.0, .max = 4.0, .display_multiply = 4.0, .value_scale = ValueScale::kIndexed, .modulatable = false });
add({ .name = "depth", .default_value = 0.5f });
add({ .name = "feedback", .min = -0.95f, .max = 0.95f, .default_value = 0.4f });
add({ .name = "sync", .max = 3.0f, .default_value = 1.0f, .value_scale = ValueScale::kIndexed, .string_lookup = strings::kFrequencySyncNames, .modulatable = false });
add({ .name = "tempo", .max = 10.0f, .default_value = 4.0f, .value_scale = ValueScale::kIndexed, .string_lookup = strings::kSyncedFrequencyNames });
add({ .name = "sync", .max = 3.0f, .default_value = 1.0f, .value_scale = ValueScale::kIndexed, .string_lookup = strings::kFrequencySyncNames });
add({ .name = "mix", .default_value = 0.5f });
add({ .name = "frequency", .min = -6.0f, .max = 3.0f, .default_value = 2.0f, .value_scale = ValueScale::kExponential, .display_invert = true, .decimal_places = 3, .hidden = true });
}
Expand All @@ -19,5 +19,10 @@ class ChorusModule: public Block {
if (is_tempo_or_secs) return parameters_[4]->value_processor->value() < 1.0 ? "frequency" : "tempo";
return Block::getParameterName(index);
}

std::string getParameterName(std::string name) override {
if (name == "tempo") return parameter_map_["sync"]->value_processor->value() < 1.0 ? "frequency" : "tempo";
return Block::getParameterName(name);
}
};
}

0 comments on commit cbdd1e1

Please sign in to comment.