Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy and Paste Modulation Routings #5181

Merged
merged 1 commit into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 141 additions & 36 deletions src/common/SurgeStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,10 +1258,10 @@ int SurgeStorage::getAdjacentWaveTable(int id, bool nextPrev) const
}
}

void SurgeStorage::clipboard_copy(int type, int scene, int entry)
void SurgeStorage::clipboard_copy(int type, int scene, int entry, modsources ms)
{
bool includemod = false, includeall = false;
if (type == cp_oscmod)
if (type & cp_oscmod)
{
type = cp_osc;
includemod = true;
Expand All @@ -1271,9 +1271,8 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry)
int id = -1;

clipboard_type = type;
switch (type)
if (type & cp_osc)
{
case cp_osc:
cgroup = 2;
cgroup_e = entry;
id = getPatch().scene[scene].osc[entry].type.id; // first parameter id
Expand All @@ -1285,8 +1284,9 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry)
}
memcpy(&clipboard_extraconfig[0], &getPatch().scene[scene].osc[entry].extraConfig,
sizeof(OscillatorStorage::ExtraConfigurationData));
break;
case cp_lfo:
}
if (type & cp_lfo)
{
cgroup = 6;
cgroup_e = entry + ms_lfo1;
id = getPatch().scene[scene].lfo[entry].shape.id;
Expand All @@ -1297,8 +1297,8 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry)
clipboard_msegs[0] = getPatch().msegs[scene][entry];
if (getPatch().scene[scene].lfo[entry].shape.val.i == lt_formula)
clipboard_formulae[0] = getPatch().formulamods[scene][entry];
break;
case cp_scene:
}
if (type & cp_scene)
{
includemod = true;
includeall = true;
Expand All @@ -1320,17 +1320,13 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry)
}
clipboard_primode = getPatch().scene[scene].monoVoicePriorityMode;
}
break;
default:
return;
}

modRoutingMutex.lock();
{

clipboard_p.clear();
clipboard_modulation_scene.clear();
clipboard_modulation_voice.clear();
clipboard_modulation_global.clear();

std::set<int> used_entries;

Expand Down Expand Up @@ -1377,14 +1373,62 @@ void SurgeStorage::clipboard_copy(int type, int scene, int entry)
clipboard_modulation_scene.push_back(m);
}
}

if (type & cp_modulator_target)
{
if (entry >= 0)
{
ms = (modsources)(entry + ms_lfo1);
}
n = getPatch().scene[scene].modulation_voice.size();
for (int i = 0; i < n; i++)
{
if (getPatch().scene[scene].modulation_voice[i].source_id != ms)
continue;
ModulationRouting m;
m.source_id = getPatch().scene[scene].modulation_voice[i].source_id;
m.source_index = getPatch().scene[scene].modulation_voice[i].source_index;
m.depth = getPatch().scene[scene].modulation_voice[i].depth;
m.destination_id = getPatch().scene[scene].modulation_voice[i].destination_id;
clipboard_modulation_voice.push_back(m);
}
n = getPatch().scene[scene].modulation_scene.size();
for (int i = 0; i < n; i++)
{
if (getPatch().scene[scene].modulation_scene[i].source_id != ms)
continue;
ModulationRouting m;
m.source_id = getPatch().scene[scene].modulation_scene[i].source_id;
m.source_index = getPatch().scene[scene].modulation_scene[i].source_index;
m.depth = getPatch().scene[scene].modulation_scene[i].depth;
m.destination_id = getPatch().scene[scene].modulation_scene[i].destination_id;
clipboard_modulation_scene.push_back(m);
}
n = getPatch().modulation_global.size();
for (int i = 0; i < n; i++)
{
if (getPatch().modulation_global[i].source_id != ms ||
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;
m.destination_id = getPatch().modulation_global[i].destination_id;
clipboard_modulation_global.push_back(m);
}
}
}
modRoutingMutex.unlock();
}

void SurgeStorage::clipboard_paste(int type, int scene, int entry)
void SurgeStorage::clipboard_paste(int type, int scene, int entry, modsources ms,
std::function<bool(int, modsources)> isValid)
{
assert(scene < n_scenes);
if (type != clipboard_type)

if (!(type & clipboard_type))
return;

int cgroup = -1;
Expand All @@ -1393,12 +1437,12 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)
int n = clipboard_p.size();
int start = 0;

if (!n)
return;
// fixme make this one or the other
// if (!n)
// return;

switch (type)
if (type & cp_osc)
{
case cp_osc:
cgroup = 2;
cgroup_e = entry;
id = getPatch().scene[scene].osc[entry].type.id; // first parameter id
Expand All @@ -1408,13 +1452,14 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)

memcpy(&getPatch().scene[scene].osc[entry].extraConfig, &clipboard_extraconfig[0],
sizeof(OscillatorStorage::ExtraConfigurationData));
break;
case cp_lfo:
}
if (type & cp_lfo)
{
cgroup = 6;
cgroup_e = entry + ms_lfo1;
id = getPatch().scene[scene].lfo[entry].shape.id;
break;
case cp_scene:
}
if (type & cp_scene)
{
id = getPatch().scene[scene].octave.id;

Expand All @@ -1437,14 +1482,16 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)

getPatch().scene[scene].monoVoicePriorityMode = clipboard_primode;
}
break;
default:
return;

if (type == cp_modulator_target)
{
// We use an == here rather than an & because in this case we want *only* the mod targets
// so disable the parameter copies
n = 0;
}

