Skip to content

Commit

Permalink
Splits prelude into WTSE/Formula and adds it to WTSE
Browse files Browse the repository at this point in the history
  • Loading branch information
nuoun committed Aug 17, 2024
1 parent 4bf7265 commit 104da33
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 32 deletions.
35 changes: 23 additions & 12 deletions src/common/LuaSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ bool Surge::LuaSupport::setSurgeFunctionEnvironment(lua_State *L)
lua_setfield(L, eidx, "print");

// add global tables
lua_getglobal(L, "surge");
lua_setfield(L, eidx, "surge");
lua_getglobal(L, "shared");
lua_setfield(L, eidx, "shared");
lua_getglobal(L, surgeTableName);
lua_setfield(L, eidx, surgeTableName);
lua_getglobal(L, sharedTableName);
lua_setfield(L, eidx, sharedTableName);

// add whitelisted functions and modules
std::vector<std::string> sandboxWhitelist = {"pairs", "ipairs", "unpack",
Expand Down Expand Up @@ -271,21 +271,32 @@ bool Surge::LuaSupport::setSurgeFunctionEnvironment(lua_State *L)
return true;
}

bool Surge::LuaSupport::loadSurgePrelude(lua_State *s, const char *surgeTableName)
bool Surge::LuaSupport::loadSurgePrelude(lua_State *L, const std::string &lua_script)
{
#if HAS_LUA
auto guard = SGLD("loadPrologue", s);
// now load the surge library
auto &lua_script = LuaSources::surge_prelude;
auto guard = SGLD("loadSurgePrelude", L);
// Load the specified Lua script into the global table "surge"
auto lua_size = lua_script.size();
auto load_stat = luaL_loadbuffer(s, lua_script.c_str(), lua_size, lua_script.c_str());
auto pcall = lua_pcall(s, 0, 1, 0);
lua_setglobal(s, surgeTableName);
auto status = luaL_loadbuffer(L, lua_script.c_str(), lua_size, lua_script.c_str());
if (status != 0)
{
std::cout << "Error: Failed to load Lua file [ " << lua_script.c_str() << " ]" << std::endl;
return false;
}
auto pcall = lua_pcall(L, 0, 1, 0);
if (pcall != 0)
{
std::cout << "Error: Failed to run Lua file [ " << lua_script.c_str() << " ]" << std::endl;
return false;
}
lua_setglobal(L, surgeTableName);
#endif
return true;
}

std::string Surge::LuaSupport::getSurgePrelude() { return LuaSources::surge_prelude; }
std::string Surge::LuaSupport::getFormulaPrelude() { return LuaSources::formula_prelude; }

std::string Surge::LuaSupport::getWTSEPrelude() { return LuaSources::wtse_prelude; }

Surge::LuaSupport::SGLD::~SGLD()
{
Expand Down
21 changes: 16 additions & 5 deletions src/common/LuaSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,20 @@ int parseStringDefiningMultipleFunctions(lua_State *s, const std::string &defini
bool setSurgeFunctionEnvironment(lua_State *s);

/*
* Call this function with a LUA state and a tablename and it will introduce the global
* 'surge' which is the surge prelude
* Call this function with a LUA state, the std::string at Surge::LuaSources and it will load the
* prelude in the table "surge"
*/
bool loadSurgePrelude(lua_State *s, const char *surgeTableName);
bool loadSurgePrelude(lua_State *s, const std::string &lua_script);

/*
* Call this function to get a string representation of the prelude
* Call this function to get a string representation of the Formula prelude
*/
std::string getSurgePrelude();
std::string getFormulaPrelude();

/*
* Call this function to get a string representation of the WTSE prelude
*/
std::string getWTSEPrelude();

/*
* A little leak debugger. Make this on your stack and if you exit the
Expand All @@ -118,6 +123,12 @@ struct SGLD
int top;
};

/*
* Global table names
*/
static constexpr const char *surgeTableName{"surge"};
static constexpr const char *sharedTableName{"shared"};

} // namespace LuaSupport
} // namespace Surge

