Re: Timing mechanism for MIDI ?
Re: Timing mechanism for MIDI ?
- Subject: Re: Timing mechanism for MIDI ?
- From: Peter Johnson <email@hidden>
- Date: Wed, 10 Dec 2008 13:10:20 -0800 (PST)
Hi
Yes the thread relies on [NSThred sleepUntilDate] but that's not a problem as NSThread is a wrapper around the POSIX pthreads (sleepUntilDate is probably implemented with something like pthreads_cond_wait) which is as low level as you can go in user-space.
In my sequencer, I do exactly what Brian describes. I have a window of events which are queued ahead of where the actual transport play head is, in my case it's an arbitrary 10 PPQN. I have only 2 threads, one for the timer and one for the sequencer. When playback begins, I start both threads and take a starting time reference using AudioGetCurrentHostTime(). The sequencer thread then sleeps on a semaphore. When the timer thread ticks over, it signals (polls) the sequencer thread. The sequencer thread then looks for events between now + look_ahead and sends them to CoreMIDI with time stamps into the future.
When the sequencer schedules a MIDI event for transmission it sets the event's time to some future time. I use a functions like these to convert between sequencer clocks (PPQN values incremented by the timer thread) and nanoseconds for CoreMIDI, thus:
class Clock is in PPQN
const int32 Clock::PPQN = 480;
const int32 CLOCKS_PER_MINUTE = 60000;// 1 minute milliseconds
const uint64 CLOCK_DIVISOR = 1000000;// nanos to millis
int32 blah::clock_to_ms(const Clock& time)
{
return ((time - start_clock) * (CLOCKS_PER_MINUTE / Clock::PPQN) / tempo);
}
void blah::send(MIDI_event e)
{
MIDITimeStamp nsec = static_cast<uint32>(clock_to_ms(e.time)) * CLOCK_DIVISOR;
midi_tx(e.data, nsec);
}
void blah::midi_tx(you_data data, MIDITimeStamp nsec)
{
Byte midi[] = { (/* your data */ };
MIDIPacketList packetList;
MIDIPacket* packetPtr = MIDIPacketListInit(&packetList);
packetPtr = MIDIPacketListAdd(&packetList, sizeof packetList, packetPtr, AudioConvertNanosToHostTime(nsec), 3, (const Byte*) &midi);
MIDIReceived(info.dest, &packetList);
}
_______________________________________________
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