Skip to content

Commit

Permalink
impl lua mod/functions context
Browse files Browse the repository at this point in the history
  • Loading branch information
samba committed Jul 16, 2024
1 parent 6b280dd commit 2e29fb0
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 113 deletions.
58 changes: 58 additions & 0 deletions examples/lua/devices/integra7/integra7.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
-- <command name="integra7" where="mod" using="lua/devices/integra7/integra7.lua">
-- creates integra7 parameter sysex messages
-- </command>
-- <param name="parameterId" optional="0" type="string">the parameter (node) id. As placeholder for the partId can `xxx` be used. For exampe `PRM-_PRF-_FPxxx-NEFP_OUT_ASGN`</param>
-- <param name="value" optional="0" type="number|string">the value</param>
-- <param name="partId" optional="1" type="0..15">specifies the part id. If not set, will be determined using its related instrument channel(s), assuming that the channel never changes.</param>


require "/lua/devices/integra7/_model"
require "lua/com/com"

parameters = {
-- { name="parameterId"},
-- { name="value"},
-- { name="partId", default=-1 },
}

local function get_partids(params)
if params.partIdsFromInstrument ~= nil then
return params.partIdsFromInstrument
end
if isnumber(params.partId) then
return { tonumber(params.partId) }
end
local function get_id_from_instrument()

end
end

function execute(params, timeinfo)
local part_ids = get_partids(params);
local value = tonumber(params.value)
local node_id = string.format(NODE_ID_TEMPLATE, part_nr)

local nodeinfo = Get_Node(node_id)
if nodeinfo == nil then
error("no node found for id:" .. node_id)
end
nodeinfo.node:setvalue(value)
local sysex = Create_SysexMessage(nodeinfo)
return {
{
["type"] = "sysex",
["sysexData"] = sysex,
}
}
end

local function get_partids_from_instrument(events)

end

function perform(events, params, timeinfo)
params.partIdsFromInstrument = get_partids_from_instrument(events)
local midiMessage = execute(params, timeinfo)
table.insert(events, midiMessage[1])
return events
end
35 changes: 20 additions & 15 deletions manual.in.md
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ function perform(events, params, timeinfo)
end
```

The perform function has 3 arguments:
The perform function has 4 arguments:

### `events` argument
This table contains all input events.
Expand Down Expand Up @@ -1059,20 +1059,7 @@ This table contains all input events.

-- a table of byte values (excluding F0 and F7)
-- only relevant if type is "sysex"
sysexData = { byte values },

-- some information about the related instrument
instrument = {
name = string,
pan = 0..100,
volume = 0..100,
midiChannel = 0..15, -- optional
midiLsb = 0..127, -- optional
midiMsb = 0..127, -- optional
midiPc = 0..127, -- optional
children: {} -- further instrument children see instrumentSection (https://www.werckme.org/manual#instrumentsection)
}

sysexData = { byte values }
}
...
}
Expand All @@ -1096,6 +1083,24 @@ Contains a table with informations about the current musical time.
}
```

### `context` argument
Contains an interface with some context related functions.

#### getCurrentInstrument
returns information about the current instrument
```lua
{
name = string,
pan = 0..100,
volume = 0..100,
midiChannel = 0..15, -- optional
midiLsb = 0..127, -- optional
midiMsb = 0..127, -- optional
midiPc = 0..127, -- optional
children: {} -- further instrument children see instrumentSection (https://www.werckme.org/manual#instrumentsection)
}
```

