Skip to content

Commit

Permalink
Copy and Paste Scene includes Global Modes; Insert FX
Browse files Browse the repository at this point in the history
Copy and Paste a scene now includes the following

1. Any scene -> global modulators (like SLFO1 to global volume)
2. The insert FX chain
3. Any modulations to the insert FX move from A to B on paste so
   the topology remains

Closes surge-synthesizer#7166
  • Loading branch information
baconpaul committed Nov 19, 2023
1 parent fdb5029 commit ade6ea2
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 13 deletions.
108 changes: 106 additions & 2 deletions src/common/SurgeStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1545,6 +1545,29 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry, modsources ms)
clipboard_extraconfig[i] = getPatch().scene[scene].osc[i].extraConfig;
}

auto fxOffset = 0;
if (scene == 0)
{
fxOffset = 0;
}
else if (scene == 1)
{
fxOffset = 4;
}
else
{
throw std::logic_error(
"Scene not 0 or 1; have you gone multi-scene without updating clipboard?");
}

for (int i = 0; i < n_fx_per_chain; ++i)
{
auto sl = fxslot_order[i + fxOffset];
if (!clipboard_scenefx[i])
clipboard_scenefx[i] = std::make_unique<Surge::FxClipboard::Clipboard>();
Surge::FxClipboard::copyFx(this, &getPatch().fx[sl], *(clipboard_scenefx[i]));
}

clipboard_primode = getPatch().scene[scene].monoVoicePriorityMode;
clipboard_envmode = getPatch().scene[scene].monoVoiceEnvelopeMode;
}
Expand Down Expand Up @@ -1614,6 +1637,48 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry, modsources ms)
clipboard_modulation_scene.push_back(m);
}
}

if (type & cp_scene)
{
n = getPatch().modulation_global.size();
for (int i = 0; i < n; i++)
{
if (getPatch().modulation_global[i].source_scene != scene)
{
continue;
}

ModulationRouting m;
m.source_id = getPatch().modulation_global[i].source_id;
m.source_index = getPatch().modulation_global[i].source_index;
m.source_scene = getPatch().modulation_global[i].source_scene;
m.depth = getPatch().modulation_global[i].depth;

auto did = getPatch().modulation_global[i].destination_id;
auto dpar = getPatch().param_ptr[did];
if (dpar->ctrlgroup == cg_FX)
{
assert(scene < 2);
for (int q = 0; q < n_fx_per_chain; ++q)
{
auto srcSl = fxslot_order[q + scene * 4];
auto tgtSl = fxslot_order[q + (1 - scene) * 4];
if (dpar->ctrlgroup_entry == srcSl)
{
int64_t d0 =
getPatch().fx[tgtSl].p[0].id - getPatch().fx[srcSl].p[0].id;
m.destination_id =
getPatch().modulation_global[i].destination_id + d0;
}
}
}
else
{
m.destination_id = getPatch().modulation_global[i].destination_id;
}
clipboard_modulation_global.push_back(m);
}
}
}

if (type & cp_modulator_target)
Expand Down Expand Up @@ -1678,8 +1743,10 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry, modsources ms)
modRoutingMutex.unlock();
}

void SurgeStorage::clipboard_paste(int type, int scene, int entry, modsources ms,
std::function<bool(int, modsources)> isValid)
void SurgeStorage::clipboard_paste(
int type, int scene, int entry, modsources ms, std::function<bool(int, modsources)> isValid,
std::function<void(std::unique_ptr<Surge::FxClipboard::Clipboard> &, int)> updateFxInSlot)

{
assert(scene < n_scenes);

Expand Down Expand Up @@ -1741,6 +1808,30 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry, modsources ms
getPatch().scene[scene].osc[i].wavetable_display_name = clipboard_wt_names[i];
}

auto fxOffset = 0;
if (scene == 0)
{
fxOffset = 0;
}
else if (scene == 1)
{
fxOffset = 4;
}
else
{
throw std::logic_error(
"Scene not 0 or 1; have you gone multi-scene without updating clipboard?");
}
for (int i = 0; i < n_fx_per_chain; ++i)
{
auto sl = fxslot_order[i + fxOffset];
if (clipboard_scenefx[i] &&
Surge::FxClipboard::isPasteAvailable(*(clipboard_scenefx[i])))
{
updateFxInSlot(clipboard_scenefx[i], sl);
}
}

