• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Timing mechanism for MIDI ?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

  • Follow-Ups:
    • Re: Timing mechanism for MIDI ?
      • From: William Stewart <email@hidden>
  • Prev by Date: Setting input frequency on Apple Built-in Digital Input
  • Next by Date: Re: Setting input frequency on Apple Built-in Digital Input
  • Previous by thread: Fwd: Timing mechanism for MIDI ?
  • Next by thread: Re: Timing mechanism for MIDI ?
  • Index(es):
    • Date
    • Thread