AZ Lua APII recommend at least read some chapters from the book about
Lua programming language. You can find the link at
www.lua.org. In case you have already installed AZ Lua and want try to reproduce some examples - you have Lua interpreter already! AZ Lua has Lua 5.3.2 interpreter build-in. You do not event forced to leave Sonar
It is very good idea to start each your preset with Lua multi-line style comment, like:
--[[ The is my dummy preset ]]--
The text will be displayed in the User mode, so everyone can get an idea what that preset is doing without looking into the "code".
When Lua program is loaded from preset/project or "Appliy"ed in UI, it is executed once. During that execution it should define 2 global function:
In addition, the program can define 3 additional functions to be called on corresponding transport changes:
The last one can be important in case of dynamic functionality change, for example attempting to restore default/previous state.
Also you program can define (global) table "GUI" (see later).
ANY error (you can see then in the Output section of UI) during initial execution or these functions calls immediately disable your FX. And the plug-in start to work as disabled (everything goes throw unchanged). The same happens in case you have some valid Lua program but you have not defined these functions.
Notice Till you have pressed "Apply" button (so set the program as MFX), your code exists in UI only. If you close UI (or close the project) your changes WILL NOT be saved. Also till "Apply" is pressed, there is no "Project is modified" indication in Sonar. The MFX code currently working is still the same when you have just modified something in the editor, so logically there is no changed is the MIDI processing and so there is no changes in the project.
Till you start to do some "advanced" programming, OnEvents can stay (verbatim) as:
OnEvents = function ( From, To, pqIn, pqOut)
OnInput(pqIn, pqOut)
end
and then you need only one function, OnInput.
Just to finish with "OnEvents": "To" and "From" parameters define the time period in MIDI Ticks for which this function is called.
pqIn and pqOutThere are called such way to mimic original API, with the meaning "the pointer to the Input Queue" and "the pointer to the Output Queue". Pointers make no big sense in Lua, but I have decided to keep the prefix "p". Note that you can rename both, there are just "the first" and "the second" parameters.
Both parameters are Lua Tables. But with a helper method "add". You can create your own queues by calling "MfxQueue.new()" method defined by AZ Lua API. More formal:
There is global object (table)
MfxQueue with one single method
new which returns an empty table with one defined method
add(event,....). This method add a COPY of arguments into the table IF AND ONLY IF they are of type "MfxEvent". So, if you call "pqOut.add(x)" with anything except MfxEvent, nothing will happened (without errors, that is handy for filtering).
pqIn is the Input table. It contains MfxEvent(s) provided by Sonar on input, with numeric indexes (in Lua counting is done from "1").
pqOut is the Output table. You should add (again with numeric indexes started from "1") all MfxEvent(s) you need. Note that in case you do not add anything there, all events will be blocked by your MFX. While you can add events with other methods (for example "table.insert(ev)"), specialized "add" simplify the task (you do not need to bother making the event copy when needed and you do not need the conditional execution when filtering out events).
So, the general structure is:
function OnInput(pqIn, pqOut)
for i = 1, #pqIn do
local e = pqIn[i]
-- Do something with "e"
pqOut.add(e)
end
end
More "Lua" style (better) definition for the same:
function OnInput(pqIn, pqOut)
for i,e in ipairs(pqIn) do
-- Do something with "e"
pqOut.add(e)
end
end
In that exact form, your MFX will just copy all events from the input table into the output table. Effectively the same "functionality" as not existing or disabled MFX plug-in. As I have already mentioned, defining the function but leaving it empty will BLOCK all MIDI events. So, you already know 2 "extreme" MFX plug-in definitions
Local in "local e = ..." is not required but optimize the speed. We are working close to the Sonar "RealTime engine", so you should care (when that does not severe disturb readability, Lue experts will probable write "must without 'when'").