getPatch().scene[scene].monoVoicePriorityMode = clipboard_primode;
getPatch().scene[scene].monoVoiceEnvelopeMode = clipboard_envmode;
}
Expand Down Expand Up @@ -1970,6 +2061,19 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry, modsources ms
m.destination_id = clipboard_modulation_scene[i].destination_id;
pushBackOrOverride(getPatch().scene[scene].modulation_scene, m);
}

n = clipboard_modulation_global.size();
for (int i = 0; i < n; i++)
{
ModulationRouting m;
m.source_id = clipboard_modulation_global[i].source_id;
m.source_index = clipboard_modulation_global[i].source_index;
m.source_scene = scene; /* clipboard_modulation_global[i].source_scene; */
m.depth = clipboard_modulation_global[i].depth;
m.destination_id = clipboard_modulation_global[i].destination_id;

pushBackOrOverride(getPatch().modulation_global, m);
}
}
}

Expand Down
16 changes: 13 additions & 3 deletions src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,12 @@ class MTSClient;

namespace Surge
{

namespace FxClipboard
{
struct Clipboard;
}

namespace Storage
{
struct ScenesOutputData
Expand Down Expand Up @@ -1348,9 +1354,11 @@ class alignas(16) SurgeStorage
// and also to stop me having to move all of isValidModulation and its buddies onto SurgeStorage
void clipboard_paste(
int type, int scene, int entry, modsources ms = ms_original,
std::function<bool(int, modsources)> isValidModulation = [](auto a, auto b) {
return true;
});
std::function<bool(int, modsources)> isValidModulation = [](auto a,
auto b) { return true; },
std::function<void(std::unique_ptr<Surge::FxClipboard::Clipboard> &, int)> updateFxInSlot =
[](auto &a, auto b) {});
;
int get_clipboard_type() const;
// direction: false for previous, true for next
int getAdjacentWaveTable(int id, bool direction) const;
Expand Down Expand Up @@ -1637,6 +1645,8 @@ class alignas(16) SurgeStorage
std::vector<Parameter> clipboard_p;
int clipboard_type;
StepSequencerStorage clipboard_stepsequences[n_lfos];
// UP this for the forward decl fix
std::unique_ptr<Surge::FxClipboard::Clipboard> clipboard_scenefx[n_fx_per_chain];
MSEGStorage clipboard_msegs[n_lfos];
FormulaModulatorStorage clipboard_formulae[n_lfos];
OscillatorStorage::ExtraConfigurationData clipboard_extraconfig[n_oscs];
Expand Down
28 changes: 20 additions & 8 deletions src/surge-xt/gui/SurgeGUIEditorValueCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,14 +795,26 @@ int32_t SurgeGUIEditor::controlModifierClicked(Surge::GUI::IComponentTagValue *c
synth->storage.clipboard_copy(cp_scene, current_scene, -1);
});

contextMenu.addItem(Surge::GUI::toOSCase("Paste Scene"),
synth->storage.get_clipboard_type() == cp_scene, // enabled
false, [this]() {
undoManager()->pushPatch();
synth->storage.clipboard_paste(cp_scene, current_scene, -1);
synth->storage.getPatch().isDirty = true;
queue_refresh = true;
});
contextMenu.addItem(
Surge::GUI::toOSCase("Paste Scene"),
synth->storage.get_clipboard_type() == cp_scene, // enabled
false, [this]() {
undoManager()->pushPatch();
synth->storage.clipboard_paste(
cp_scene, current_scene, -1, ms_original,
[this](int p, modsources m) {
auto res = synth->isValidModulation(p, m);
return res;
},
[this](std::unique_ptr<Surge::FxClipboard::Clipboard> &f, int cge) {
Surge::FxClipboard::pasteFx(&(synth->storage), &synth->fxsync[cge], *f);
synth->fx_reload[cge] = true;
});

synth->load_fx_needed = true;
synth->storage.getPatch().isDirty = true;
queue_refresh = true;
});

contextMenu.showMenuAsync(popupMenuOptions(control->asJuceComponent(), false),
Surge::GUI::makeEndHoverCallback(control));
Expand Down

0 comments on commit ade6ea2

Please sign in to comment.