iPhone で簡単なオーディオ シーケンサーをプログラムしたいのですが、正確なタイミングを取得できません。ここ数日、AudioServicesPlaySystemSound と AVAudioPlayer と OpenAL から AudioQueues に至るまで、iphone で可能なすべてのオーディオ技術を試しました。
前回の試みでは、openAL を使用し、サウンドを複数のバッファにロードして、必要なときにいつでも再生できる CocosDension サウンド エンジンを試しました。基本的なコードは次のとおりです。
初期化:
int channelGroups[1];
channelGroups[0] = 8;
soundEngine = [[CDSoundEngine alloc] init:channelGroups channelGroupTotal:1];
int i=0;
for(NSString *soundName in [NSArray arrayWithObjects:@"base1", @"snare1", @"hihat1", @"dit", @"snare", nil])
{
[soundEngine loadBuffer:i fileName:soundName fileType:@"wav"];
i++;
}
[NSTimer scheduledTimerWithTimeInterval:0.14 target:self selector:@selector(drumLoop:) userInfo:nil repeats:YES];
初期化では、サウンド エンジンを作成し、いくつかのサウンドを異なるバッファーにロードしてから、NSTimer でシーケンサー ループを確立します。
オーディオ ループ:
- (void)drumLoop:(NSTimer *)timer
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
}
それだけで、正常に動作しますが、タイミングが不安定で不安定です。他の何かが発生するとすぐに (ビューでの ig 描画)、同期が取れなくなります。
私がサウンドエンジンとopenALを理解しているように、バッファは(initコードで)ロードされ、すぐに開始する準備ができていalSourcePlay(source);
ます.NSTimerに問題があるのでしょうか?
現在、アプリストアには数十のサウンド シーケンサー アプリがあり、それらは正確なタイミングを持っています。Ig "idrum" は、ズームと描画を行うと 180 bpm でも完全に安定したビートを持っています。したがって、解決策があるはずです。
誰にもアイデアはありますか?
事前に助けてくれてありがとう!
よろしくお願いします、
ウォルキー
ご回答有難うございます。それは私をさらに一歩進めましたが、残念ながら目標には達しませんでした. これが私がしたことです:
nextBeat=[[NSDate alloc] initWithTimeIntervalSinceNow:0.1];
[NSThread detachNewThreadSelector:@selector(drumLoop:) toTarget:self withObject:nil];
初期化では、次のビートの時間を保存し、新しいスレッドを作成します。
- (void)drumLoop:(id)info
{
[NSThread setThreadPriority:1.0];
while(1)
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
NSDate *newNextBeat=[[NSDate alloc] initWithTimeInterval:0.1 sinceDate:nextBeat];
[nextBeat release];
nextBeat=newNextBeat;
[NSThread sleepUntilDate:nextBeat];
}
}
シーケンス ループでは、スレッドの優先度をできるだけ高く設定し、無限ループに入ります。サウンドを再生した後、次のビートの次の絶対時間を計算し、その時間までスレッドをスリープ状態にします。
繰り返しますが、これは機能し、NSThread なしで試した場合よりも安定して動作しますが、何か他のことが発生した場合、特に GUI の問題が発生した場合でも不安定です。
iphone で NSThread を使用してリアルタイムの応答を取得する方法はありますか?
よろしくお願いします、
ウォルキー