2012-06-12 27 views
9

これを動作させようと数日間問題が発生しました。しかし私が望むのは、ネットワーク上で生データを送信するアプリケーションがあるということです。私はこのバイナリデータを読み込んで、それをwav(任意のオーディオ)ファイルに保存します。後で圧縮を見るかもしれない。オーディオバイト[]をwavファイルに保存

だから、問題のあるコード:

byte[] allBytes = ... 
InputStream b_in = new ByteArrayInputStream(allBytes); 

try 
{ 
    AudioFormat format = new AudioFormat(8000f, 16, 1, true, true); 
    AudioInputStream stream = new AudioInputStream(b_in, format, allBytes.length); 
    //AudioInputStream stream = AudioSystem.getAudioInputStream(b_in);     

は、同様に上記のステートメントを使用しようとしましたが、私は例外を取得:javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from streamを。だから私の考えは、私のストリームは生のオーディオデータであり、これは例外をスローしているウェーブヘッダを持たないからです。

File newPath = new File(SystemConfiguration.getLatest().voiceNetworkPathDirectory + currentPhoneCall.fileName); 
if (!AudioSystem.isFileTypeSupported(Type.WAVE, stream)) 
{ 
    Logger.error("Audio System file type not supported"); 
} 

AudioSystem.write(stream, Type.WAVE, newPath); 

ファイルが正常に書くんが、それはすべて静的ですが、私はthisのようなものを使用して、出力の波ヘッダーを作成する必要があります。メモ帳で出力されたwavファイルを見ると、「RIFF」で始まるヘッダーがあるようです。

入力ストリームに偽のヘッダーを追加する必要がありますか?私は自分の出力ヘッダーを作成してバイナリライターで保存するだけですか?

+0

あなたの投稿に何か問題があります。データ/書式が欠落しています。 – user845279

+1

他の有効なWAVEファイルと比較するとどうですか?それらのいずれかを選択すると、ヘッダーの後にデータをコピーし、生データを配列allBytesにコードに置きます。コードを実行したら、2つのwaveファイルを単純に比較できます。それが同じでない場合、いずれかのコードが悪いか、波のフォーマットのベライターを理解する必要があります。 –

+0

'AudioInputStream'のコンストラクタの' length'引数は、データ長ではなくフレーム長の値でなければなりません。 'frame-length = data-length/channel/sample-size-in-byte' –

答えて

2

だから私は終わった、それがなぜ本当にわからなく、働いて得るが、これは働いているコードです。

InputStream b_in = new ByteArrayInputStream(resultArray); 
try { 
     DataOutputStream dos = new DataOutputStream(new FileOutputStream(
       "C:\\filename.bin")); 
     dos.write(resultArray); 
     AudioFormat format = new AudioFormat(8000f, 16, 1, true, false); 
     AudioInputStream stream = new AudioInputStream(b_in, format, 
       resultArray.length); 
     File file = new File("C:\\file.wav"); 
     AudioSystem.write(stream, Type.WAVE, file); 
     Logger.info("File saved: " + file.getName() + ", bytes: " 
       + resultArray.length) 

したがって、私の署名付き/未署名/リトルエンディアンの設定である必要があります。私がやったことは、データをバイナリファイルに保存することでした。次に、そのファイルを大胆に生データとしてインポートします。これは、私がすでに新しいレート以外のすべてを教えてくれました。 私が今問題にしているのは、ヘッダ計算だけです。私は4秒のwavを生成するバイナリデータを保存しますが、それはたった2秒のサウンドしか持っていません。それは私のヘッダーを間違って計算しているかのように。 LiuYanが言及したフレームの長さと関係があるかどうかはわかりません。

配列の長さが160の場合、これはフレーム長が10であることを意味しますか? 160/1/16。 これを行うと、バイナリファイルに10バイトのデータしか保存されません。

+0

それ以外は、フレーム長が16であると仮定していたオーディオで問題が発生しました.... しかし、format.getFrameSize()の値が2であることを確認したとき AudioInputStream stream = new AudioInputStream b_in、format、 \t \t \t \t \t resultArray.length/1/format.getFrameSize()); – user1434177

1

エラーがどこにあるのかを知るのは難しいですが、ヘッダーがあることを意味するファイルを開いたときに 'RIFF'が表示されているときは、質問に答えてください。あなた自身のヘッダーを構築しようとすることは可能ですが、少し時間がかかります(必要があるので不要です)。

読み込み時に、手動で指定するのではなく、ファイル自体からフォーマットを取得するのが最も安全です。エラーが発生しにくくなります。そのためのサンプルコードはここにあります:書き込むとき

http://www.jsresources.org/examples/SimpleAudioPlayer.java.html

、あなたは「ファイルが正常に書くんが、それはすべての静的がある」と言う - あなたはあなた自身のJavaコード以外のものであることを確認していますか?たぶん私は正しく理解していないかもしれませんが、新鮮なJavaコードでWAVファイルを録音して再生しようとしているように聞こえますが、その場合は、録音や再生に何か問題があるかどうかを判断するのは難しいです。

メディアプレーヤーやクイックタイムなどでファイルを開き、録音が正常に動作するように、バニラ形式(16ビット、ステレオ、非圧縮、44,100 kHz)から開始する必要があります。それが機能すると、SRなどを変更しようとすることができます。録音用のサンプルコードを次に示します。 、それを起動し、それが動作することを確認し、その後、より複雑なものに移動:

http://www.jsresources.org/examples/SimpleAudioRecorder.java.html

0

AudioFormatのエンコードとフレームサイズとフレームレートを設定してみてください。

new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
        8000f, 
        16, 
        1, 
        2, // frameSize 
        8000f,// frameRate 
        false); 
関連する問題