[英]Need Help for this flow (AudioInputStream -> byte Array -> AudioOutputStream)
我正在制作一個修改原始聲音的程序。
我程序的過程就在這里。
我做了過程1和2和3。
這是我的過程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
我看到了一個使用ByteArrayInputStream的源。
但是,它是讀取文件的源,而不是AudioInput :(
如何處理第4和第5步?
我認為您沒有將audioInputStream
正確讀取到byte
數組中。 嘗試替換您的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頁面和此文章,以獲取一些有用的鏈接,以修改音頻流。
無論如何....一旦修改了音頻流,就可以使用AudioSystem.getAudioInputStream(java.io.InputStream)
來執行步驟4,如下所示:
AudioInputStream newStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(reflectedPacket));
最后,您將需要Clip
界面播放聲音:
Clip clip = AudioSystem.getClip();
clip.open(newStream);
您要查找的“ AudioOutputStream”稱為SourceDataLine
。 可以從AudioSystem獲得, 這里有一個教程 。
但是,作為警告,
我的AudioFormat的幀大小是4。
除非您的音頻是具有4通道的8位音頻(我可以保證幾乎沒有),否則否定字節聽起來就像是失真。 這是因為幀中的字節是“打包的”,例如:
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);
對於little-endian,高字節和低字節反轉。
另請參閱: JSR常見問題解答 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.