midi messages, osc note on/off, stop all sounds


I am really new to scripting in Lua, so i have some basic questions.
I am normaly using PureData and dicided I could try to rebuild some of my PureData things with scripting in Renoise. So I need some basic tips to get startet.

I realised through other threads that it is not possible to trigger an instrument via the api directly.
I have to start the OSC Server connect me to this Server and send OSC messages to it right?

I managed to to this verry simple with the OSC example.

The i realised thanks to MXB and the irc channel how i can make timed actions in Lua. ( renoise.tool():add_timer(myfunc, 1000) )

One thing i didn’t solve was the use of midi in lua… i tried the following from the example but had no success. Any ideas what is missing?
the example should print some text in the terminal but nothing shows up…

-- midi input listener (function callback)  
local inputs = renoise.Midi.available_input_devices()  
local midi_device = nil  
if not table.is_empty(inputs) then  
 local device_name = inputs[1]  
 local function midi_callback(message)  
 assert(#message == 3)  
 assert(message[1] >= 0 and message[1] <= 0xff)  
 assert(message[2] >= 0 and message[2] <= 0xff)   
 assert(message[3] >= 0 and message[3] <= 0xff)  
 print(("%s: got MIDI %X %X %X"):format(device_name,   
 message[1], message[2], message[3]))  
 -- note: sysex callback would be a optional 2nd arg...  
 midi_device = renoise.Midi.create_input_device(  
 device_name, midi_callback)  
 -- stop dumping with 'midi_device:close()' ...  

additionally i have some understanding questions.

  • When i send note_off via OSC does this trigger an envelope which fads out my instrument?
  • does every send note_on osc signal trigger a new instrument play or does it stop the old instrument and plays it again. or do renoise play two instances at the same time so that they overlap?
  • do i have to send a note_off for samples like i do for pads? or do they automatically stop playing? do i have to do this for example for freeing the ram or so?
  • is there a simple way to stop mall playing activity from lua? or do i have to send osc messages to all instruments when i want to stop all sounds?
  • is there a way to change the transpose value of an instrument via midi, osc or lua?
    thats it for now…thanks! renoise is awesome!

here is an example how my first tests sound like:

It depends on what is midi inputs[1], have you first of all printed out the devicename for inputs[1]? Perhaps it is not the midi device that you are controlling.

1 - It should be
2 - If you don’t send a note off, it will trigger a new note, but up to a maximum or 12 notes per track and 6 notes in NNA.
3 - Notes only stop automatically playing if the sample isn’t looped, frankly the whole NNA and note-off deal is just a serious gameplayer as control through Midi is.
4 - You could create a custom OSC function in the GlobalOSCActions.lua of the scripts folder where you can simply perform a “stop song” play which should more or less act as panic and stop all instrument play, but i haven’t tested this myself. There is an existing function /transport/panic.
5 - See 4:add a custom made lua function that responds to a custom designed OSC call that would perform the API call by using the renoise.song() api. There are some testscripts in the scripts\Snippets folder where you can toy with and ofcourse you can inspect the contents of the GlobalOSCActions.lua to see which custom made lua functions are in there including the descriptions of what they are made for and how you can add your own.

I believe this + PureData is a double-win.

Hey vV,

thanks for your answeres…this helps me a lot.

when i print all midi devices, i get the following: “table: 0x6b764c0”
i rechecked the first midi device is my midi controller. any ideas? is that right?

I’m not that familiar with the midi or osc API trickery, but in this case I’d say using rprint instead of print would get you further. Rprint is an addition for recursively printing out lua tables. Instead of the “table: 0x6b764c0” (which I think is only the address at which the table holding the midi devices resides) you’ll get a list of all the elements of the table.

If those elements are some objects like say renoiseMidiDevice-objects (making this up as I go along), you can query even further by doing an oprint (Object print) on those.

that or oprint(object_table)

that was the trick…thanks. controller was on [5]

now how to handle the values the best way? create a table and set all values to 0. then fill the entrys with the values when something changes?
i think this is important because otherwise i get NIL errors.

is there something like a range mapper function in the api…
like: func mapper(instart,inend,outstart,outend)

I use this function to indiscriminately dump the info I want, whatever it is:

-- Debug print  
function dbug(msg)  
 if DBUG_MODE == false then return end  
 local base_types = {  
 ["nil"]=true, ["boolean"]=true, ["number"]=true,  
 ["string"]=true, ["thread"]=true, ["table"]=true  
 if not base_types[type(msg)] then oprint(msg)  
 elseif type(msg) == 'table' then rprint(msg)  
 else print(msg) end  

Then you just type dbug(whatever) and it will always print something useful.

Hope this helps.

I don’t understand. Why not just check for nil? (== nil, ~= nil)

I don’t know of any mapper feature. I usually just use for i=1,#foo do where foo is a table and # means “count”. But, there are some extended table functions like table.find() that could maybe help?

see: https://code.google.com/p/xrnx/source/browse/trunk/Documentation/Lua.Standard.API.lua#72

i am using a table now which gets created with all values = 0

miditable = {}   
for i=0,256 do  
 miditable[i] = 0   

if the midivalues change they got writtten to the table. this gives me the possibility to directly use the table as value in other function.
as a plus i use a little mapper function now which maps for example my controller values 0-127 to a defined range. thats really helpful if i need other ranges in my script.

function map (val,startin,endin,startout,endout)  
 return (val - startin) * (endout - startout) / (endin - startin) + startout;  

but i am now having the problem that after a while my script isn’t responding to the midi controller anymore. if i only use the midi stuff and delete everything else it seems to work good…
here is the whole script if you want to have a look: http://pastebin.com/c7t2xh48

maybe its to jmuch osc action at once…???

Should i maybe start am new topic in “Tec: Scripting API Development Q&A” for this?

Not necessarily though the level of the topic got outside beginners quick enough.
You might be interested in trying to inspect a few other tools that convert midi into OSC messages, like Nism’s tool:

vV, thanks for the link. i checked the tools and cannot find any big difference in the midi/osc handling.

if i uncomment my timer function everything works. do i call the timer the right way?
i’m stuck.

if (renoise.tool():has_timer(myfunc)) then   
 randtime = 10 + math.random(100)  
 renoise.tool():add_timer(myfunc, randtime)