我正在制作修改原始声音的程序。
我的程序流程就在这里。
我做了第1步,第2步和第3步。
以下是进程1,2,3的 CODE
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步?
答案 0 :(得分:0)
我认为您没有正确地将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页面和此post以获取一些有用的链接来修改音频流。
无论如何....一旦修改了音频流,就可以使用AudioSystem.getAudioInputStream(java.io.InputStream)
执行第4步,如下所示:
AudioInputStream newStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(reflectedPacket));
最后,您需要Clip
界面来播放声音:
Clip clip = AudioSystem.getClip();
clip.open(newStream);
答案 1 :(得分:0)
&#39; AudioOutputStream&#39;你正在寻找被称为SourceDataLine
。它可以从AudioSystem获得,并且有一个tutorial here。
但是,作为警告,
我的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 FAQ。