2

ある期間にイベントがトリガーされた時期に基づいた時間値を表すfloatの配列があります。

0: time stored: 1.68
1: time stored: 2.33
2: time stored: 2.47
3: time stored: 2.57
4: time stored: 2.68
5: time stored: 2.73
6: time stored: 2.83
7: time stored: 2.92
8: time stored: 2.98
9: time stored: 3.05

ここで、タイマーを開始し、タイマーが1秒687ミリ秒(配列の最初の位置)に達したときに、イベントがトリガーされる/メソッドが実行されるようにします。タイマーが2秒と337ミリ秒に達すると、2番目のメソッドの実行がトリガーされ、配列の最後の要素が3秒と56ミリ秒になり、最後のイベントがトリガーされます。

どうすればこのようなものを模倣できますか?高精度なものが必要です

私が本質的に求めているのは、サウンドを時間どおりに再生するための高精度のメソッド呼び出しでメトロノームを作成する方法だと思いますか?

4

3 に答える 3

4

…高精度のメソッド呼び出しでメトロノームを作成して、時間どおりにサウンドを再生するにはどうすればよいですか?

オーディオクロックを使用します。これは、通常必要なすべての精度(オーディオ再生のサンプルレート-たとえば44.1kHz)-ではありませんNSTimer

具体的には、サンプラー(AudioUnitなど)を使用してMIDIイベントをスケジュールするか、テンポによって決定されるサンプル位置でオーディオストリーミングコールバックの(プリロードされた)クリックサウンドのサンプルデータでバッファーを埋めることができます。

1ms以上を維持するには、常にオーディオクロックに基づいてタイミングを調整する必要があります。テンポによってフレームの間隔が決まるため、これは非常に簡単です。

(ほとんどの人にとって)難しい部分は、以前にそのドメインで作業したことがない場合、リアルタイムコンテキストでの作業とオーディオフレームワークの使用に慣れることです。

于 2012-04-21T07:17:29.917 に答える
2

高精度のタイミングを得るには、プログラミングレベルを1〜2下げて、サンプル精度のタイミングを提供するCore Audio Unitフレームワークのようなものを利用する必要があります(44100kHzでは、サンプルは約0.02msごとに発生する必要があります)。

このアプローチの欠点は、そのようなタイミングパフォーマンスを得るために、CoreAudioUnitプログラミングがObjective-CをC/C ++アプローチに使用しないことです。これは、(私の意見では)Objective-Cよりもコーディングが困難です。コアオーディオユニットの動作方法も、特にオーディオDSPのバックグラウンドがない場合は、非常に混乱します。

Objective-Cにとどまると、NSTimersがここでのオプションではないことをおそらくご存知でしょう。AVFoundationフレームワークをチェックしてみませんか?正確なメディアシーケンスに使用でき、少し創造的な水平思考とAVURLAssetAVURLAssetPreferPreciseDurationAndTimingKeyのオプションを 使用すると、CoreAudioUnitを使用せずに目的を達成できる可能性があります。


について詳しく入力するためにAVFoundation、のインスタンスを(オブジェクトを介して)に配置AVAssetAVMutableComposition、インスタンスを持つオブジェクトをAVMutableCompositionTrack使用して結果を制御できます。AVPlayerItem通知(docs)を使用して、個々のアセットがいつ終了するかを判断できます。また、AVPlayerメソッドを使用して、任意の時間に通知を提供できます。AVPlayerItemAVPlayerAVPlayerItemDidPlayToEndTimeNotificationaddBoundaryTimeObserverForTimes:queue:usingBlock:addPeriodicTimeObserverForInterval:queue:usingBlock:

iOSでは、アプリがオーディオを再生する場合、これをすべてバックグラウンドスレッドで実行することもできます。つまり、アプリがバックグラウンドにある間、時間を保つことができます(ただし、警告、オーディオが再生されない場合、Appleはこのバックグラウンドモードを使用してアプリを受け入れないでください)。詳細については、 UIBackgroundModesのドキュメントをご覧ください。

于 2012-04-21T07:34:54.737 に答える
2

調べてくださいdispatch_after()。のようなものを使用して、その目標時間を作成しますdispatch_time(DISPATCH_TIME_NOW, 1.687000 * NSEC_PER_SEC)


更新:任意の作業を行うのではなく、特定の時間にのみサウンドを再生する場合は、特定の時間に再生をスケジュールできるオーディオAPIを使用する必要があります。私はAudioQueueAPIに最も精通しています。キューを作成し、2つまたは3つのバッファーを作成します。(オーディオが常に同じである場合は2。動的にロードまたは計算する場合は3。)次に、AudioQueueEnqueueBufferWithParameters()特定の開始時刻で各バッファーをキューに入れるために使用します。オーディオキューは、要求された開始時間に可能な限り近い再生を処理します。代替案を手動でコーディングすることで、その精度を打ち負かすつもりはないと思います。キューは処理されたバッファを返すので、必要に応じてそれを補充し、次回キューに入れます。

AVFoundationには、特定の時間に再生をスケジュールするための同様の機能が必要だと確信していますが、私はそれに精通していません。

于 2012-04-21T11:10:11.613 に答える