[英]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.