Skip to content

Commit

Permalink
- Adds voice_id, voice_max, voice_count, is_display parameters to for…
Browse files Browse the repository at this point in the history
…mula modulator

- Fakes voice_count of "1" and sets defaults for other params on display calls
- Adds "shared" table to formula modulator
- Sets entries of "shared" table to nil on new Lua function env
- Makes formula debugger also use "shared" table
- Adds lua_isfunction to formula debugger
- Some cleanup
  • Loading branch information
nuoun committed Aug 3, 2024
1 parent 455d9af commit 72d8ba1
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 81 deletions.
11 changes: 7 additions & 4 deletions src/common/LuaSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ bool Surge::LuaSupport::setSurgeFunctionEnvironment(lua_State *L)

// List of whitelisted functions and modules
std::vector<std::string> sandboxWhitelist = {"ipairs", "error", "math", "surge", "global"};
/*
std::vector<std::string> sandboxWhitelist = {"pairs", "ipairs", "next", "print",
"error", "math", "string", "table",
"bit", "setmetatable", "surge", "shared"};
*/

for (const auto &f : sandboxWhitelist)
{
Expand Down Expand Up @@ -164,13 +169,11 @@ bool Surge::LuaSupport::setSurgeFunctionEnvironment(lua_State *L)
// stack is now f>t>(m). Pop m
lua_pop(L, 1);

// retrieve the "global" table
lua_getglobal(L, "global");
// check if the retrieved value is a table
// retrieve "shared" table and set entries to nil
lua_getglobal(L, "shared");
if (lua_istable(L, -1))
{
lua_pushnil(L);
// set table entries to nil
while (lua_next(L, -2))
{
lua_pop(L, 1); // pop value
Expand Down
2 changes: 1 addition & 1 deletion src/common/SurgeStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ class alignas(16) SurgeStorage
bool oscReceiving{false};
bool oscSending{false};

int polyCount;
int voiceCount;

bool getOverrideDataHome(std::string &value);
void createUserDirectory();
Expand Down
24 changes: 11 additions & 13 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,12 +833,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++, storage.getPatch().polylimit.val.i, host_noteid,
host_originating_key, host_originating_channel, 0.f, 0.f);
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);
}
}
break;
Expand Down Expand Up @@ -981,9 +981,8 @@ void SurgeSynthesizer::playVoice(int scene, char channel, char key, char velocit
&storage, &storage.getPatch().scene[scene],
storage.getPatch().scenedata[scene], key, velocity, channel, scene, detune,
&channelState[channel].keyState[key], &channelState[mpeMainChannel],
&channelState[channel], mpeEnabled, voiceCounter++,
storage.getPatch().polylimit.val.i, host_noteid, host_originating_key,
host_originating_channel, aegReuse, fegReuse);
&channelState[channel], mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, aegReuse, fegReuse);

if (wasGated && pkeyToReuse > 0)
{
Expand Down Expand Up @@ -1126,9 +1125,8 @@ void SurgeSynthesizer::playVoice(int scene, char channel, char key, char velocit
&storage, &storage.getPatch().scene[scene],
storage.getPatch().scenedata[scene], key, velocity, channel, scene, detune,
&channelState[channel].keyState[key], &channelState[mpeMainChannel],
&channelState[channel], mpeEnabled, voiceCounter++,
storage.getPatch().polylimit.val.i, host_noteid, host_originating_key,
host_originating_channel, aegStart, fegStart);
&channelState[channel], mpeEnabled, voiceCounter++, host_noteid,
host_originating_key, host_originating_channel, aegStart, fegStart);
}
}
else
Expand Down Expand Up @@ -4794,7 +4792,7 @@ void SurgeSynthesizer::process()

storage.modRoutingMutex.unlock();
polydisplay = vcount;
storage.polyCount = vcount;
storage.voiceCount = vcount;

