Managing midi control messages


basically, there are two functions to get control messages from external midi hardware: sync and get. sync waits for an event, get will give the last message received.

Let’s say you’d like to get the current value of controller number one, the code could look like this:

live_loop :player do
  controller, value =  get "/midi/photon_25_midi_1/1/1/control_change"
  puts value if controller == 1
  sleep 1

This is not very elegant, is it?

I found another solution, which is a nice hack perhaps, but still awkward:

values = [0,0,0,0,0,0,0,0,0,0,0,0,0]

live_loop :updater do
  controller, values[controller] =  get "/midi/photon_25_midi_1/1/1/control_change"
  puts values[1]
  sleep 1

Any better idea? Something like

get "....", 1

would be awesome!

1 Like

Completely agreed. Pattern matching on event paths is something I’ve been planning for a while :slight_smile:

Thank you Sam, so this means, the given code examples are best practice for current sonic pi versions?

I control synths with my midi controller this way:

set :synth, nil
synths = [:beep, :blade, :bnoise, :chipbass, :chiplead, :chipnoise, :cnoise, :dark_ambience, :dpulse,
          :dsaw, :dtri, :dull_bell, :fm, :gnoise, :growl, :hollow, :hoover, :mod_beep, :mod_dsaw,
          :mod_fm, :mod_pulse, :mod_saw, :mod_sine, :mod_tri, :noise, :piano, :pluck, :pnoise,
          :pretty_bell, :prophet, :pulse, :saw, :sine, :square, :subpulse, :supersaw, :tb303,
          :tech_saws, :tri, :zawa]

live_loop :midi_piano do   
  note, velocity = sync "/midi/apc_key_25/1/2/note_on"
  use_synth get[:synth]
  play note, cutoff: 80, release: 3, attack: 1, amp: 1

live_loop :synth_checker do
  note, velocity = sync "/midi/apc_key_25/1/1/note_on"
  set :used_synth,synths[note]
  print synths[note]