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

wavetable morph lag adjustment #7783

Merged
merged 2 commits into from
Sep 12, 2024
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
8 changes: 6 additions & 2 deletions src/common/SurgePatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,14 +978,18 @@ void SurgePatch::init_default_values()

SurgePatch::~SurgePatch() { free(patchptr); }

void SurgePatch::copy_scenedata(pdata *d, int scene)
void SurgePatch::copy_scenedata(pdata *d, pdata *dUnmod, int scene)
{

int s = scene_start[scene];
for (int i = 0; i < n_scene_params; i++)
{
// if (param_ptr[i+s]->valtype == vt_float)
// d[i].f = param_ptr[i+s]->val.f;
d[i].i = param_ptr[i + s]->val.i;

if (param_ptr[i + s]->ctrlgroup == cg_OSC)
dUnmod[i].f = d[i].f;
}

for (int i = 0; i < paramModulationCount; ++i)
Expand Down Expand Up @@ -1068,7 +1072,7 @@ void SurgePatch::update_controls(

unsigned char mbuf alignas(16)[oscillator_buffer_size];
Oscillator *t_osc =
spawn_osc(sc.osc[osc].type.val.i, storage, &sc.osc[osc], nullptr, mbuf);
spawn_osc(sc.osc[osc].type.val.i, storage, &sc.osc[osc], nullptr, nullptr, mbuf);
if (t_osc)
{
t_osc->init_ctrltypes(sn, osc);
Expand Down
3 changes: 2 additions & 1 deletion src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ class SurgePatch
void init_default_values();
void update_controls(bool init = false, void *init_osc = 0, bool from_stream = false);
void do_morph();
void copy_scenedata(pdata *, int scene);
void copy_scenedata(pdata *, pdata *, int scene);
void copy_globaldata(pdata *);

// load/save
Expand Down Expand Up @@ -1086,6 +1086,7 @@ class SurgePatch

std::vector<ModulationRouting> modulation_global;
pdata scenedata[n_scenes][n_scene_params];
pdata scenedataOrig[n_scenes][n_scene_params];
pdata globaldata[n_global_params];
void *patchptr;
SurgeStorage *storage;
Expand Down
32 changes: 20 additions & 12 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ SurgeSynthesizer::SurgeSynthesizer(PluginLayer *parent, const std::string &suppl
// TODO: FIX SCENE ASSUMPTION
memset(storage.getPatch().scenedata[0], 0, sizeof(pdata) * n_scene_params);
memset(storage.getPatch().scenedata[1], 0, sizeof(pdata) * n_scene_params);

memset(storage.getPatch().scenedataOrig[0], 0, sizeof(pdata) * n_scene_params);
memset(storage.getPatch().scenedataOrig[1], 0, sizeof(pdata) * n_scene_params);

memset(storage.getPatch().globaldata, 0, sizeof(pdata) * n_global_params);
memset(mControlInterpolatorUsed, 0, sizeof(bool) * num_controlinterpolators);

Expand Down Expand Up @@ -833,12 +837,12 @@ void SurgeSynthesizer::playVoice(int scene, char channel, char key, char velocit
int mpeMainChannel = getMpeMainChannel(channel, key);

voices[scene].push_back(nvoice);
new (nvoice) SurgeVoice(&storage, &storage.getPatch().scene[scene],
storage.getPatch().scenedata[scene], key, velocity, channel,
scene, detune, &channelState[channel].keyState[key],
&channelState[mpeMainChannel], &channelState[channel],
mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, 0.f, 0.f);
new (nvoice) SurgeVoice(
&storage, &storage.getPatch().scene[scene], storage.getPatch().scenedata[scene],
storage.getPatch().scenedataOrig[scene], key, velocity, channel, scene, detune,
&channelState[channel].keyState[key], &channelState[mpeMainChannel],
&channelState[channel], mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, 0.f, 0.f);
}
}
break;
Expand Down Expand Up @@ -979,8 +983,9 @@ void SurgeSynthesizer::playVoice(int scene, char channel, char key, char velocit
storage.last_key[scene] = key;
new (nvoice) SurgeVoice(
&storage, &storage.getPatch().scene[scene],
storage.getPatch().scenedata[scene], key, velocity, channel, scene, detune,
&channelState[channel].keyState[key], &channelState[mpeMainChannel],
storage.getPatch().scenedata[scene],
storage.getPatch().scenedataOrig[scene], key, velocity, channel, scene,
detune, &channelState[channel].keyState[key], &channelState[mpeMainChannel],
&channelState[channel], mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, aegReuse, fegReuse);

Expand Down Expand Up @@ -1123,8 +1128,9 @@ void SurgeSynthesizer::playVoice(int scene, char channel, char key, char velocit
voices[scene].push_back(nvoice);
new (nvoice) SurgeVoice(
&storage, &storage.getPatch().scene[scene],
storage.getPatch().scenedata[scene], key, velocity, channel, scene, detune,
&channelState[channel].keyState[key], &channelState[mpeMainChannel],
storage.getPatch().scenedata[scene],
storage.getPatch().scenedataOrig[scene], key, velocity, channel, scene,
detune, &channelState[channel].keyState[key], &channelState[mpeMainChannel],
&channelState[channel], mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, aegStart, fegStart);
}
Expand Down Expand Up @@ -4395,9 +4401,11 @@ void SurgeSynthesizer::processControl()

// TODO: FIX SCENE ASSUMPTION
if (playA)
storage.getPatch().copy_scenedata(storage.getPatch().scenedata[0], 0); // -""-
storage.getPatch().copy_scenedata(storage.getPatch().scenedata[0],
storage.getPatch().scenedataOrig[0], 0); // -""-
if (playB)
storage.getPatch().copy_scenedata(storage.getPatch().scenedata[1], 1);
storage.getPatch().copy_scenedata(storage.getPatch().scenedata[1],
storage.getPatch().scenedataOrig[1], 1);

// TODO: FIX SCENE ASSUMPTION.
// Prior to 1.1 we could play before or after copying modulation data but as we
Expand Down
4 changes: 2 additions & 2 deletions src/common/dsp/Oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
using namespace std;

Oscillator *spawn_osc(int osctype, SurgeStorage *storage, OscillatorStorage *oscdata,
pdata *localcopy, unsigned char *onto)
pdata *localcopy, pdata *localcopyUnmod, unsigned char *onto)
{
static bool checkSizes = true;
if (checkSizes)
Expand Down Expand Up @@ -91,7 +91,7 @@ Oscillator *spawn_osc(int osctype, SurgeStorage *storage, OscillatorStorage *osc
case ot_classic:
return new (onto) ClassicOscillator(storage, oscdata, localcopy);
case ot_wavetable:
return new (onto) WavetableOscillator(storage, oscdata, localcopy);
return new (onto) WavetableOscillator(storage, oscdata, localcopy, localcopyUnmod);
case ot_window:
{
// In the event we are misconfigured, window oscillator will segfault. If you still play
Expand Down
2 changes: 1 addition & 1 deletion src/common/dsp/Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
static constexpr size_t oscillator_buffer_size = 16 * 1024;

Oscillator *spawn_osc(int osctype, SurgeStorage *storage, OscillatorStorage *oscdata,
pdata *localcopy,
pdata *localcopy, pdata *localcopyUnmod,
unsigned char *onto); // This buffer should be at least oscillator_buffer_size

#endif // SURGE_SRC_COMMON_DSP_OSCILLATOR_H
9 changes: 5 additions & 4 deletions src/common/dsp/SurgeVoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ SurgeVoice::SurgeVoice()
#endif
}

SurgeVoice::SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *oscene, pdata *params, int key,
int velocity, int channel, int scene_id, float detune,
MidiKeyState *keyState, MidiChannelState *mainChannelState,
SurgeVoice::SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *oscene, pdata *params,
pdata *paramsUnmod, int key, int velocity, int channel, int scene_id,
float detune, MidiKeyState *keyState, MidiChannelState *mainChannelState,
MidiChannelState *voiceChannelState, bool mpeEnabled, int64_t voiceOrder,
int32_t host_nid, int16_t host_key, int16_t host_chan, float aegStart,
float fegStart)
Expand All @@ -165,6 +165,7 @@ SurgeVoice::SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *oscene, pdata *
this->storage = storage;
this->scene = oscene;
this->paramptr = params;
this->paramptrUnmod = paramsUnmod;
this->mpeEnabled = mpeEnabled;
this->host_note_id = host_nid;
this->originating_host_key = host_key;
Expand Down Expand Up @@ -527,7 +528,7 @@ void SurgeVoice::switch_toggled()
{
bool nzid = scene->drift.extend_range;
osc[i] = spawn_osc(scene->osc[i].type.val.i, storage, &scene->osc[i], localcopy,
oscbuffer[i]);
this->paramptrUnmod, oscbuffer[i]);
if (osc[i])
{
// this matches the override in ::process_block
Expand Down
16 changes: 9 additions & 7 deletions src/common/dsp/SurgeVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,18 @@ class alignas(16) SurgeVoice
float output alignas(16)[2][BLOCK_SIZE_OS];
lipol_ps osclevels alignas(16)[7];
pdata localcopy alignas(16)[n_scene_params];
pdata localcopy2 alignas(16)[n_scene_params];
float fmbuffer alignas(16)[BLOCK_SIZE_OS];

// used for the 2>1<3 FM-mode (Needs the pointer earlier)

SurgeVoice();
SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *scene, pdata *params, int key,
int velocity, int channel, int scene_id, float detune, MidiKeyState *keyState,
MidiChannelState *mainChannelState, MidiChannelState *voiceChannelState,
bool mpeEnabled, int64_t voiceOrder, int32_t host_note_id,
int16_t originating_host_key, int16_t originating_host_channel, float aegStart,
float fegStart);
SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *scene, pdata *params, pdata *paramsUnmod,
int key, int velocity, int channel, int scene_id, float detune,
MidiKeyState *keyState, MidiChannelState *mainChannelState,
MidiChannelState *voiceChannelState, bool mpeEnabled, int64_t voiceOrder,
int32_t host_note_id, int16_t originating_host_key, int16_t originating_host_channel,
float aegStart, float fegStart);
~SurgeVoice();

void release();
Expand Down Expand Up @@ -261,8 +262,9 @@ class alignas(16) SurgeVoice

// data
int lag_id[8], pitch_id, octave_id, volume_id, pan_id, width_id;
SurgeSceneStorage *scene, *origscene;
SurgeSceneStorage *scene;
pdata *paramptr;
pdata *paramptrUnmod;
int route[6];

float octaveSize = 12.0f;
Expand Down
12 changes: 7 additions & 5 deletions src/common/dsp/oscillators/WavetableOscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ using namespace std;
const float hpf_cycle_loss = 0.99f;

WavetableOscillator::WavetableOscillator(SurgeStorage *storage, OscillatorStorage *oscdata,
pdata *localcopy)
pdata *localcopy, pdata *localcopyUnmod)
: AbstractBlitOscillator(storage, oscdata, localcopy)
{
unmodulatedLocalcopy = localcopyUnmod;
}

WavetableOscillator::~WavetableOscillator() {}
Expand Down Expand Up @@ -85,8 +86,8 @@ void WavetableOscillator::init(float pitch, bool is_display, bool nonzero_init_d
// rather than wavetable from first to second to last frame
nointerp = !oscdata->p[wt_morph].extend_range;

float shape = l_shape.v;

float shape = limit_range(
l_shape.v + (localcopy[id_shape].f - unmodulatedLocalcopy[id_shape].f), 0.f, 1.f);
float intpart;
shape *= ((float)oscdata->wt.n_tables - 1.f + nointerp) * 0.99999f;
tableipol = shape;
Expand Down Expand Up @@ -377,7 +378,7 @@ template <bool is_init> void WavetableOscillator::update_lagvals()
l_hskew.newValue(limit_range(localcopy[id_hskew].f, -1.f, 1.f));
float a = limit_range(localcopy[id_clip].f, 0.f, 1.f);
l_clip.newValue(-8 * a * a * a);
l_shape.newValue(limit_range(localcopy[id_shape].f, 0.f, 1.f));
l_shape.newValue(unmodulatedLocalcopy[id_shape].f);
formant_t = max(0.f, localcopy[id_formant].f);

float invt = min(1.0, (8.175798915 * storage->note_to_pitch_tuningctr(pitch_t)) *
Expand Down Expand Up @@ -440,7 +441,8 @@ void WavetableOscillator::process_block(float pitch0, float drift, bool stereo,
last_tableipol = tableipol;
last_tableid = tableid;

float shape = l_shape.v;
float shape = limit_range(
l_shape.v + (localcopy[id_shape].f - unmodulatedLocalcopy[id_shape].f), 0.f, 1.f);
float intpart;
shape *= ((float)oscdata->wt.n_tables - 1.f + nointerp) * 0.99999f;
tableipol = shape;
Expand Down
4 changes: 3 additions & 1 deletion src/common/dsp/oscillators/WavetableOscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class WavetableOscillator : public AbstractBlitOscillator
};

lipol_ps li_hpf, li_DC, li_integratormult;
WavetableOscillator(SurgeStorage *storage, OscillatorStorage *oscdata, pdata *localcopy);
WavetableOscillator(SurgeStorage *storage, OscillatorStorage *oscdata, pdata *localcopy,
pdata *localcopyUnmod);
virtual void init(float pitch, bool is_display = false,
bool nonzero_init_drift = true) override;
virtual void init_ctrltypes() override;
Expand Down Expand Up @@ -72,6 +73,7 @@ class WavetableOscillator : public AbstractBlitOscillator
int nointerp;
float FMmul_inv;
int sampleloop;
pdata *unmodulatedLocalcopy;
};

#endif // SURGE_SRC_COMMON_DSP_OSCILLATORS_WAVETABLEOSCILLATOR_H
4 changes: 2 additions & 2 deletions src/surge-testrunner/UnitTestsDSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,8 @@ TEST_CASE("Oscillator Onset", "[dsp]") // See issue 7570

oscstorage->retrigger.val.b = rt;

auto o =
spawn_osc(ot, storage, oscstorage, storage->getPatch().scenedata[0], oscbuffer);
auto o = spawn_osc(ot, storage, oscstorage, storage->getPatch().scenedata[0],
storage->getPatch().scenedataOrig[0], oscbuffer);
o->init_ctrltypes();
o->init_default_values();
o->init_extra_config();
Expand Down
3 changes: 2 additions & 1 deletion src/surge-testrunner/UnitTestsMOD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,8 @@ TEST_CASE("LFO Tempo Sync Drift in Latch Mode", "[mod]")
surge->setParameter01(rid, 0.455068, false, false);
lfostorage->shape.val.i = lt_square;

surge->storage.getPatch().copy_scenedata(surge->storage.getPatch().scenedata[0], 0);
surge->storage.getPatch().copy_scenedata(surge->storage.getPatch().scenedata[0],
surge->storage.getPatch().scenedataOrig[1], 0);

lfo->assign(&(surge->storage), lfostorage, surge->storage.getPatch().scenedata[0], nullptr,
ss.get(), nullptr, nullptr);
Expand Down
2 changes: 1 addition & 1 deletion src/surge-xt/gui/widgets/OscillatorWaveformDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ ::Oscillator *OscillatorWaveformDisplay::setupOscillator()
tp[oscdata->p[i].param_id_in_scene].i = oscdata->p[i].val.i;
}

return spawn_osc(oscdata->type.val.i, storage, oscdata, tp, oscbuffer);
return spawn_osc(oscdata->type.val.i, storage, oscdata, tp, tp, oscbuffer);
}

void OscillatorWaveformDisplay::populateMenu(juce::PopupMenu &contextMenu, int selectedItem,
Expand Down
Loading