Teensy USB MIDI - receive SysEx messages

Status
Not open for further replies.

timg11

Member
I found the USB MIDI capability of the Teensy, and it looks like exactly what I need to perform some MIDI translation.
My requirement is to receive some SysEx messages and transmit them back out as MIDI CCs (continuous controllers).

I see there is no callback function for SysEx. I suppose it would be acceptable to just poll the read() function and act on SysEx messages that way, since the system isn't doing anything else.

Since USB MIDI provides a higher data rate than legacy serial MIDI, is there any buffer overflow protection if SysEx messages come in faster than the read() polling and output process can handle them?

One more question - I'm new to the Teensy. Does the MIDI code work equally well on the Teensy 2.0 and the 3.1? I see the schematic with the 74HC4051 input multiplexer shows the 2.0 version....
 
Last edited:
Based on this image from the tutorial, which shows only Teensy 2.x versions and no 3.x version, I'm going to assume that only the Teensy 2.x versions are usable with the TeensyDuino and thus the USB MIDI library

td_tutorial_01a.png
 
The screenshots in that tutorial predate the introduction of Teensy 3.x, and so show the state of the Teensyduino at that time. USB MIDI can be used with Teensy 2.0, Teensy++ 2.0, Teensy 3.0, and Teensy 3.1.

Also, since that screenshot was taken, the selection of USB type has moved to a separate menu item than selecting the board. This makes it less cluttered.

usbmidi-select.png

You can see some examples of USB MIDI in File > Examples.

usbmidi-examples.png
 
Last edited:
If you look in your Arduino install under hardware/cores/teensy/teensy3 in usb_midi.h, usb_midi.c there are some things related to SYSEX that may be helpful (and some you may need to change).

In particular
Code:
#define USB_MIDI_SYSEX_MAX 60  // maximum sysex length we can receive
may need to be increased, depending on the size of individual SYSEX messages that you intend to handle.

There is also a handler for SYSEX
Code:
extern void (*usb_midi_handleSysEx)(const uint8_t *data, uint16_t length, uint8_t complete);
and a method to send CC
Code:
void sendControlChange(uint32_t control, uint32_t value, uint32_t channel)

Regarding flow control and buffering, I'm afraid I don't know how USB handles that.
 
Nantonos, thanks for the tips.

The Sysex messages I want to receive and translate are small - approximately 16 bytes. However the instrument is capable of sending larger messages under some circumstances. If USB_MIDI_SYSEX_MAX was set to 24, and a message of 10Kbytes was received, what would happen? Discarding the large message is OK. Buffer overflow and crash is not ;)



If you look in your Arduino install under hardware/cores/teensy/teensy3 in usb_midi.h, usb_midi.c there are some things related to SYSEX that may be helpful (and some you may need to change)..
 
My Teensy 3.1 has arrived - thanks for the fast shipping!
I have the Arduino 1.0.5 installed with TeensyDuino, and I have verified the Teensy loader with the fast and slow LED blink programs.

I loaded the Buttons sketch in the Arduino IDE and uploaded it. I was happy to see "Teensy MIDI" appearing as new MIDI in and MIDI out devices.

Next step was to start up MIDI-OX to have a look at the data coming out of the Teensy. Options / MIDI Devices; "Teensy MIDI" is right there with the others.
Strangely, I cannot select the Teensy MIDI device as an input. USB MIDIsport works OK, FocusRite works OK, input from Midi Yoke works OK. But whenever Teensy MIDI is selected as an input, I get the MIDI-OX error: "Teensy MIDI" There is not enough memory available for this task".

Has anybody else seen this? Is it an issue with MIDI-OX, or something about the Teensy?
 
If you look in your Arduino install under hardware/cores/teensy/teensy3 in usb_midi.h, usb_midi.c there are some things related to SYSEX that may be helpful (and some you may need to change).

I'm looking at usb_midi.c, and trying to understand the function of int usb_midi_read(uint32_t channel)

I think I understand the section of code starting with
Code:
if (type1 >= 0x08 && type1 <= 0x0E) {
That is handling all the channel messages with the status between 0x08 and 0x0E, and the associated callback routines (usb_midi_handleNoteOff, etc).

I'm confused by the code below that:
Code:
	if (type1 == 0x04) {
		sysex_byte(n >> 8);
		sysex_byte(n >> 16);
		sysex_byte(n >> 24);
		return 0;
	}

I thought type1 was the MIDI status byte's high nibble. So for SysEx, it should be 0xF. But here type1 seems to be treated like size, and three other bytes are pulled out of the 4 byte "n".

Perhaps there is something else going on in the USB MIDI driver before it gets to this code, so that type1 is not simply the MIDI status? Where is the data structure or format of the rxpacket defined?
 
I haven't seen this "There is not enough memory available for this task" when using MIDI-OX to debug Teensy 2.0 or Teensy 3.x USB MIDI. I have used both input and output.
 
With respect to MIDI-OX out of memory - it was apparently a spurious or random problem. After shutting down yesterday, I tried it all again today, and MIDI-OX is working fine with the Teensy now.

I'm still trying to figure out the flow in usb_midi.c. I'd appreciate any references to further explanation or documentation for how that code works. The SysEx messages I'm interested in are small, but there is a possibility that larger messages may be sent sometimes.
I'm trying to trace the path of an incoming SysEx message to determine if a large message would just be discarded, or exactly what happens. Does my Teensy code need to do anything to clear unwanted messages out of the buffer?


Does anybody have any example sketches that show the processing of incoming SysEx messages?
 
Last edited:
i had this prob but worked out that its couse there is another program that is using it as u can only have 1 program reading a midi devise at a time
 
Status
Not open for further replies.
Back
Top