### return value
Returns a table containing events. See [events](#events-argument)

Expand Down
35 changes: 20 additions & 15 deletions manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ function perform(events, params, timeinfo)
end
```

The perform function has 3 arguments:
The perform function has 4 arguments:

### `events` argument
This table contains all input events.
Expand Down Expand Up @@ -1059,20 +1059,7 @@ This table contains all input events.

-- a table of byte values (excluding F0 and F7)
-- only relevant if type is "sysex"
sysexData = { byte values },

-- some information about the related instrument
instrument = {
name = string,
pan = 0..100,
volume = 0..100,
midiChannel = 0..15, -- optional
midiLsb = 0..127, -- optional
midiMsb = 0..127, -- optional
midiPc = 0..127, -- optional
children: {} -- further instrument children see instrumentSection (https://www.werckme.org/manual#instrumentsection)
}

sysexData = { byte values }
}
...
}
Expand All @@ -1096,6 +1083,24 @@ Contains a table with informations about the current musical time.
}
```

### `context` argument
Contains an interface with some context related functions.

#### getCurrentInstrument
returns information about the current instrument
```lua
{
name = string,
pan = 0..100,
volume = 0..100,
midiChannel = 0..15, -- optional
midiLsb = 0..127, -- optional
midiMsb = 0..127, -- optional
midiPc = 0..127, -- optional
children: {} -- further instrument children see instrumentSection (https://www.werckme.org/manual#instrumentsection)
}
```

### return value
Returns a table containing events. See [events](#events-argument)

Expand Down
25 changes: 25 additions & 0 deletions rendertests/tests/eventFunctionInstrumentinfo.sheet
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

using "./modinstrumentinfo.lua";

device: _setName=MyDevice _isType=midi _useDevice="FLUID Synth";
instrumentDef: _setName=piano _onDevice=MyDevice _ch=0 _pc=1 _cc=8;

instrumentDef: _setName=p1 _onDevice=MyDevice _ch=1 _pc=100;
instrumentDef: _setName=p2 _onDevice=MyDevice _ch=2 _pc=12;
instrumentSection: mySection p1 p2;

[
instrument: piano;
{
/call: modinstrumentinfo/
c d e f | g a b c'
}
]

[
instrument: mySection;
{
/call: modinstrumentinfo/
c, d, e, f, | g, a, b, c
}
]
30 changes: 30 additions & 0 deletions rendertests/tests/integra7-instrumentDef.sheet
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using "/chords/default.chords";
using "../../examples/lua/devices/integra7/integra7.lua";
using "../../examples/lua/mods/myArpeggio.lua";

tempo: 150;
device: MyDevice midi _useDevice="DIN 3";
instrumentDef:guitar _onDevice=MyDevice _pc=0 _ch=6 _bankMsb=89 _bankLsb=64 _pc=97;
instrumentConf: guitar
mod myArpeggio
mod integra7
;

[
type: template;
name: chords;
instrument: guitar;
{
<II III V VII I>1 :(x3)
|:
<I II III V VII>1 :(x3)|
}
]

[
type: accomp;
{
/template: chords/
C | F | G7 :|
}
]
19 changes: 16 additions & 3 deletions rendertests/tests/modinstrumentinfo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ local function checkinstrument (instrument)
if instrument.name == nil then
return false
end
if #instrument.name == 0 then
return false
end
if instrument.children ~= nil then
for _, child in pairs(instrument.children) do
return checkinstrument(child)
Expand All @@ -18,9 +21,19 @@ local function checkinstrument (instrument)
return true
end

function perform(events, params, timeinfo)
if checkinstrument(events[1].instrument) == false then
return {}
function perform(events, params, timeinfo, context)
local instrument = context:getCurrentInstrument()
if checkinstrument(instrument) == false then
error("instrument check failed")
end
return events
end

function execute(params, timeinfo, context)
local instrument = context:getCurrentInstrument()
dump(instrument)
if checkinstrument(instrument) == false then
error("instrument check failed")
end
return {}
end
2 changes: 1 addition & 1 deletion rendertests/tests/modinstrumentinfo.sheet
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ instrument: mySection;
/mod: modinstrumentinfo/
c, d, e, f, | g, a, b, c
}
]
]
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ SET (SRC_FETZER_LIB
compiler/SheetNavigator.cpp
compiler/EventInformationServer.cpp
compiler/lua/luaTimeInfo.cpp
compiler/lua/luaContext.cpp
documentModel/objects/Event.cpp
documentModel/objects/ChordDef.cpp
documentModel/objects/Track.cpp
Expand Down
101 changes: 101 additions & 0 deletions src/compiler/lua/luaContext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "luaContext.h"
#include <lua.hpp>
#include <compiler/context/IContext.h>
#include <compiler/Instrument.h>

static const char *LUA_CONTEXT_PROPETRY_CURRENT_INSTRUMENT = "getCurrentInstrument";
static const char *LUA_EVENT_PROPETRY_INSTRUMENT = "instrument";
static const char *LUA_INSTRUMENT_PROPERTY_CHILDREN = "children";
static const char *LUA_INSTRUMENT_PROPERTY_NAME = "name";
static const char *LUA_INSTRUMENT_PROPERTY_VOLUME = "volume";
static const char *LUA_INSTRUMENT_PROPERTY_PAN = "pan";
static const char *LUA_INSTRUMENT_PROPERTY_MIDI_CHANNEL = "midiChannel";
static const char *LUA_INSTRUMENT_PROPERTY_MIDI_MSB = "midiMsb";
static const char *LUA_INSTRUMENT_PROPERTY_MIDI_LSB = "midiLsb";
static const char *LUA_INSTRUMENT_PROPERTY_MIDI_PC = "midiPc";

namespace lua
{

static void pushInstrument(lua_State *L, compiler::IContext &ctx, compiler::AInstrumentDefPtr instrument)
{
lua_createtable(L, 4, 0);
if (!instrument)
{
return;
}
auto top = lua_gettop(L);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_NAME);
lua_pushstring(L, instrument->uname.c_str());
lua_settable(L, top);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_VOLUME);
lua_pushnumber(L, instrument->volume);
lua_settable(L, top);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_PAN);
lua_pushnumber(L, instrument->pan);
lua_settable(L, top);
//
auto instrumentSection = std::dynamic_pointer_cast<compiler::InstrumentSectionDef>(instrument);
if (instrumentSection)
{
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_CHILDREN);
lua_createtable(L, instrumentSection->instrumentNames.size(), 0);
auto childrenTop = lua_gettop(L);
int index = 1;
for (const auto &uname : instrumentSection->instrumentNames)
{
auto instrumentDef = ctx.getInstrumentDef(uname);
lua_pushinteger(L, index++);
pushInstrument(L, ctx, instrumentDef);
lua_settable(L, childrenTop);
}
lua_settable(L, top);
return;
}
//
auto midiInstrument = std::dynamic_pointer_cast<compiler::MidiInstrumentDef>(instrument);
if (!midiInstrument)
{
return;
}
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_MIDI_CHANNEL);
lua_pushinteger(L, midiInstrument->channel);
lua_settable(L, top);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_MIDI_MSB);
lua_pushinteger(L, midiInstrument->bankMsb);
lua_settable(L, top);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_MIDI_LSB);
lua_pushinteger(L, midiInstrument->bankLsb);
lua_settable(L, top);
//
lua_pushstring(L, LUA_INSTRUMENT_PROPERTY_MIDI_PC);
lua_pushinteger(L, midiInstrument->pc);
lua_settable(L, top);
}

static int getCurrentInstrument(lua_State *L)
{
using namespace lua;
auto luaContext = ALuaObject::getObject<LuaContext>(L, -1);
auto top = lua_gettop(L);
// instrument
auto& context = luaContext->context;
auto instrument = context.currentInstrumentDef();
pushInstrument(L, context, instrument);
return 1;
}

static const luaL_Reg libfs[] = {
{"getCurrentInstrument", getCurrentInstrument},
{NULL, NULL}};

void LuaContext::push(lua_State *L)
{
Base::push(L, libfs, 1);
}
}
Loading

0 comments on commit 2e29fb0

Please sign in to comment.