Teensy 4 send multiple MIDI notes at once through USB.

Status
Not open for further replies.

frankzappa

Well-known member
Hello!

I'm wondering if it's possible to send multiple MIDI notes at once through USB midi.

As far as I understand MIDI works sequencially sending one message at a time but I'm wondering if it's possible to send multiple notes and have them played at the same time without any delay between them.

Thanks.
 
The simple answer is yes, you can send multiple MIDI messages at once.

The actual MIDI communication is done at 480 Mbit using a complicated protocol which communicates in packets. A single packet can hold up to 128 MIDI messages, so unless you are transmitting a pretty incredible number of messages very quickly, typically the messages you transmitted at once will all end packed into the same packet. Even though the individual bits are sent 1 at a time, the host controller in your PC receives the entire packet into a memory buffer and verifies its CRC check before passing the data on to any MIDI software. The end result is all the MIDI messages within 1 packet are indeed received at once by the software on your PC. Or at least the operating system & drivers make them all available to the software at the same instant.

Even if multiple USB packets are used, the timing is incredibly fast relative to the pace of musical events. So even though a large burst MIDI messages spanning multiple USB packets aren't technically received simultaneously, the delay is so short that it's not worth any worry.

Something you might consider on the Teensy side is the usbMIDI.send_now() function. If you have sent less than 128 messages, this function tells Teensy's USB code not to wait for any more, to transmit a USB packet as soon as possible with only the messages it currently has buffered. If you care deeply about performance, this can reduce latency by up to 125 microseconds. But it does use the USB bandwidth less efficiently, so only call usbMIDI.send_now() after you've completed a group of messages and you do not expect to send any more immediately.
 
Last edited:
The simple answer is yes, you can send multiple MIDI messages at once.

The actual MIDI communication is done at 480 Mbit using a complicated protocol which communicates in packets. A single packet can hold up to 128 MIDI messages, so unless you are transmitting a pretty incredible number of messages very quickly, typically the messages you transmitted at once will all end packed into the same packet. Even though the individual bits are sent 1 at a time, the host controller in your PC receives the entire packet into a memory buffer and verifies its CRC check before passing the data on to any MIDI software. The end result is all the MIDI messages within 1 packet are indeed received at once by the software on your PC. Or at least the operating system & drivers make them all available to the software at the same instant.

Even if multiple USB packets are used, the timing is incredibly fast relative to the pace of musical events. So even though a large burst MIDI messages spanning multiple USB packets aren't technically received simultaneously, the delay is so short that it's not worth any worry.

Something you might consider on the Teensy side is the usbMIDI.send_now() function. If you have sent less than 128 messages, this function tells Teensy's USB code not to wait for any more, to transmit a USB packet as soon as possible with only the messages it currently has buffered. If you care deeply about performance, this can reduce latency by up to 125 microseconds. But it does use the USB bandwidth less efficiently, so only call usbMIDI.send_now() after you've completed a group of messages and you do not expect to send any more immediately.

Thanks paul, very helpful as always.

I'm using usbMIDI.send_now(). Ok so if I send three notes every time and I use send now it should always send them in the same package right?

The timing may be fast but what I'm doing is a special case where phase cancellation will be a problem so it needs to be pretty much instantaneous.
 
MIDI isn't designed for timing that accurate. You'd expect MIDI latencies to be measured in milliseconds, not microseconds.
You'd be at the mercy of the receiving software as to what happens, but its entirely plausible a whole packet is processed
as if simultaneous, and its entirely plausible that it isn't - you'd need to experiment.
 
MIDI isn't designed for timing that accurate. You'd expect MIDI latencies to be measured in milliseconds, not microseconds.
You'd be at the mercy of the receiving software as to what happens, but its entirely plausible a whole packet is processed
as if simultaneous, and its entirely plausible that it isn't - you'd need to experiment.

Yeah I'm aware of that and it's not something I can control. All I can do is to try send them at once and cross my fingers that the recieving side will process it as three simultaneous hits.
 
Hi Paul,

I'm working on a project that requires sending a large number of midi messages quickly and I just wanted to check something about the information you provide below.

I've uncommented #define USBHOST_PRINT_DEBUG in USBHost_t36.h and I can see that when I send 64 MIDI messages in quick succession, they are sent as 64 buffers each of which contains a single midi message and 127x4 '00's

When I check the MIDIDeviceBase::write_packed() function in the midi.cpp file I can see the following:

Code:
else {
    // TODO: start a timer, rather than sending the buffer
    // before it's full, to make best use of bandwidth
    tx1_count = tx_max;
    queue_Data_Transfer(txpipe, tx_buffer1, tx_max*4, this);
}

I would make a massive difference to my project to be able to send midi messages packed into a single buffer so I'm just wondering if I'm missing something to make this buffer packing work?

Many thanks in advance,
Dennis




The simple answer is yes, you can send multiple MIDI messages at once.

The actual MIDI communication is done at 480 Mbit using a complicated protocol which communicates in packets. A single packet can hold up to 128 MIDI messages, so unless you are transmitting a pretty incredible number of messages very quickly, typically the messages you transmitted at once will all end packed into the same packet. Even though the individual bits are sent 1 at a time, the host controller in your PC receives the entire packet into a memory buffer and verifies its CRC check before passing the data on to any MIDI software. The end result is all the MIDI messages within 1 packet are indeed received at once by the software on your PC. Or at least the operating system & drivers make them all available to the software at the same instant.

Even if multiple USB packets are used, the timing is incredibly fast relative to the pace of musical events. So even though a large burst MIDI messages spanning multiple USB packets aren't technically received simultaneously, the delay is so short that it's not worth any worry.

Something you might consider on the Teensy side is the usbMIDI.send_now() function. If you have sent less than 128 messages, this function tells Teensy's USB code not to wait for any more, to transmit a USB packet as soon as possible with only the messages it currently has buffered. If you care deeply about performance, this can reduce latency by up to 125 microseconds. But it does use the USB bandwidth less efficiently, so only call usbMIDI.send_now() after you've completed a group of messages and you do not expect to send any more immediately.
 
Status
Not open for further replies.
Back
Top