0

私は Java で DAW を作成していますが、実際にはそれよりも基本的なもので、かつて所有していた古い Tascam 4 トラック レコーダーをモデルにしています。2 つの間のレイテンシー (遅延) をできるだけ少なくして、録音しながらオーディオをモニターしようとしています。オーディオバイトを読み込んでいる同じスレッドに書き込むと、かなりの量のレイテンシーが発生します(コードを見たい場合は投稿しますが、書き直す必要があると思われるため、無関係に思えました) . 私が考えていたのは、プロデューサー、コンシューマー スレッド、およびキューを使用して、その間にバイトのチャンクを格納することです。私のプロデューサースレッドはTargetDataLineそれらをキューに格納します。おそらく、読み取ったバイト数を返すメソッドを使用して、while ループで EOF をチェックできるようにします。そして、キューに格納されたバイトのチャンクを (書き込み対象のバイトの場合) 取得し、SourceDataLine. 私の考えでは、同時に実行されている2つのスレッドは、読み取られるのとほぼ同時にバイトを書き込むことができるか、少なくとも私が現在持っているものよりも優れていると思いますが、他の人がこの問題をどのように解決したか知りたいです.

また、キューにバイトがない場合は消費者スレッドが待機し、バイトが追加されてバイトの書き込みが再開されたときに通知されるようにする必要があります.2つのスレッドを同期する適切な方法の例を誰かが投稿する場合は、感謝します。複数のロックを使用する必要がありますか? オーディオに固有の例を求めているのではなく、コレクションに何かを追加してから削除する一般的な例を求めているわけではありません。ありがとう。

4

1 に答える 1

1

「古典的な」Java では、生産者と消費者の実装に単一のロック オブジェクトを使用できます (そしておそらく使用する必要があります)。何かのようなもの

public final static Object LOCK = new Object();

次に、 Produce() メソッドで次のようなコードを作成します。

synchronized(LOCK) {
   //place stuff in queue
   LOCK.notifyAll(); //wake up any sleepers
}

そして、あなたの consumer() メソッドには、反対側があります:

synchronized(LOCK) {
   if (anything in queue) {
      return something
   }
   //queue is empty - wait
   while (nothing in queue) { //while bit is important - we might wakeup for no reason or someone else might grab everything leaving us with nothing
      try {
         Lock.wait();
      } catch (InterruptedException ex) {
         //99% of java code ignores these spurious wakeups, and they also hardly ever really happen
      }
   }
}

しかし、これは古い学校です。Java の最新バージョンには、この低レベルのブードゥー教のすべてをきちんとラップするクラスがあります。たとえばArrayBlockingQueue。「グローバル」静的キューを定義してから、それぞれ offer() と take() を使用して、それぞれ Produce() と consumer() の実装を行うことができます。

しかし、あなたが本当にレイテンシに関心があるなら、私はさらに一歩進んで、低レイテンシのスレッド間通信用に正確に書かれたライブラリを使用します. そのようなライブラリの良い例は、ArrayBlockingQueue よりもはるかに優れたレイテンシを主張するディスラプターです。

于 2013-04-11T05:24:04.760 に答える