Hi, I started developing a device with usb midi 1.0 based on a microchip usb stack example (the descriptor is almost the same of the "midi10.pdf" final example). Everything is working fine on mac os, but if I connect the device to any Windows pc it works only for PC, CC, MIDI CLOCK, Notes, but NOT FOR SYSEX. Messages are actually not seen.
WHen I compose the messages I pack them in 4 bytes groups (control byte + 3message bytes) to fill a 32 bytes buffer and send it to the host. As already said, on mac os there's no problem, so messages are correctly received.
On windows I'm using MIDI-OX to monitor the input, and to be sure about the configuration I tried to do the same thing with a commercial USB-MIDI converter and it works fine, so i'm sure it's a problem on my device.
Is there somebody who suffered of similar issues? The only thing I didn't try is to send 4 bytes buffers instead of the compact 32 bytes buffer.
Are you sending all 32 bytes, or only as many as are actually used? It's possible that the Windows driver ignore the entire USB packet when it sees an invalid event packet.
Good question Clemens! I tried to send 4bytes packets but it didn't work. Now I will try to complete a 32 bytes buffer and I'll tell you if it works. Than you for the suggest.
It didn't work.
Still having the same problem even with a complete 32Bytes buffer and a complete 64Bytes buffer.
Please show your source code.
Ok, I just rewrote a "generic" function that fills my tx buffer with only the necessary bytes (there's no check on max length since it's not necessary for this example code) to show you how I prepare the packets. Just checked and it works on mac OS (I tried on an old mac with yosemite OS and a new mac with catalina OS) but it doesn't work on windows (Windows 10). No issues with program changes or other standard "one/two/three bytes" messages.
Here' the code:
void USB_SYSEX_TX (unsigned char ID, unsigned char *tx_buf,unsigned char len)
{
unsigned char i = 0;
unsigned char tx_packets;
unsigned char last_packet_len = 0;
unsigned char buf_len;
len+=3; //Add F0, ID, F7
tx_packets = len/3;
last_packet_len = len - (tx_packets*3);
if (last_packet_len) tx_packets++;
buf_len = len + tx_packets;
if(!USBHandleBusy(USBTxHandle))
{
//First chunk
sysex_packet.v[0] = MIDI_CIN_SYSEX_START;
sysex_packet.v[1] = SysEx_START; //F0
sysex_packet.v[2] = ID;
sysex_packet.v[3] = tx_buf[0];
//middle chunks
for (i=1; i<tx_packets-1; i++)
{
sysex_packet.v[i*4] = MIDI_CIN_SYSEX_CONTINUE;
sysex_packet.v[(i*4)+1] = tx_buf[(i*3)-2];
sysex_packet.v[(i*4)+2] = tx_buf[(i*3)-1];
sysex_packet.v[(i*4)+3] = tx_buf[i*3];
}
//Last chunk
if (last_packet_len == 0)
{
sysex_packet.v[i*4] = MIDI_CIN_SYSEX_ENDS_3;
sysex_packet.v[(i*4)+1] = tx_buf[(i*3)-2];
sysex_packet.v[(i*4)+2] = tx_buf[(i*3)-1];
sysex_packet.v[(i*4)+3] = SysEx_END; //F7
}
else if (last_packet_len == 2)
{
sysex_packet.v[i*4] = MIDI_CIN_SYSEX_ENDS_2;
sysex_packet.v[(i*4)+1] = tx_buf[(i*3)-2];
sysex_packet.v[(i*4)+2] = SysEx_END; //F7
}
else if (last_packet_len == 1)
{
sysex_packet.v[i*4] = MIDI_CIN_SYSEX_ENDS_1;
sysex_packet.v[(i*4)+1] = SysEx_END; //F7
}
USBTxHandle = USBTxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&sysex_packet,buf_len);
}
}
buf_len must be a multiple of four.
Thank you Clemens, I'll add a padding of 0s on the last chunk after the "sysex_end" and I'll try.
It worked! Buf_len now is multiple of four and I added a padding on the last chunk to complete the "fourtet". It works. Thank you for the support.
Hi all, I'm new here. I have a question, and I think this post is the closest I've found to something similar.
I'm working on adding USB MIDI functionality according to the USB MIDI v1.0 spec. The device uses a musb controller. I'm noticing this behavior when debugging while connected to a Windows host running Midi-ox, class-compliant driver.
- When I send a non-sysex message from Midi-ox, each USB packet received at the device contains a single 32-bit USB-MIDI Event packet, corresponding to a single MIDI message.
- When I send a sysex message from Midi-ox, the USB packet received at the device contains multiple USB-MIDI Event packets up to the endpoint max packet size.
- So far I haven't seen any realtime (or other status) USB-MIDI Event packets in the middle of a USB packet containing a string of sysex USB-MIDI Event packets.
I've tried to find a description of this behavior in the USB and class specifications, but I can't seem to find it. For now to make sure I'm following the specifications, I'm processing each USB-MIDI Event separately, but it would be really convenient if I could assume that a single USB packet contains only one MIDI message with no interleaved realtime packets.
So my question is: is this behavior defined by specification or by the OS/driver/application? I'd be very grateful for any help! Some of the terminology in the USB specs is a little beyond my current level of understanding.
The USB MIDI class specification has no such restriction.
What you are seeing is caused by the driver in the specific version of Windows you're using. Other drivers will behave differently. (The Linux driver fills up a single USB packet as much as possible; the OpenBSD driver even interleaves event packets from multiple ports.)
Thanks so much! You just saved me a lot of time and frustration.
Now that you've given me the right answer, I see that it's explained in the 1st and 4th paragraphs of section 3.2.1 of "Universal Serial Bus Device Class Definition for MIDI Devices rel 1.0."