Browse Source

Implements a copy of the ProccessBlock that is used to provide 1-based indices in the Lua VM and keep the speed of the FFI

tags/v1.3.0
Leonardo Laguna Ruiz Andrew Belt 5 years ago
parent
commit
909d5d7241
1 changed files with 48 additions and 14 deletions
  1. +48
    -14
      src/LuaJITEngine.cpp

+ 48
- 14
src/LuaJITEngine.cpp View File

@@ -27,11 +27,22 @@ LUALIB_API void custom_openlibs(lua_State *L)
struct LuaJITEngine : ScriptEngine {
lua_State* L = NULL;

struct SafeArray {
void* p;
size_t len;
// This is a mirror of ProcessBlock that we are going to use
// to provide 1-based indices within the Lua VM
struct LuaProcessBlock {
float sampleRate;
float sampleTime;
int bufferSize;
float* inputs[NUM_ROWS+1];
float* outputs[NUM_ROWS+1];
float* knobs;
bool* switches;
float* lights[NUM_ROWS+1];
float* switchLights[NUM_ROWS+1];
};

LuaProcessBlock block;

~LuaJITEngine() {
if (L)
lua_close(L);
@@ -42,7 +53,22 @@ struct LuaJITEngine : ScriptEngine {
}

int run(const std::string& path, const std::string& script) override {
ProcessBlock* block = getProcessBlock();
ProcessBlock* original_block = getProcessBlock();

block.sampleRate = original_block->sampleRate;
block.sampleTime = original_block->sampleTime;
block.bufferSize = original_block->bufferSize;

// Initialize all the pointers with an offset of -1
block.knobs = (float*)&(original_block->knobs[-1]);
block.switches = (bool*)&(original_block->switches[-1]);

for(int i = 1; i < NUM_ROWS + 1; i++) {
block.inputs[i] = (float*)&(original_block->inputs[i-1][-1]);
block.outputs[i] = (float*)&(original_block->outputs[i-1][-1]);
block.lights[i] = (float*)&(original_block->lights[i-1][-1]);
block.switchLights[i] = (float*)&(original_block->switchLights[i-1][-1]);
}

L = luaL_newstate();
if (!L) {
@@ -80,20 +106,21 @@ struct LuaJITEngine : ScriptEngine {
std::stringstream ffi_stream;
ffi_stream
<< "local ffi = require('ffi')" << std::endl
// Describes the struct 'ProcessBlock' that way LuaJIT knows how to access the data
// Describes the struct 'LuaProcessBlock' that way LuaJIT knows how to access the data
<< "ffi.cdef[[" << std::endl
<< "struct ProcessBlock {" << std::endl
<< "struct LuaProcessBlock {" << std::endl
<< "float sampleRate;" << std::endl
<< "float sampleTime;" << std::endl
<< "int bufferSize;" << std::endl
<< "float inputs[" << NUM_ROWS << "][" << MAX_BUFFER_SIZE << "];" << std::endl
<< "float outputs[" << NUM_ROWS << "][" << MAX_BUFFER_SIZE << "];" << std::endl
<< "float knobs[" << NUM_ROWS << "];" << std::endl
<< "bool switches[" << NUM_ROWS << "];" << std::endl
<< "float lights[" << NUM_ROWS << "][3];" << std::endl
<< "float switchLights[" << NUM_ROWS << "][3];};]]" << std::endl
<< "float *inputs[" << NUM_ROWS + 1 << "];" << std::endl
<< "float *outputs[" << NUM_ROWS + 1 << "];" << std::endl
<< "float *knobs;" << std::endl
<< "bool *switches;" << std::endl
<< "float *lights[" << NUM_ROWS + 1 << "];" << std::endl
<< "float *switchLights[" << NUM_ROWS + 1 << "];" << std::endl
<<"};]]" << std::endl
// Declares the function 'castBlock' used to transform the 'block' pointer into a LuaJIT cdata
<< "function castBlock(b) return ffi.cast('struct ProcessBlock*', b) end";
<< "function castBlock(b) return ffi.cast('struct LuaProcessBlock*', b) end";
std::string ffi_script = ffi_stream.str();

// Compile the ffi script
@@ -157,7 +184,7 @@ struct LuaJITEngine : ScriptEngine {

// Create block object
lua_getglobal(L, "castBlock");
lua_pushlightuserdata(L, (void *)block);
lua_pushlightuserdata(L, (void *)&block);
if (lua_pcall(L, 1, 1, 0) != 0)
printf("error running function 'castBlock': %s", lua_tostring(L, -1));

@@ -165,6 +192,13 @@ struct LuaJITEngine : ScriptEngine {
}

int process() override {
ProcessBlock* original_block = getProcessBlock();

// Update the values of the block (the pointers should not change)
block.sampleRate = original_block->sampleRate;
block.sampleTime = original_block->sampleTime;
block.bufferSize = original_block->bufferSize;

// Duplicate process function
lua_pushvalue(L, -2);
// Duplicate block


Loading…
Cancel
Save