需要此流程的帮助(AudioInputStream - > byte Array - > AudioOutputStream)

时间:2014-11-06 07:18:20

标签: java arrays audio bytearray javasound

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

我的程序流程就在这里。

  1. AudioInputStream
  2. 获取声音
  3. 将声音数据更改为字节数组。(我的AudioFormat' 帧大小 4 。所以,我' ll使用长度 4 的字节数组
  4. 修改字节数组(类似于"将-1加到每个元素"
  5. 将修改后的字节数组发送到 AudioOutputStream
  6. 播放声音。
  7. 我做了第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步?

2 个答案:

答案 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