2017-12-03 1 views
1

私は、このミキサー(この場合はWindowsシステムのステレオミックス)からオーディオバイトを読み込もうとしています。プロジェクトは2つの部分で構成されています。 AudioFormatとMixer IDは、Mixerから所定の行を開くSocket(例外をスローするもの)を介して2番目のものに送信し、オーディオバイトを読み込んでサードパーティのソフトウェアに送信します。Mixer(Stereo Mix)からバイトを読み込もうとしたときにArrayIndexOutOfBoundsExceptionが発生しました

このタスクは、次のいずれか実行するコード...

 try { 
     line = (TargetDataLine) mixer.getLine(info); 
     line.open(format); 

     int bytesRead, CHUNK_SIZE = 4096; 
     byte[] data = new byte[line.getBufferSize()/5]; 

     line.start(); 

     while (true) { 
      bytesRead = line.read(data, 0, CHUNK_SIZE); // Exception thrown in here. 
      stdout.write(data, 0, bytesRead); 
      stdout.flush(); 
     } 

    } catch (LineUnavailableException ex) { 
     System.out.println("Line is unavailable."); 
     ex.printStackTrace(); 
    } 

そして、具体的なエラーメッセージは、次の一つです...

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 800 
     at com.sun.media.sound.DirectAudioDevice$DirectTDL.read(Unknown Source) 
     at org.Main.main(Main.java:69) 

このエラーは、として私を驚くべきことです数ヶ月前に全く同じコードがテストされ、完全にバイトをstdoutを通して送信しました。

UPDATE:私は1600を言うだろう範囲例外の16ビット1つのアウトを選択した場合インデックス800範囲は、8ビットのAudioFormatのためです。

+0

スタックトレースから、使用しているライブラリでエラーが発生していて、実際のコードではないようです。 – Meepo

答えて

0

問題は、while(true)セクションによる無限ループです。配列であるlineオブジェクトを無限に読むと、特定の長さを持つことになります。したがって、800回のループの後に配列の境界に達し、読み取るべき他のオブジェクトはありません。これが、あなたがそのタイプの例外を得る理由です。

この問題を解決するには、whileループ条件内で配列の長さをチェックする必要があります。もちろん

は、Java 8のストリーム機能で

をこのジョブを実行できるコードサンプルの欠如のための私を許して。この回答を私の電話で書いています。

+0

返事をありがとうが、Oracle Webサイトの公式の例が非常によく似た方法で動作しているように見えるので、それが失敗するのは不思議です。while条件で真の値をブール変数で変更するだけです。 https://docs.oracle.com/javase/tutorial/sound/capturing.htmlでは、「TargetDataLineからのデータの読み取り」の部分を参照してください。 –

+0

公式の例では、グローバル変数 'boolean stopped'を使用しています。これは、特定の条件で値を 'false'に変更します。あなたの場合、whileループの条件は常に真であり、無限ループを意味します。 –

+0

しかし、その条件でも、ループは「無限に」実行することができます。たとえば、「開始」ボタンと「停止」ボタンがありますが、「開始」ボタンを押すだけで、一日中実行できます。これはちょうど開始時にクラッシュし、初回の繰り返しさえしません。 –

関連する問題