Expand Down
5 changes: 5 additions & 0 deletions src/common/dsp/WavetableScriptEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "WavetableScriptEvaluator.h"
#include "LuaSupport.h"
#include "lua/LuaSources.h"

namespace Surge
{
Expand All @@ -42,6 +43,10 @@ std::vector<float> evaluateScriptAtFrame(SurgeStorage *storage, const std::strin
auto values = std::vector<float>();

auto wg = Surge::LuaSupport::SGLD("WavetableScript::evaluate", L);

// Load the WTSE prelude
Surge::LuaSupport::loadSurgePrelude(L, Surge::LuaSources::wtse_prelude);

std::string emsg;
auto res = Surge::LuaSupport::parseStringDefiningFunction(L, eqn.c_str(), "generate", emsg);
if (res)
Expand Down
8 changes: 5 additions & 3 deletions src/common/dsp/modulators/FormulaModulationHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <thread>
#include <functional>
#include "fmt/core.h"
#include "lua/LuaSources.h"

namespace Surge
{
Expand Down Expand Up @@ -81,12 +82,13 @@ bool prepareForEvaluation(SurgeStorage *storage, FormulaModulatorStorage *fs, Ev

if (firstTimeThrough)
{
// setup shared table
// Setup shared table
lua_newtable(s.L);
lua_setglobal(s.L, sharedTableName);

// setup prelude
Surge::LuaSupport::loadSurgePrelude(s.L, surgeTableName);
// Load the Formula prelude
Surge::LuaSupport::loadSurgePrelude(s.L, Surge::LuaSources::formula_prelude);

auto reserved0 = std::string(R"FN(
function surge_reserved_formula_error_stub(m)
return 0;
Expand Down
1 change: 0 additions & 1 deletion src/common/dsp/modulators/FormulaModulationHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ struct GlobalData
};

static constexpr int max_formula_outputs{max_lfo_indices};
static constexpr const char *surgeTableName{"surge"};
static constexpr const char *sharedTableName{"shared"};

struct EvaluatorState
Expand Down
12 changes: 7 additions & 5 deletions src/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ project(surge-lua-src)
# 1. Create myscript.lua
# 2. Add it to the list below
# 3. myscript.lua is now a std::string at Surge::LuaSources::myscript

set(lua_sources
surge_prelude.lua
surge_prelude_test.lua
)
formula_prelude.lua
formula_prelude_test.lua
wtse_prelude.lua
)

set(generated_sources
${CMAKE_CURRENT_BINARY_DIR}/LuaSources.cpp
${CMAKE_CURRENT_BINARY_DIR}/include/lua/LuaSources.h
)
)

add_library(${PROJECT_NAME} ${generated_sources})

add_custom_command(OUTPUT ${generated_sources}
COMMAND ${CMAKE_COMMAND} -P lua2cpp.cmake ${CMAKE_CURRENT_BINARY_DIR} LuaSources.cpp lua/LuaSources.h Surge::LuaSources ${lua_sources}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS lua2cpp.cmake ${lua_sources}
)
)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include)
File renamed without changes.
File renamed without changes.
118 changes: 118 additions & 0 deletions src/lua/wtse_prelude.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
-- This document is loaded in each Surge XT session and provides a set of built-in helpers
-- we've found handy when generating wavetables. Consider it as a library of functions.
-- For each official update of Surge XT we will freeze the state of the prelude as stable
-- and not break included functions after that.
--
-- If you have ideas for other useful functions that could be added here, by all means
-- contact us over GitHub or Discord and let us know!


local surge = {}


--- MATH FUNCTIONS ---


-- parity function returns 0 for even numbers and 1 for odd numbers
function math.parity(x)
return (x % 2 == 1 and 1) or 0
end

-- signum function returns -1 for negative numbers, 0 for zero, 1 for positive numbers
function math.sgn(x)
return (x > 0 and 1) or (x < 0 and -1) or 0
end

-- sign function returns -1 for negative numbers and 1 for positive numbers or zero
function math.sign(x)
return (x < 0 and -1) or 1
end

-- linearly interpolates value from in range to out range
function math.rescale(value, in_min, in_max, out_min, out_max)
return (((value - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min
end

-- returns the norm of the two components (hypotenuse)
function math.norm(a, b)
return math.sqrt(a ^ 2 + b ^ 2)
end

-- returns the absolute range between the two numbers
function math.range(a, b)
return math.abs(a - b)
end


-- WTSE MATH FUNCTIONS - NON-FINAL AND WIP


-- returns a table with the cumulative product of the elements in the input table
function math.cumprod(t)
local o = {}
o[1] = t[1]
for i = 2, #t do
o[i] = o[i - 1] * t[i]
end
return o
end

-- returns a table with the cumulative sum of the elements in the input table
function math.cumsum(t)
local o = {}
o[1] = t[1]
for i = 2, #t do
o[i] = o[i - 1] + t[i]
end
return o
end

-- returns a table containing num_points linearly spaced numbers from start_point to end_point
function math.linspace(start_point, end_point, num_points)
local t = {}
local step = (end_point - start_point) / (num_points - 1)
for i = 1, num_points do
t[i] = start_point + (i - 1) * step
end
return t
end

-- returns a table containing num_points logarithmically spaced numbers from 10^start_point to 10^end_point
function math.logspace(start_point, end_point, num_points)
local t = {}
local step = (end_point - start_point) / (num_points - 1)
for i = 1, num_points do
local exponent = start_point + (i - 1) * step
t[i] = 10 ^ exponent
end
return t
end

-- returns the maximum absolute value found in the input table
function math.maxAbsFromTable(t)
local o = 0
for i = 1, #t do
local a = abs(t[i])
if a > o then o = a end
end
return o
end

-- returns the normalized sinc function for a table of input values
function math.sinc(t)
local o = {}
for i, x in ipairs(t) do
if x == 0 then
o[i] = 1
else
o[i] = math.sin(math.pi * x) / (math.pi * x)
end
end
return o
end


--- END ---


return surge
5 changes: 2 additions & 3 deletions src/surge-testrunner/UnitTestsLUA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,11 @@ TEST_CASE("Surge Prelude", "[lua]")
REQUIRE(L);
luaL_openlibs(L);

static constexpr const char *surgeTableName{"surge"};
REQUIRE(Surge::LuaSupport::loadSurgePrelude(L, surgeTableName));
REQUIRE(Surge::LuaSupport::loadSurgePrelude(L, Surge::LuaSources::formula_prelude));

std::string emsg;
REQUIRE(Surge::LuaSupport::parseStringDefiningFunction(
L, Surge::LuaSources::surge_prelude_test, "test", emsg));
L, Surge::LuaSources::formula_prelude_test, "test", emsg));
Surge::LuaSupport::setSurgeFunctionEnvironment(L);

auto pcall = lua_pcall(L, 0, 1, 0);
Expand Down
5 changes: 2 additions & 3 deletions src/surge-xt/gui/overlays/LuaEditors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ FormulaModulatorEditor::FormulaModulatorEditor(SurgeGUIEditor *ed, SurgeStorage
mainDocument->insertText(0, fs->formulaString);

preludeDocument = std::make_unique<juce::CodeDocument>();
preludeDocument->insertText(0, Surge::LuaSupport::getSurgePrelude());
preludeDocument->insertText(0, Surge::LuaSupport::getFormulaPrelude());

preludeDisplay = std::make_unique<SurgeCodeEditorComponent>(*preludeDocument, tokenizer.get());
preludeDisplay->setTabSize(4, true);
Expand Down Expand Up @@ -1282,9 +1282,8 @@ WavetableScriptEditor::WavetableScriptEditor(SurgeGUIEditor *ed, SurgeStorage *s
mainDocument->insertText(0, osc->wavetable_formula);
}

// FIXME: split prelude into Formula and WTSE
preludeDocument = std::make_unique<juce::CodeDocument>();
preludeDocument->insertText(0, Surge::LuaSupport::getSurgePrelude());
preludeDocument->insertText(0, Surge::LuaSupport::getWTSEPrelude());

preludeDisplay = std::make_unique<SurgeCodeEditorComponent>(*preludeDocument, tokenizer.get());
preludeDisplay->setTabSize(4, true);
Expand Down

0 comments on commit 104da33

Please sign in to comment.