Trigger MIDI and UI events programmatically?

Hello,

I’m wondering if it is possible to use Lua to trigger MIDI and/or UI events programmatically with the grid? For example, I could press a button which causes an LED to light in a different location and playback a series of midi messages that are stored in a Lua variable?

I’m guessing this is outside of the scope of the Lua environment, but it would be pretty cool and would open up a lot of possibilities if so.

From poking around the reference manual it seems like this is possible with the midi_send and led_value functions.

Ultimately what I would love to do is create a midi looper that would work something like this:

  1. Press a button to begin recording midi events
  2. Turn a bunch of knobs
  3. Press button again to stop recording and playback knob midi events from step 2

I realize this is somewhat complex, but is it theoretically possible?

1 Like

Should be quite possible, yes!

You would have to create some kind of buffer that records the events that happen then run through that buffer and play them back with a timer event.

I could create some kind of demo for this…

@narayb did you ever create a demo for this? I’m really interested in the idea of recording various controller changes which I make and then playing them back in a loop and i’d love to see a simple example of this to get started with.

I actually did. You can now find it under midirecord on the Profile Cloud.

It’s very barebones and simple, and for now it doesn’t loop the captured MIDI sequence, but that should be doable as well.

image

Here’s how it works:

  1. Press Rec.
  2. Play with the faders.
  3. Press Rec again to turn off the recording.
  4. Press Play to play it once (this deletes the recording).

It’s made for a PBF4 because that’s all I had lying around then, but all code is found under these elements:

image

So you can just open the profile up and load these three specifically.

That’s brilliant, thanks so much!

1 Like

I’ve been working with your example (thank you again!) and I think I mostly understand it, but there’s one place I’d really appreciate a little bit of extra explanation.
In the system block you have a function

self.midirx_cb = function(self, midi_ev, grid_headers)
    table.insert(midirx_list, midi_ev)
    limit(midirx_list, 4)
end

then in the timer you are copying the last element from the midirx_list into the buffer, so that we can later read from that buffer for playback.

What I don’t really understand is when midirx_cb is called, and what midi_ev contains, I don’t see any place where this function is called or any reference to it, or the values it takes in the wiki.

Also what does the limit function do? it seems like it keeps the midi input recording list at 4 elements max. But when we are inserting that data into the buffer are we not just taking the most recent value? table.insert(buffer, midirx_list[#midirx_list]), so couldn’t we just keep the single most recent value in memory? or am I getting confused about what the # operator does in lua? (sorry my lua is a bit rusty!)

and could you give me some hints about how to rewrite this to target only recording a specific control rather than everything?

Thanks very much.

Yeah, the above is a little bit of black magic.

What essentially happens is that there is a not documented micro-instrumentation hook for grabbing all MIDI events that happen across your Grid setup.

The limit() function makes the buffer of midirx_list{} a FIFO one by setting the limit of the buffer with the second parameter. You can make a different buffer if you’d like.

If you want to limit the buffer to only look for specific CCs and similar, just insert an if branch around the table.insert function.

1 Like