WARNING this is quite a technical post. If you are new to Sonic Pi, and/or are not into using midi input then please feel free to ignore it completely. However it may be of use to those who are already using midi fairly heavily with Sonic Pi.
Just a heads up about a recent change Sam has made to the midi cue format, to bring it more into line with the way osc cues are formatted.
Instead of formats such as
new cues will now have a format like
where the device name, port number and channel which were previously in separate sections separated by the / symbol are now encoded as part of the midi header with : separators.
This has two effects, as those who are already using SP3.2dev with OSC cues will know, whereas in SP3.1 you would look to sync cues with strings like
"/osc/hello" in SP3.2 because you have strings like
"/osc:192.168.1.240:9000/hello" it is usally convenient to seach for a sync using
"/osc*/hello" where the wild card * matches the ip address and port number which form part of the osc header.
In the same way now it will usually be convenient to use
"/midi*/note_on" to match a note_on midi cue. If you want to match the channel you could use
"/midi*2/note_on" to match channel 2 note_on.
Users of my programs will have come across my parse_sync_address function which I have used to extract information from both osc and midi cues, for example in my recent midifile player program.
With the new format of midi cues this needs modifying to work. I have a modified parse_midi_sync_address function which can be used to extract information from midi cues as shown below
original parse_sync_address function (still valid for osc cues)
define:parse_sync_address do |address| #gets info on wild cards used in sync address v= get_event(address).to_s.split(",") if v != nil #return a list of address elements with wild cards substituted by actual values return v[3..-2].split("/") else return ["error"] end end
["osc:192.168.1.240:9000", "mplayer", "synths", "1", "4"] with the wild card * filled in by the actual trigger ing cue.
The new function
define :parse_midi_sync_address do |address| v= get_event(address).to_s.split(",") if v != nil p1=v[3..-2].split("/") return p1.split(":")+p1[1..-1] else return ["error"] end end
["midi", "usb_oxygen_8_v2", "1", "5", "note_on"]
filling in the missing data, but critically following the previous format for midi cues
/midi/usb_oxygen_8_v2/1/5/note_on rather than the new format
/midi:usb_oxygen_8_v2:1:5/note_on making it a drop in replacement when used in existing programs which are parsing midi cues.
I will post an updated midiplayer file soon.