I want to send MIDI SysEx messages from a Linux PC to a device that provides an USB MIDI interface.
The basic idea is that I send a SysEx message to the device and then receive the response like shown in this very simplified example:
handle = open("/dev/midiXxx", O_RDWR);
write(f, "\xF0...\xF7", LENGTH_OF_MESSAGE_1);
read(f, response1, sizeof(response1));
write(f, "\xF0...\xF7", LENGTH_OF_MESSAGE_1);
read(f, response2, sizeof(response2));
My problem is that the first read() sometimes hangs. By inserting sleep() in some parts of the program, I found out that the MIDI driver seems to discard all bytes received until read() is called the first time. If the device sends the response before the read() function is called in my program (for example because a task switch is happening exactly between the first write() and the first read()), the response is lost.
I saw this behavior ...
- Using
/dev/midiXxx - Opening
/dev/snd/midiCXxxDxxx(and usingread()andwrite()) directly - Using ALSA's
snd_rawmidi_Xxx()API instead ofopen(),read()andwrite()
(This API internally accesses/dev/snd/midiCXxxDxxx)
My question:
What is the correct method to ensure that the MIDI data is read?
I tried two methods that have worked:
One method was using O_NONBLOCK, calling read() (returning EWOULDBLOCK) and then using fcntl(F_SETFL) to make the file handle "non-O_NONBLOCK" (because I don't want O_NONBLOCK in the rest of my program).
The other method was to call poll() with POLLIN before the write().
However, I am not sure if these methods work reliably (especially after a Linux update).