// TODO: FIX SCENE ASSUMPTION
if (play_scene[0])
Expand Down
6 changes: 3 additions & 3 deletions src/common/dsp/SurgeVoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ SurgeVoice::SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *oscene, pdata *
int velocity, int channel, int scene_id, float detune,
MidiKeyState *keyState, MidiChannelState *mainChannelState,
MidiChannelState *voiceChannelState, bool mpeEnabled, int64_t voiceOrder,
int polylimit, int32_t host_nid, int16_t host_key, int16_t host_chan,
float aegStart, float fegStart)
int32_t host_nid, int16_t host_key, int16_t host_chan, float aegStart,
float fegStart)
//: fb(storage,oscene)
{
#ifdef VOICE_LIFETIME_DEBUG
Expand Down Expand Up @@ -193,7 +193,7 @@ SurgeVoice::SurgeVoice(SurgeStorage *storage, SurgeSceneStorage *oscene, pdata *
state.channel = channel;

state.voiceOrderAtCreate = voiceOrder;
state.polylimit = polylimit;
state.voiceMax = storage->getPatch().polylimit.val.i;

state.velocity = velocity;
state.fvel = velocity / 127.f;
Expand Down
2 changes: 1 addition & 1 deletion src/common/dsp/SurgeVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class alignas(16) 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, int polylimit, int32_t host_note_id,
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();
Expand Down
2 changes: 1 addition & 1 deletion src/common/dsp/SurgeVoiceState.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct SurgeVoiceState
MidiKeyState *keyState;
MidiChannelState *mainChannelState;
MidiChannelState *voiceChannelState;
int key, velocity, channel, scene_id, releasevelocity, voiceindex, polycounter, polylimit;
int key, velocity, channel, scene_id, releasevelocity, voiceMax;
float portasrc_key, portaphase;
bool porta_doretrigger;

Expand Down
121 changes: 66 additions & 55 deletions src/common/dsp/modulators/FormulaModulationHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ bool prepareForEvaluation(SurgeStorage *storage, FormulaModulatorStorage *fs, Ev

if (firstTimeThrough)
{
// setup prelude table
// setup global table
lua_newtable(s.L);
lua_setglobal(s.L, "shared");

// setup prelude
Surge::LuaSupport::loadSurgePrelude(s.L);
auto reserved0 = std::string(R"FN(
function surge_reserved_formula_error_stub(m)
Expand All @@ -95,9 +99,6 @@ end
{
lua_setglobal(s.L, "surge_reserved_formula_error_stub");
}
// setup global table
lua_newtable(s.L);
lua_setglobal(s.L, "global");
}

// OK so now evaluate the formula. This is a mistake - the loading and
Expand Down Expand Up @@ -234,6 +235,7 @@ end
addn("tempo", s.tempo);
addn("songpos", s.songpos);
addb("released", s.released);
addb("is_display", s.is_display);
addb("clamp_output", true);

auto cres = lua_pcall(s.L, 1, 1, 0);
Expand Down Expand Up @@ -368,12 +370,16 @@ end
s.h = 0;
s.r = 0;
s.s = 0;

s.rate = 0;
s.phase = 0;
s.amp = 0;
s.deform = 0;
s.tempo = 120;

if (is_display)
s.is_display = true;

if (s.raisedError)
std::cout << "ERROR: " << *(s.error) << std::endl;
#endif
Expand Down Expand Up @@ -456,6 +462,7 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,
std::string fn;
bool replace = true;
} onerr(s->L, s->funcName);

/*
* So: make the stack my evaluation func then my table; then push my table
* values; then call my function; then update my global
Expand All @@ -469,12 +476,6 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,
}
lua_getglobal(s->L, s->stateName);

/*
lua_pushstring(s->L, "av");
lua_gettable(s->L, -2);
lua_pop(s->L, 1);
*/

// Stack is now func > table so we can update the table
lua_pushinteger(s->L, phaseIntPart);
lua_setfield(s->L, -2, "intphase");
Expand All @@ -483,8 +484,12 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,
lua_pushinteger(s->L, phaseIntPart);
lua_setfield(s->L, -2, "cycle");

lua_pushinteger(s->L, storage->polyCount);
lua_setfield(s->L, -2, "voice_poly");
// fake voice count for display calls
int vcount = 1;
if (storage->voiceCount != 0)
vcount = storage->voiceCount;
lua_pushinteger(s->L, vcount);
lua_setfield(s->L, -2, "voice_count");

auto addn = [s](const char *q, float f) {
lua_pushnumber(s->L, f);
Expand All @@ -501,33 +506,24 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,
lua_setfield(s->L, -2, q);
};

addn("phase", phaseFracPart);
addn("delay", s->del);
addn("decay", s->dec);
addn("attack", s->a);
addn("hold", s->h);
addn("sustain", s->s);
addn("release", s->r);

if (true /* s->subLfoEnvelope */)
{
addn("delay", s->del);
addn("decay", s->dec);
addn("attack", s->a);
addn("hold", s->h);
addn("sustain", s->s);
addn("release", s->r);
}
if (true /* s->subLfoParams */)
{
addn("rate", s->rate);
addn("amplitude", s->amp);
addn("startphase", s->phase);
addn("deform", s->deform);
}
addn("rate", s->rate);
addn("amplitude", s->amp);
addn("startphase", s->phase);
addn("deform", s->deform);

if (true /* s->subTiming */)
{
addn("tempo", s->tempo);
addn("songpos", s->songpos);
addb("released", s->released);
}
addn("phase", phaseFracPart);
addn("tempo", s->tempo);
addn("songpos", s->songpos);
addb("released", s->released);

if (/* s->subVoice && */ s->isVoice)
if (s->isVoice)
{
addb("is_voice", s->isVoice);
addn("key", s->key);
Expand All @@ -536,9 +532,8 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,
addn("channel", s->channel);
addb("released", s->released);

addn("voice_order", s->voice_order);
addn("voice_index", s->voice_index);
addn("voice_limit", s->voice_limit);
addn("voice_id", s->voiceid);
addn("voice_max", s->voicemax);

addn("poly_at", s->polyat);
addn("mpe_bend", s->mpebend);
Expand All @@ -553,6 +548,7 @@ void valueAt(int phaseIntPart, float phaseFracPart, SurgeStorage *storage,

addnil("retrigger_AEG");
addnil("retrigger_FEG");
addb("is_display", s->is_display);

if (s->subAnyMacro)
{
Expand Down Expand Up @@ -731,13 +727,7 @@ std::vector<DebugRow> createDebugDataOfModState(const EvaluatorState &es)
#if HAS_LUA
std::vector<DebugRow> rows;
Surge::LuaSupport::SGLD guard("debugViewGuard", es.L);
lua_getglobal(es.L, es.stateName);
if (!lua_istable(es.L, -1))
{
lua_pop(es.L, -1);
rows.emplace_back(0, "Error", "Not a Table");
return rows;
}

std::function<void(const int, bool)> rec;
rec = [&rows, &es, &rec](const int depth, bool internal) {
Surge::LuaSupport::SGLD guardR("rec[" + std::to_string(depth) + "]", es.L);
Expand Down Expand Up @@ -783,10 +773,6 @@ std::vector<DebugRow> createDebugDataOfModState(const EvaluatorState &es)
{
rows.emplace_back(depth, lab, lua_tostring(es.L, -1));
}
else if (lua_isnil(es.L, -1))
{
rows.emplace_back(depth, lab, "(nil)");
}
else if (lua_isboolean(es.L, -1))
{
rows.emplace_back(depth, lab, (lua_toboolean(es.L, -1) ? "true" : "false"));
Expand All @@ -798,12 +784,23 @@ std::vector<DebugRow> createDebugDataOfModState(const EvaluatorState &es)
rows.back().isInternal = internal;
rec(depth + 1, internal);
}
else if (lua_isfunction(es.L, -1))
{
rows.emplace_back(depth, lab, "(function)");
rows.back().isInternal = internal;
}
else if (lua_isnil(es.L, -1))
{
rows.emplace_back(depth, lab, "(nil)");
rows.back().isInternal = internal;
}
else
{
rows.emplace_back(depth, lab, "(unknown)");
rows.back().isInternal = internal;
}
rows.back().isInternal = internal;
};

for (auto k : ikeys)
{
std::ostringstream oss;
Expand All @@ -823,13 +820,26 @@ std::vector<DebugRow> createDebugDataOfModState(const EvaluatorState &es)
}
};

rec(0, false);
lua_pop(es.L, -1);
std::vector<std::string> tablesList = {es.stateName, "shared"};
for (const auto &t : tablesList)
{
lua_getglobal(es.L, t.c_str());
if (!lua_istable(es.L, -1))
{
lua_pop(es.L, -1);
rows.emplace_back(0, "Error", "Not a Table");
return rows;
}
rec(0, false);
lua_pop(es.L, -1);
}

return rows;
#else
return {};
#endif
}

std::string createDebugViewOfModState(const EvaluatorState &es)
{
auto r = createDebugDataOfModState(es);
Expand Down Expand Up @@ -898,15 +908,16 @@ void setupEvaluatorStateFrom(EvaluatorState &s, const SurgePatch &patch, int sce
s.highest_key = scene.modsources[ms_highest_key]->get_output(0);
s.latest_key = scene.modsources[ms_latest_key]->get_output(0);
}

void setupEvaluatorStateFrom(EvaluatorState &s, const SurgeVoice *v)
{
s.key = v->state.key;
s.channel = v->state.channel;
s.velocity = v->state.velocity;
s.releasevelocity = v->state.releasevelocity;

s.voice_order = v->state.voiceOrderAtCreate;
s.voice_limit = v->state.polylimit;
s.voiceid = v->state.voiceOrderAtCreate;
s.voicemax = v->state.voiceMax;

s.polyat =
v->storage
Expand Down
7 changes: 4 additions & 3 deletions src/common/dsp/modulators/FormulaModulationHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ struct EvaluatorState

bool retrigger_AEG, retrigger_FEG;

bool is_display = false;

// voice features
bool isVoice;
int key{60}, channel{0}, velocity{0}, releasevelocity{0}, voice_index{0}, voice_limit{0},
mpebendrange{24};
int64_t voice_order{0};
int key{60}, channel{0}, velocity{0}, releasevelocity{0}, voicemax{1}, mpebendrange{24};
int64_t voiceid{1L};
float polyat{0}, mpebend{0}, mpetimbre{0}, mpepressure{0};

// scene features
Expand Down

0 comments on commit 72d8ba1

Please sign in to comment.