CoreMIDI: надежная миди-синхронизация
У меня проблемы с миди-синхронизацией. Следуя сообщениям на сайте abyte.com, я использую класс PGMidi. Синхронизация работает, но постоянно смещается до 1-2 ударов в минуту.
Вот код, который я использую:
- (void)sendMidiClockInMidiThread {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[lock lock];
const int64_t kOneMillion = 1000 * 1000;
const UInt8 tick[] = { 0xF8 };
// Calculate tick time
// returns sample for sixteen note (5512 if current bpm is 120)
SInt32 sixteen = AGGetSamples_SixteensWithoutSwing(_grid, 1.0);
UInt64 tickTime = (sixteen / 6) * kOneMillion;
int tickLatency = 0;
// Send ticks messages
for (int i = 0; i < 6; ++i) {
int beginTime = clock();
hostTime = hostTime + (tickTime - tickLatency);
[self.midi sendBytes:tick size:sizeof(tick) atTime:hostTime];
int endTime = clock();
tickLatency = endTime - beginTime;
}
[lock unlock];
[pool drain];
}
Подскажите пожалуйста как получить четкую синхронизацию.
1 ответ
Во-первых: откуда вызывается это сообщение? Какой у тебя таймер? Вы должны убедиться, что вы используете очень точный таймер. По сути, вам понадобится что-то более 10 мс (20 мс - период тактового импульса MIDI, 24 импульса на четвертную ноту, 120 четвертных нот в минуту).
Этот парень сделал довольно приличную запись примитивов синхронизации, доступных на iOS / MacOS.
Его худший случай здесь (который включает в себя спин-блокировку) все еще выключен почти на 50 мс в худшем случае, и выключен на 14 мс в среднем случае. Это абсолютно ужасное время для MIDI. Лучше всего запустить поток CoreAudio (или поток в реальном времени, используя информацию, доступную здесь).