繁体   English   中英

需要此流程的帮助(AudioInputStream->字节数组-> AudioOutputStream)

[英]Need Help for this flow (AudioInputStream -> byte Array -> AudioOutputStream)

我正在制作一个修改原始声音的程序。

我程序的过程就在这里。

  1. AudioInputStream获取声音
  2. 将声音数据更改为字节数组 。(我的AudioFormat的帧大小4。因此,我将使用长度为4的字节数组)
  3. 修改字节数组(类似于“将-1乘以每个元素”
  4. 将修改后的字节数组发送到AudioOutputStream
  5. 播放声音。

我做了过程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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM