2016-12-13 4 views
0

Java Sound APIのパフォーマンス(レイテンシ)問題があると思います。Java Sound API:ライブマイクの入力監視が遅い

オーディオモニター

次のコードは、実際に私のために働くありません。マイクを正しく開き、スピーカーからリアルタイムで音声入力を出力します(モニタリング)。しかし、私の懸念は、再生が起こるスピードです...スピーカーから再生するまでにマイクに向かって話すときから0.5秒遅れです。

パフォーマンスを向上させるにはどうすればよいですか?どのようにレイテンシを下げるのですか?このコードで

private void initForLiveMonitor() { 

    AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false); 

    try { 

     //Speaker 
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 
     SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(info); 
     sourceLine.open(); 

     //Microphone 
     info = new DataLine.Info(TargetDataLine.class, format); 
     TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(info); 
     targetLine.open(); 

     Thread monitorThread = new Thread() { 
      @Override 
      public void run() { 
       targetLine.start(); 
       sourceLine.start(); 

       byte[] data = new byte[targetLine.getBufferSize()/5]; 
       int readBytes; 

       while (true) { 
        readBytes = targetLine.read(data, 0, data.length); 
        sourceLine.write(data, 0, readBytes); 
       } 
      } 
     }; 

     System.out.println("Start LIVE Monitor for 15 seconds"); 
     monitorThread.start(); 

     Thread.sleep(15000); 
     targetLine.stop(); 
     targetLine.close(); 
     System.out.println("End LIVE Monitor"); 

    } 
    catch(LineUnavailableException lue) { lue.printStackTrace(); } 
    catch(InterruptedException ie) { ie.printStackTrace(); } 


} 

追記

  • 、再生は、遅延ちょうど半分秒(NOポップやジッタ)滑らかです。
  • Logic Pro Xとのサイドバイサイド比較で遅延が最小限に抑えられているため、コンピュータとUSBオーディオインターフェイスでコンピュータのリアルタイムモニタリングを処理できることも知っていますまったく。
  • byte []のサイズを小さくしたり大きくしたりする試みは、この問題には役立ちませんでした。

私の結論は、これは私が持っているJavaコードの問題です。前もって感謝します。

+0

'targetLine.getBufferSize()'がどのくらいの大きさになっているかは分かります。それは何バイトですか? –

+0

@AndrewThompson 'targetLine.getBufferSize()'メソッドは、88200バイトを返します。私はすでにほとんど変化のないバイト[]の除数で演奏してきました。 'byte []'を明示的に4バイトにすると、本当に助けになりましたが、私はまだ0.5秒以上の遅延から1/4秒の遅延を感じています。 –

+0

設定したbyte []のサイズは、DataLineのバッファには関係しません。 DataLineのバッファサイズを設定するには、open()メソッドにサイズを含める必要があります。 .open(サイズ)。 1フレームあたり4バイトで88200バイト、1秒間に44100フレームは、0.5秒の遅延を説明します。あまりにも短くするとドロップアウトが発生する可能性がありますが、待ち時間の少ない安全な値を設定できます。下の私の答えを見てください。 –

答えて

1

複数のバッファが含まれています。

SourceDataLineとTargetDataLineを開くときに、バッファサイズを指定するフォームを使用することをお勧めします。しかし、私はどのサイズを推奨するのか分かりません。私はこれを使って、マイク入力を安全に配管するのに最適なサイズが何であるかを知ることができませんでした。私の経験は、リアルタイムシンセシスによるものです。

とにかく、データの長さ[]を定義し、ラインの開始方法で同じ長さを使用します。 1024または倍数のような数字を試してください(使用しているフォーマットに応じて4バイトに見えるバイト数をフレームごとのバイト数で均等に分割できるようにしてください)。配管にも開始する前に必要な処理を追加しないように

int bufferLen = 1024 * 4; // experiment with buffer size here 

byte[] data = new byte[bufferLen]; 
sourceLine.open(bufferLen); 
targetLine.open(bufferLen); 

はまた、あなたの目で多分コードは()よりよい他の場所に置かれることになります。配列data []とint readBytesはインスタンス変数で、run()に潜んでいるのではなく、ロールする準備ができている可能性があります。

これは、とにかく私が試してみたいものです。

+0

"配列data []とint readBytesはインスタンス変数で、run()に潜んでいるのではなく、ロールする準備ができています。これらは大きなジャガイモの小さなチップです。もし彼が彼が異なるバッファサイズを試したと言うなら、それはそれです! - "複数のバッファが含まれています!"どこで具体的に知りたいですか?彼のパフォーマンスに影響するだろう – gpasch

+0

APIはDataLinesのバッファサイズを明示的に述べています。 http://docs.oracle.com/javase/8/docs/api/javax/sound/sampled/SourceDataLine.html#open-javax.sound.sampled.AudioFormat-int- TargetDataLineもあります。 –

+0

ありがとうございました。はい、両方のopen()メソッドに対してbufferSizeを設定すると、レイテンシは実際に下がりました。レイテンシーが10分の1秒に改善されていると私は推測しています(1/4秒より良い)。そして、バッファサイズ1024 * 2で実験すると、歪みの問題を起こすことなく動作しました。下のどこかに行くと、聞こえる問題が発生しました。 –

関連する問題