私は、0.25秒ごとにシステム音を鳴らして、簡単なメトロノームを書こうとしています。私は別のスレッド上でクリックを再生するためにGCDを使用していますが、クリックは2回の速いビートと遅いビートの後にくることがあります。ループのif文が実行された時刻と0.25秒後の時刻を記録しました。 Audio Queue Servicesを使用する必要はありません。助言がありますか?彼らはいずれかの特定のハードウェア/ OS用に開発されていないもののシンプルなメトロノーム
- (IBAction)start:(id)sender
{
dispatch_queue_t clickQueue; // the queue to run the metronome clicker
dispatch_queue_t mainQueue; // I access the main queue to demonstrate how to change UIKit items
//clickQueue = dispatch_queue_create("clickQueue", NULL);
clickQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
mainQueue = dispatch_get_main_queue();
dispatch_async(clickQueue, ^{
double timeWas = [NSDate timeIntervalSinceReferenceDate];
//delay by a 1/10 of a second so the first few clicks don't bunch up.
double timeIs = [NSDate timeIntervalSinceReferenceDate] - 0.1;
// playing starts out as NO because it gets switched at the end of the loop
// and the PlaySystemSound block isn't off the queue yet. There is probably a
// better way to do this.
while (playing) {
timeIs = [NSDate timeIntervalSinceReferenceDate] ;
if ((timeIs - timeWas) > (60.0/240)) {
AudioServicesPlaySystemSound(sound);
timeWas = timeIs;
// I want to flast the 200 label between orange and black but I have to access
// user interface objects from the queue that they are running in, usually the
// main queue.
dispatch_async(mainQueue, ^{
if (flash)
[bpm setTextColor:[UIColor orangeColor]];
else
[bpm setTextColor:[UIColor blackColor]];
flash = !flash;
});
}
}
});
playing = !playing;
if (playing)
[startButton setTitle:@"Stop" forState:UIControlStateNormal];
else
[startButton setTitle:@"Start" forState:UIControlStateNormal];
}
...あなたのコンテキストで非常に興味深いであるhttp://atastypixel.com/blog/experiments-with-precise-timing-in-ios/をも読み取ることができますAVFoundationによって導入された遅れはあなたのタイミングを捨てます。いくつかの状況では許容できる程度に近いかもしれませんが、メトロノームの場合、より正確なタイミングが必要になります。 –