What @crim described above is probably all you’ll need for Awake, but if you want a “least recently used” voice stealing algorithm, Norns comes with a really useful little library called voice: https://github.com/monome/norns/blob/master/lua/lib/voice.lua

… I’m having a strangely hard time finding an example of it in use, but the principle is something like this:

local Voice = require 'voice'

local voices = Voice.new(2) -- 2 voices of polyphony
local midi_out = midi.connect()

local function start_note(note, vel)
  -- allocate a voice, "stealing" an existing one if necessary
  local voice_slot = voices:get()
  -- use the voice ID (1 or 2) as the MIDI channel
  local midi_channel = voice_slot.id
  -- send MIDI note
  midi_out:note_on(note, vel, midi_channel)
  -- tell this slot to send the correct note off when the voice is released or stolen
  local release_callback = function()
    midi_out:note_off(note, 0, midi_channel)
  end
  slot.on_steal = release_callback
  slot.on_release = release_callback
end

then you can use that start_note() function to send MIDI notes each step and they’ll alternate between channels 1 + 2, but if you call voices.slots[1]:release() between steps, a note off will be sent on MIDI channel 1, and the next step’s note will always go out on channel 1, while voice/channel 2 drones. Maybe not that interesting for steady 16th note sequences, but it’s really useful for grid or keyboard interfaces, and it’s a good way to make sure you’re sending note off messages.

3 Likes