2012-06-12 72 views
9

保存音頻的byte []一直有一個有點麻煩,在過去的幾天裏試圖得到這個工作。但我想要的是我們有一個通過網絡發送原始數據的應用程序。然後我讀入這個二進制數據並且想把它保存到一個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。運行代碼後,您可以簡單比較兩個波形文件。如果不一樣,那麼代碼不好,或者你需要了解波形格式。 –

+0

AudioInputStream構造函數中的'length'參數應該是幀長度值而不是數據長度。 '幀長度=數據長度/信道/樣本大小的功能於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秒的聲音。它就好像它正在計算我的標題是錯誤的。我不確定這是否與劉延提到的幀長有關。

如果我的數組長度爲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千赫),所以你可以打開Media Player或QuickTime或一些文件,並確認記錄工作。一旦有效,您可以嘗試更改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);