2014-11-06 22 views
0

我正在製作一個修改原始聲音的程序。需要此流程的幫助(AudioInputStream - >字節數組 - > AudioOutputStream)

我的程序的過程就在這裏。

  1. 獲取聲音從的AudioInputStream
  2. 更改聲音數據爲字節數組。(我的AudioFormat的幀大小是,所以,我會用字節數組長度)
  3. 修改字節數組(類似於「乘以-1到每個元素」
  4. 發送修改的字節數組到AudioOutputStream
  5. 發出聲音。

我做的過程1,2和3

這裏是我的CODE過程1,2,3

try { 
    byte[] packet = new byte[4]; 
    int result; 

    while((result = audioInputStream.read(packet)) != -1) 
    for(int i = 0;i < 4;i++) 
     reflectedPacket[i] = (byte)(-1 * packet[i]); 

     //I think I have to do something to send packet to AudioOutputStream in here 
    } 
catch(IOException ioe) { 
    System.out.println(ioe.getMessage()); 
} 

不過,我不知道該怎麼辦過程4 ,發送改性字節數組AudioOutputStream

只見其使用源的ByteArray的InputStream。

然而,這是源讀取文件,而不是AudioInput :(

我怎樣才能做到過程4和5?

回答

0

我不認爲你是你的audioInputStreambyte陣列正確讀取。試着用替換你while和嵌套循環for

int framesize = 4; 
byte[] packet = new byte[framesize]; 
int numBytesRead = audioInputStream.read(packet, 0, framesize); 
for(int i = 0; i < numBytesRead; i++) 
    reflectedPacket[i] = (byte)(-1 * packet[i]); 

順便說一句,我認爲這是一個修飾的非常方式您的音頻流。請查看Java Sound Info頁面和此post以獲取修改音頻流的一些有用鏈接。

反正....一旦你已經修改了你的音頻流,你可以使用AudioSystem.getAudioInputStream(java.io.InputStream),執行你的第4步,就像這樣:

AudioInputStream newStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(reflectedPacket)); 

最後,你將需要Clip接口播放聲音:

Clip clip = AudioSystem.getClip(); 
clip.open(newStream); 
0

您正在查找的'AudioOutputStream'被稱爲SourceDataLine。它可以從AudioSystem獲得,並且有一個tutorial here

然而,作爲一個警告,

我的AudioFormat的幀大小爲4

除非你的聲音是8位4個通道(我幾乎可以保證它不是),否定字節聽起來就像失真。這是因爲在框架中的字節「包裝」,例如:

 
big-endian 16-bit stereo PCM frame 

    b[0]  b[1]  b[2]  b[3] 
00000000 00000000 00000000 00000000 

where: 
- b[0] = left channel high byte 
- b[1] = left channel low byte 
- b[2] = right channel high byte 
- b[3] = right channel low byte 

爲了解開這個框架,你可以做

int ch0 = (b[0] << 8) | (b[1] & 0xFF); 
int ch1 = (b[2] << 8) | (b[3] & 0xFF); 

要收拾這個框架,你可以做

b[0] = (byte)((ch0 >>> 8) & 0xFF); 
b[1] = (byte)(ch0  & 0xFF); 
b[2] = (byte)((ch1 >>> 8) & 0xFF); 
b[3] = (byte)(ch1  & 0xFF); 

對於小端,高字節和低字節是相反的。

另請參閱:JSR FAQ

+0

謝謝你的回答!我很抱歉,但是,你能給我更詳細的信息**來自AudioInputStream的字節數組如何看起來像**?我注意到來自AudioInputStream的4字節數組表示左邊高字節/左低/右高/右低。我從來沒有見過這樣的解釋。 – 2014-11-06 09:07:44

+0

我想要做的是主動噪聲消除。所以我必須使輸入聲音(AudioInputStream)反相。並將其寫入揚聲器。有沒有關於主動噪音消除的建議? – 2014-11-06 09:10:07

+0

*「來自AudioInputStream的字節數組如何看起來像?」*這真的需要一個漫長的解釋。 Java聲音資源常見問題包含很多解釋這種類型的問題的答案,特別是[*'樣本是如何以字節數組/流的形式組織的?'](http://www.jsresources.org/faq_audio.html#樣本_組織) – Radiodef 2014-11-06 16:35:53