1

別のフォーラムで、MIDI イベント (Note On メッセージなど) を正確に生成することについて、何人かの開発者と議論しています。人間の耳はわずかなタイミングの不正確さに非常に敏感であり、主な問題は、イベントを約 15 ミリ秒間隔で量子化する比較的低解像度のタイマーを使用していることにあると思います (これは、知覚できる不正確さを引き起こすのに十分な大きさです)。

約 10 年前、私はソフトウェア シンセサイザーと MIDI プレーヤーを組み合わせたサンプル アプリケーション (Windows 95 上の Visual Basic 5) を作成しました。基本的な前提は、各バッファーが 16 分音符のデュレーションであるリープフロッグ バッファー再生システムでした (例: 1 分あたり 120 の 4 分音符の場合、各 4 分音符は 500 ms であり、したがって各 16 分音符は 125 ms であったため、各バッファーはバッファは 5513 サンプルです)。各バッファは waveOutWrite メソッドを介して再生され、このメソッドからのコールバック関数を使用して、次のバッファをキューに入れ、MIDI メッセージを送信しました。これにより、WAV ベースのオーディオと MIDI オーディオの同期が保たれました。

私の耳には、この方法は完璧に機能しました。MIDI ノートはわずかにずれても聞こえませんでした (一方、15 ミリ秒の精度の通常のタイマーを使用して MIDI ノートを再生すると、著しくずれて聞こえます)。

理論的には、この方法は、サンプル、つまり 0.0227 ミリ秒 (1 ミリ秒あたり 44.1 サンプルがあるため) に対して正確な MIDI タイミングを生成します。バッファが終了してから waveOutWrite コールバックが通知されるまでの間にわずかな遅延があると思われるため、これがこのアプローチの真のレイテンシであるとは思えません。この遅延が実際にどれくらい大きくなるか知っている人はいますか?

4

3 に答える 3

5

Windowsスケジューラは、プロセッサに応じて、デフォルトで10ミリ秒または16ミリ秒の間隔で実行されます。timeBeginPeriod()APIを使用する場合は、この間隔を変更できます(かなりの電力消費コストがかかります)。

WindowsXPおよびWindows7では、Wave APIは約30ミリ秒の遅延で実行されますが、Windows Vistaの場合、WaveAPIの遅延は約50ミリ秒です。次に、オーディオエンジンのレイテンシーを追加する必要があります。

残念ながら、一方向のエンジンレイテンシーの数値はありませんが、エンジンレイテンシーに関する数値はあります。USBオーディオデバイスを介してループバックされたトーンを再生するテストを実行し、ラウンドトリップレイテンシーを測定しました(レンダリング先キャプチャー)。Vistaでは、往復の遅延は約80ミリ秒で、変動は約10ミリ秒でした。Win7では、往復の待ち時間は約40ミリ秒で、変動は約5ミリ秒でした。ただし、YMMVは、オーディオハードウェアによって導入される遅延の量が、ハードウェアごとに異なるためです。

XPオーディオエンジンまたはWin9xオーディオスタックのレイテンシーが何であったかはまったくわかりません。

于 2009-08-23T16:50:07.737 に答える
1

非常に基本的なレベルでは、Windows はマルチスレッド OS です。また、100 ミリ秒のタイム スライスでスレッドをスケジュールします。つまり、CPU の競合がなければ、バッファの最後と waveOutWrite コールバックの間の遅延は任意に短くなる可能性があります。または、他のビジー スレッドがある場合は、スレッドごとに最大 100 ミリ秒待機する必要があります。ただし、最良のケースでは... 現在、CPU の速度は GHz でクロックインしています。これにより、コールバックを 0.000,000,000,1 秒単位で呼び出すことができる絶対的な下限が設定されます。

1 秒間に処理できる waveOutWrite コールバックの最大数を把握できない限り、これは各呼び出しの遅延を意味する可能性があります。使用中のスレッドが多すぎます。その場合、恐ろしく、恐ろしく間違っています。

于 2009-08-20T09:15:35.647 に答える
1

上記の素晴らしい回答に追加します。

あなたの質問は、Windows が気にしないと約束した待ち時間に関するものです。そのため、OS のバージョン、ハードウェア、その他の要因によって、かなり異なる場合があります。WaveOut API と DirectSound も (WASAPI についてはわかりませんが、この最新の Vista+ オーディオ API にも当てはまると思います)、すべてバッファリングされたオーディオ出力用に設定されています。特定のコールバック精度は、現在の再生がまだ行われている間に次のバッファーをキューに入れている限り、必要ありません。

オーディオの再生を開始するときは、再生中にアンダーフローが発生せず、すべての出力が連続しており、オーディオ クロック レートが正確に 44,100 Hz など、予想どおりであるなど、いくつかの前提条件があります。次に、時間をサンプルに変換してからバイトに変換する簡単な計算を行い、時間内にウェーブ出力をスケジュールします。

残念ながら、有効な再生レートは正確ではありません。たとえば、実際のハードウェアのサンプリング レートが 44,100 Hz -3% であると想像してみてください。オーディオ ハードウェアを再生クロックにしてビデオを同期する (これがプレーヤーの動作方法です) など、この効果を補う試みや、受信データ レートをハードウェアの実際の再生レートに一致させるレート マッチング技術が行われています。これらはどちらも、問題の絶対時間測定とレイテンシーをかなり推測的な知識にします。

さらに、API のレイテンシは 20 ミリ秒、30 ミリ秒、50 ミリ秒などです。昔から、waveOut API は他の API の上にあるレイヤーです。これは、データが実際にハードウェアに到達する前に何らかの処理が行われることを意味します。この処理では、事前にキューに入れられたデータから手を離す必要があります。そうしないと、データがハードウェアに到達しません。再生時間の直前に 10 ミリ秒のバッファーでデータをキューに入れようとすると、API はこのデータを受け入れますが、このデータを下流に渡すのが遅くなり、スピーカーに無音または快適なノイズが発生します。

これは、受信するコールバックにも関連しています。バッファのレイテンシは気にせず、重要なのは正確なコールバック時間だと言えます。ただし、API は階層化されているため、内層の同期の正確さでコールバックを受け取ります。このような 2 番目の内層はフリー バッファーについて通知し、最初の内層はそのレコードを更新し、バッファーも解放できるかどうかを確認します (これらのバッファーは解放されません)。 t も一致する必要があります)。これにより、コールバックの精度に対する期待は非常に弱く、信頼できなくなります。

かなり長い間 waveOut API に触れていなかったとしても、同期の精度についてこのような疑問が生じた場合、まず最初に次の 2 つのことを考えるでしょう。

  • Windows は、オーディオ ハードウェア クロックへのアクセスを提供します (私は、DirectShow を介して利用可能な IReferenceClock インターフェイスを認識しており、おそらくアクセス可能な別の低レベルのものから来ている可能性があります)。

  • Microsoft の最新のオーディオ API である WASAPI は、メディア スレッド スケジューリングの改善、排他モード ストリーム、PCM の 10 ミリ秒未満の遅延など、新しい優れた機能を備えた低遅延オーディオの特別なサポートを提供します。これは、より良い同期が見られる場所です。

于 2011-10-08T17:39:54.253 に答える