modRoutingMutex.lock();
{

for (int i = start; i < n; i++)
{
Parameter p = clipboard_p[i];
Expand All @@ -1460,9 +1507,7 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)
getPatch().param_ptr[pid]->deform_type = p.deform_type;
}

switch (type)
{
case cp_osc:
if (type & cp_osc)
{
if (uses_wavetabledata(getPatch().scene[scene].osc[entry].type.val.i))
{
Expand Down Expand Up @@ -1495,18 +1540,79 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)
getPatch().scene[scene].modulation_scene.push_back(m);
}
}
break;
case cp_lfo:
if (type & cp_lfo)
{
if (getPatch().scene[scene].lfo[entry].shape.val.i == lt_stepseq)
memcpy(&getPatch().stepsequences[scene][entry], &clipboard_stepsequences[0],
sizeof(StepSequencerStorage));
if (getPatch().scene[scene].lfo[entry].shape.val.i == lt_mseg)
getPatch().msegs[scene][entry] = clipboard_msegs[0];
if (getPatch().scene[scene].lfo[entry].shape.val.i == lt_formula)
getPatch().formulamods[scene][entry] = clipboard_formulae[0];

break;
case cp_scene:
}
if (type & cp_modulator_target)
{
if (entry >= 0)
{
ms = (modsources)(entry + ms_lfo1);
}
// copy modroutings
n = clipboard_modulation_voice.size();
for (int i = 0; i < n; i++)
{
ModulationRouting m;
m.source_id = ms;
m.source_index = clipboard_modulation_voice[i].source_index;
m.depth = clipboard_modulation_voice[i].depth;
m.destination_id = clipboard_modulation_voice[i].destination_id;
if (isValid(m.destination_id + getPatch().scene_start[scene],
(modsources)m.source_id))
{
if (isScenelevel((modsources)m.source_id))
{
getPatch().scene[scene].modulation_scene.push_back(m);
}
else
{
getPatch().scene[scene].modulation_voice.push_back(m);
}
}
}
n = clipboard_modulation_scene.size();
for (int i = 0; i < n; i++)
{
ModulationRouting m;
m.source_id = ms;
m.source_index = clipboard_modulation_scene[i].source_index;
m.depth = clipboard_modulation_scene[i].depth;
m.destination_id = clipboard_modulation_scene[i].destination_id;
if (isValid(m.destination_id + getPatch().scene_start[scene],
(modsources)m.source_id))
{
if (isScenelevel((modsources)m.source_id))
{
getPatch().scene[scene].modulation_scene.push_back(m);
}
else
{
getPatch().scene[scene].modulation_voice.push_back(m);
}
}
}
n = clipboard_modulation_global.size();
for (int i = 0; i < n; i++)
{
ModulationRouting m;
m.source_id = ms;
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;
if (isValid(m.destination_id, (modsources)m.source_id))
getPatch().modulation_global.push_back(m);
}
}
if (type & cp_scene)
{
getPatch().scene[scene].modulation_voice.clear();
getPatch().scene[scene].modulation_scene.clear();
Expand All @@ -1533,7 +1639,6 @@ void SurgeStorage::clipboard_paste(int type, int scene, int entry)
getPatch().scene[scene].modulation_scene.push_back(m);
}
}
}
}

modRoutingMutex.unlock();
Expand Down
26 changes: 17 additions & 9 deletions src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -880,12 +880,12 @@ struct PatchCategory
enum surge_copysource
{
cp_off = 0,
cp_scene,
cp_osc,
cp_lfo,
cp_oscmod,

n_copysources,
cp_scene = 1U << 1,
cp_osc = 1U << 2,
cp_oscmod = 1U << 3,
cp_lfo = 1U << 4,
cp_modulator_target = 1U << 5,
cp_lfomod = cp_lfo | cp_modulator_target
};

class MTSClient;
Expand Down Expand Up @@ -1014,8 +1014,15 @@ class alignas(16) SurgeStorage
// void load_wt_wav(std::string filename, Wavetable* wt);
bool load_wt_wav_portable(std::string filename, Wavetable *wt);
std::string export_wt_wav_portable(std::string fbase, Wavetable *wt);
void clipboard_copy(int type, int scene, int entry);
void clipboard_paste(int type, int scene, int entry);
void clipboard_copy(int type, int scene, int entry, modsources ms = ms_original);
// this function is a bit of a hack to stop me having a reference to a surge synth
// here and also stop me having to move all of isValidModulation and its buddies onto
// storage
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;
});
int get_clipboard_type() const;
int getAdjacentWaveTable(int id, bool nextPrev) const;

Expand Down Expand Up @@ -1275,7 +1282,8 @@ class alignas(16) SurgeStorage
MSEGStorage clipboard_msegs[n_lfos];
FormulaModulatorStorage clipboard_formulae[n_lfos];
OscillatorStorage::ExtraConfigurationData clipboard_extraconfig[n_oscs];
std::vector<ModulationRouting> clipboard_modulation_scene, clipboard_modulation_voice;
std::vector<ModulationRouting> clipboard_modulation_scene, clipboard_modulation_voice,
clipboard_modulation_global;
Wavetable clipboard_wt[n_oscs];
char clipboard_wt_names[n_oscs][256];
MonoVoicePriorityMode clipboard_primode = NOTE_ON_LATEST_RETRIGGER_HIGHEST;
Expand Down
Loading