lua_opcall — Calls a Lua opcode at i-rate only. Any number of output and/or input arguments may be passed. All arguments must be passed on the right-hand side. Outputs are returned in the argument.
lua_iopcall Sname, ...
lua_ikopcall Sname, ...
lua_iaopcall Sname, ...
lua_iopcall_off Sname, ...
lua_ikopcall_off Sname, ...
lua_iaopcall_off Sname, ...
Sname -- The name of the opcode.
... -- An arbitrary list of any number of
output and input arguments, of any type. The number, sequence,
and types of these arguments must agree with the cdef of the
arguments structure that is declared in the corresponding
lua_opdef
opcode.
lua_iopcall
calls a Lua opcode at i-rate only.
Requires opname_init
to be defined in Lua.
lua_ikopcall
calls a Lua opcode at i-rate and
k-rate. Requires opname_init
and
opname_kontrol
to be defined in Lua.
lua_iaopcall
calls a Lua opcode at i-rate and a-rate.
Requires opname_init
and
opname_audio
to be defined in Lua.
lua_iopcall_off
calls a Lua opcode at i-rate only.
Requires opname_init
and
opname_noteoff
to be defined in Lua.
lua_ikopcall_off
calls a Lua opcode at i-rate and
k-rate. Requires opname_init
,
opname_kontrol
, and opname_noteoff
to be defined in Lua.
lua_iaopcall_off
calls a Lua opcode at i-rate
and a-rate. Requires opname_init
,
opname_audio
, and opname_noteoff
to be defined in Lua.
Lua code accesses elements of arguments as follows (pointers to both scalars and arrays are dereferenced by the Lua array access operator):
ffi.cdef(' struct arguments_t { double *a_out, double *i_in, double *i_txt, double *f_sig };'); local arguments = ffi.cast("struct arguments_t *", carguments_lightuserdata) for i = 0, ksmps -1 do begin carguments.a_out[i] = carguments.i_in[0] * 3 end end
The "off" variants of the opcode always schedule a "note off" event that is called when the intrument instance is removed from the active list, and which can be used to release unneeded resources, reschedule the instrument to render a reverb tail, and so on.
Here is an example of a Lua opcode, showing how to pass strings back and forth between Lua opcodes and Csound orchestra code. The example uses the file luaopcode.csd.
Example 464. Example of a Lua opcode.
<CsoundSynthesizer> <CsInstruments> lua_opdef "luatest", {{ local ffi = require("ffi") local string = require("string") local csoundLibrary = ffi.load('csound64.dll.5.2') ffi.cdef[[ int csoundGetKsmps(void *); double csoundGetSr(void *); struct luatest_arguments {double *out; double *stringout; char *stringin; double *in1; double *in2; double sr; int ksmps; }; ]] function luatest_init(csound, opcode, carguments) local arguments = ffi.cast("struct luatest_arguments *", carguments) arguments.sr = csoundLibrary.csoundGetSr(csound) print(string.format('stringin: %s', ffi.string(arguments.stringin))) print(string.format('sr: %f', arguments.sr)) arguments.ksmps = csoundLibrary.csoundGetKsmps(csound) print(string.format('ksmps: %d', arguments.ksmps)) arguments.out[0] = arguments.in1[0] * arguments.in2[0] ffi.copy(arguments.stringout, 'Hello, world!') return 0 end function luatest_kontrol(csound, opcode, carguments) local arguments = ffi.cast("struct luatest_arguments *", carguments) arguments.out[0] = arguments.in1[0] * arguments.in2[0] return 0 end function luatest_noteoff(csound, opcode, carguments) local arguments = ffi.cast("struct luatest_arguments *", carguments) arguments.out[0] = arguments.in1[0] * arguments.in2[0] print('off') return 0 end }} instr 1 iresult = 0 Stringin = "stringin" Stringout = "stringout" lua_iopcall "luatest", iresult, Stringout, Stringin, p2, p3 prints Stringout endin instr 2 iresult = 0 Stringin = "stringin" Stringout = "initial value" lua_iopcall_off "luatest", iresult, Stringout, Stringin, p2, p3 print iresult prints Stringout endin </CsInstruments> <CsScore> i 1 1 2 i 2 2 2 i 1 3 2 e </CsScore> </CsoundSynthesizer>