Re: MIDISend problems
Re: MIDISend problems
- Subject: Re: MIDISend problems
- From: Doug Wyatt <email@hidden>
- Date: Fri, 23 May 2003 11:09:26 -0700
On Friday, May 23, 2003, at 05:57 AM, Fredrik Lundkvist wrote:
fredagen den 23 maj 2003 kl 05.45 skrev Kurt Revis:
On Thursday, May 22, 2003, at 10:10 AM, Fredrik Lundkvist wrote:
1) I made a test program sending to a USB interface connected in a
loop.
I create in and outports, send messages and verify that all are
returned.
Often the first message sent is not returned. If I put a delay
between creating the
output port and starting to send messages it seems to work better.
Have I missed something? Is there a notification or a property I
can check before
I should start sending?
The same test with a virtual loop-back (another app) never fails.
What device are you using? I believe I've seen something similar
with one of my devices (a Midiman Midisport 2x2 or a MOTU Fastlane
2x2), but I don't remember which. In any case I think it's a bug and
not your fault -- you should not have to wait before sending data,
and there isn't any notification you should be waiting for.
In the hardware I test with regularly (Roland UM-880, Emagic MT-4) the
first message is never lost ... I have a benchmark test that measures
round-trip transport times ...
I have tested Steinberg USB2MIDI and M-Audio MIDISport 2x2, and both
have this problem.
I also tried with Emagic MT4, with which I had even more problems.
Sometimes a few messages
were lost, sometimes all.
It didn't work with a delay either, by the way. I sent a sensing
message first as a workaround, but that
seems like a dumb solution.
2) I made another test sending lots of messages. It looks like the
MIDISend function
runs happily until a buffer is filled, then it waits until there is
room in the buffer,
blocking the calling thread.
How much data can you send before it blocks? The communication
between your program and the MIDIServer process takes place through a
fixed-size ring buffer in shared memory. My understanding is that if
you fill up this buffer before the MIDIServer gets a chance to empty
it, CoreMIDI falls back to putting the data in a secondary buffer (so
it doesn't lose any data). Probably something related to that is
causing the block. I don't know if it is possible for CoreMIDI to
handle this case without blocking or not
not, it's not possible -- no matter how big I make that ring buffer, it
can fill and I'll have to fall back -- but: the thread in the
MIDIServer that empties the ring buffer runs with realtime priority,
and so it should be somewhat difficult to get into these kinds of cases
unless you are sending huge amounts of data *from* a realtime thread
... or sending data faster than it can get out the interface port ...
... perhaps someone in the CoreAudio team can say.
If you are sending all the data in one packet list (in one call to
MIDISend()), you might try breaking it up into multiple packet lists
and multiple calls to MIDISend(), in hopes that the MIDIServer will
have more opportunities to read from the buffer before you fill it.
Just an idea -- I don't know if this will work or not.
It's a loop sending thousands of messages, one in each packet list.
It looks like it blocks after one thousand, then each thousand takes
about a second to send.
1000 messages/second * 3 bytes/message * 10 bits/byte
(on a MIDI serial link, there are stop and start bits in addition to 8
data bits/byte)
= 30000 bits/second
The speed of MIDI is 31250 bytes per second -- so it looks like
everything is behaving just as one would expect.
This means I must create a separate thread that sends all messages if
my
application should stay responsive when there is a buffer overflow,
right?
If you're sending large amounts of data, yes, although you can use
MIDISendSysEx (if sysex is what you're sending) to create a separate
sending thread for you too.
Doug
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.