Re: Calling MIDIPacketListAdd from NSTimer
Re: Calling MIDIPacketListAdd from NSTimer
- Subject: Re: Calling MIDIPacketListAdd from NSTimer
- From: Brian Willoughby <email@hidden>
- Date: Tue, 11 Oct 2011 22:28:02 -0700
CoreMIDI scheduling is indeed more accurate than NSTimer, but it's
not as if Apple purposely made NSTimer less accurate. There are very
logical constraints which make NSTimer significantly less appropriate
for MIDI timing compared to the CoreMIDI functionality.
NSTimer is a general-purpose API and is at the mercy of the thread
priority in the hosting application. It would not be very efficient
for every MIDI application to have kernel priority threads just to
handle MIDI timing. Not only are there thread issues, but NSTimer
works within a run loop and thus can often be delayed by application
user interface events. Apple makes it clear that timers may not fire
exactly when scheduled. Keeping multiple threads running within
tight timing constraints is not what NSTimer is designed for, but
rather NSTimer is a much simpler API for more relaxed timing needs.
Instead of forcing every application to deal with fixed priority, low
latency threads for precise MIDI timing, CoreMIDI allows applications
to pass data from application space to system space in a way that
allows OSX to handle the timing of MIDI data in carefully written
code. Another benefit of CoreMIDI is that the implementation of the
timing can be changed without application developers needing to alter
their code to match available hardware.
One very important factor to keep in mind is that you can only
achieve the full accuracy of the CoreMIDI clock if you give a decent
margin of advance notice to the API. In other words, you cannot wait
until a MIDI event is supposed to occur before sending it to the API,
because there won't be enough of an opportunity for CoreMIDI to
schedule the MIDI data properly. I do not know, off hand, the exact
amount of advance notice that you need, but it should be easy when
playing MIDI data from a file because you can predict the data.
CoreMIDI cannot go back in time, so you have to make sure your code
runs slightly ahead of time if you want full precision in the timing
of MIDI events.
A caveat here is that real-time MIDI translation cannot actually take
advantage of the CoreMIDI clock accuracy because there is no way to
predict live MIDI input. The best you could do in this particular
case is to add a static latency to the time stamp of each incoming
MIDI message so that your translated output would maintain the same
relative timing to full CoreMIDI clock accuracy, albeit with a very
slight delay (which would depend upon your translation code's
efficiency). This limitation affects not only translation of live
MIDI input to MIDI output, but also limits what can be done in
interactive, algorithmic MIDI event generation. While you can have
interface MIDI generation, there must be some amount of latency to
allow for precise timing.
Yet another benefit of CoreMIDI time stamps is that OSX has the
ability to offload timing duties to external hardware. Any MIDI
interface with advanced timing capabilities, such as MOTU's MTS (MIDI
Time Stamping) or EDIROL's custom protocol, can accept the MIDI data
from CoreMIDI along with the time stamp and then the hardware
interface itself will take responsibility for the timing of the
outgoing data (or marking of incoming data). This sort of advanced
performance simply isn't possible when using NSTimer. Thankfully,
CoreMIDI handles all of the details for you so that your code does
not need to adjust to the available hardware and yet you're always
guaranteed the maximum accuracy possible (provided that your
application provides the MIDI data with sufficient advance notice).
Sorry if this is more detail than you requested, or if my "answer"
calls up more questions. Personally, I find that it helps to study
all of the advanced capabilities that CoreMIDI offers so as to
understand why it works the way that it does.
Brian Willoughby
Sound Consulting
On Oct 11, 2011, at 21:17, Tom Jeffries wrote:
This brings up another issue. The reason I want to use MIDI packet
lists is because of my understanding (which may be incorrect) that
they use the Coreaudio clock, which I have been told is more
accurate than NSTimer. The code I posted to the list is
simplified, the code I want to use has a (hopefully) accurate time
stamp in each call to MIDIPacketListAdd.
Do MIDI packet lists use a more accurate clock than NSTimer? My
source for that information is not associated with Apple, and it
could be that I misunderstood.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden