2012-03-16 5 views
1

미디 동기화에 문제가 있습니다. syntheticbits.com의 게시물에 이어 PGMidi 클래스를 사용합니다. 동기화는 작동하지만 지속적으로 1-2bpm으로 이동합니다.CoreMIDI : 단색 미디 동기화

- (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]; 
} 

방법 명확한 동기를 얻는 방법을 가르쳐주세요 : 여기

은 내가 사용하는 코드입니다.

답변

0

첫 번째 :이 메시지는 어디에서 전화가 왔습니까? 너의 타이머가 뭐니? 매우 정확한 타이머를 사용해야합니다. 근본적으로 10ms보다 더 엄격한 것이 필요합니다 (20ms는 MIDI 클럭 펄스의주기입니다, 4 분 음표 당 24 개의 펄스, 분당 120 분 음표).

This guy iOS/MacOS에서 사용할 수있는 동기화 프리미티브에 대해 꽤 괜찮은 글을 올렸습니다.

여기서 최악의 경우 (스핀 록킹과 관련된) 최악의 경우는 최악의 경우 약 50ms, 평균 경우는 14ms 정도 떨어져 있습니다. 이것은 MIDI에 대한 절대적인 끔찍한 타이밍입니다. 가장 좋은 방법은 CoreAudio 스레드 (또는 사용 가능한 정보 here을 사용하는 실시간 스레드)를 시작하는 것입니다.