Midi SysEx Messages

Hi,

am I correct in assuming that currently it is not possible to send SysEx messages with Sonic Pi?

1 Like

You can send raw midi so probably can that way though I’ve not investigated it.

Yes, I have seen that. The thing is that I need to send something like:

F0 00 20 6B 7F 42 02 00 **01 70 09** F7 (source)

and up to now I have not spotted how to translate this to something like

midi_raw 0xb0, 0x79, 0x0  # example from Sonic Pi doc

accepting only 3 bytes. As far as I understood sysex commands contain more than 3 bytes (as in the example above, where the mere midi control data bytes are #9 to #11).

Great question. It should work, but I have to confess to not having tried it myself, so it’s possible there’s a bug somewhere.

I’m currently on the road, so it’s a bit hard for me to try something out right now, but please pester me if I don’t get back to you on this.

First time I tried, it did not work. But I’ll give some more effort tomorrow. Maybe I did someting wrong.

If I understand correctly I will just have to spit up the command in 3 groups, right?

Thanks for the input, @samaaron !

Hi Sam,

if you have the time I’d like some help about this issue. I have confirmed that I can trigger the controller by using amidi. F. e. I can send the following message to trigger a pad’s LED to on:

 amidi -p hw:2 -S 'F0 00 20 6B 7F 42 02 00 10 77 01 F7'

I tried different versions but I do not manage to send the same command using Sonic Pi’s midi_raw.

Some obvious questions:

  • How do I divide the command (if at all); midi_raw expects 3 bytes (or at least parts) if I interpret the documentation correctly: “midi_raw a (byte), b (byte), c (byte)”
  • Do I need the sysex delimiters F0 ... F7?
  • Do I need the hex prefixes 0x; if yes: for all bytes?
  • Finally - and an answer to the questions before: Could you give an example using the above mentioned sysex command I sent with amidi that I could try?

I’d be very grateful for some help on this issue.

Martin

I’m in Australia for a couple more weeks. Hopefully I’ll an opportunity to look into this before Christmas.

Yes, I know. Have a nice stay. No hurry with that.

Thanks
Martin

I’d like to chime in and show interest in this functionality. A lot of the controls on the Roland Integra 7 use sysex commands and they are usually around 14 bytes. This could open some doors to new possibilities.

I’m a SysEx junkie. Actually got into SysEx midi before midi noteOn/Off or CC because I realized I could control deep parameter settings of my Lexicon MPX1 pro. MidiOX is an awesome tool for analyzing what is going on with midi.

Please get Sonic Pi to support SysEx because I will use it to control effects parameters on hardware in sync with performance. Legendary!

I just stumbled in here while checking some Beatstep sysex stuff…

As a preliminary solution you could try to make a sequence of midi_raw calls by splitting up your sysex into 3 byte chunks. This should work as far as I can tell from looking at the Sonic Pi code.

In order to simplify things you could define a function in Sonic Pi to do just that:

def midi_rawest(*args)
  midi_raw *args.take(3)
  midi_rawest *args.drop(3) if args.length > 3
end

The new function should allow you to send longer messages, i.e.

midi_rawest 0xf0, 0x00, 0x20, 0x6b, 0x7f, 0x42, 0x02, 0x00, 0x10, 0x77, 0x01, 0xf7

Please note that I haven’t tested the function as I am not in front of my music PC.

2 Likes

Hi @Daniel,

thanks for looking into that!

I will have some time at the weekend and try, what you are recommending …

PS.: I like the function name midi_rawest :wink:

I had a quick look, generating a SysEx message with SysEx Librarian, and looking at the message with Midi Monitor. It is sent as a single 12-byte message, whereas midi_rawest sends a number of separate 3-byte messages, most of which are marked as “invalid” in Midi Monitor, so I think these are unlikely to be interpreted in the same way by most midi hardware.

However, I found an internal function in Sonic Pi that is able to send a raw midi message of arbitrarily length:

__midi_send_timed("/*/raw", 0xf0, 0x00, 0x20, 0x6b, 0x7f, 0x42, 0x02, 0x00, 0x10, 0x77, 0x01, 0xf7)

Be aware that it is undocumented and completely unsupported and may well change or disappear in a later version, but it seems to work at the moment, and might be a good enough workaround for now.

EDIT: I’ve created a PR to allow midi_raw to support longer SysEx messages.

6 Likes

This is of interest to me too. I looked into the various methods of sending raw midi described here, and they all worked for me with the limitations mentioned. (E.g. midi_raw only sending three bytes.). Extending midi_raw to allow longer messages, e.g. by being able to pass it an array or simply an open ended number of arguments, would be useful.

I don’t know Ruby, but I had a look at the code for midi_raw. Assuming that Ruby isn’t too unexpectedly weird a language, surely it would be possible to detect that an array has been passed to it, and send all the bytes.

Yay, my PR was just merged, so next Sonic Pi version will have a midi_sysex function :smiley:

6 Likes

Thanks so much for looking into this and for the fab PR :slight_smile: