如何合并两个 AudioInputStream?

How do I combine two AudioInputStream?

文件格式为"PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian",我想在放大两个文件之一的同时将它们加在一起。我打算读取两个wav get把它们放入两个audioinputstream实例中,然后将实例存储到两个byte[]数组中,在数组中进行操作,并得到return作为另一个audioinputstream实例

我做了很多研究,但没有什么好的结果。 我知道这是来自 www.jsresources.org 的 class 混合两个音频输入流,但它不允许我在混合之前修改两个流中的任何一个,而我想在混合它们之前减少其中一个流。你觉得我应该怎么做?

为此,您可以将流转换为 PCM 数据,将您希望更改其音量的通道乘以所需的系数,将结果中的 PCM 数据相加,然后转换回字节。

要按字节访问 AudioStreams,请在 Using Files and Format Converters 的 Java 教程部分查看第一个扩展代码片段。这显示了如何获取一组声音字节数据。有评论是这样写的:

  // Here, do something useful with the audio data that's 
  // now in the audioBytes array...

此时,遍历字节,转换为 PCM。基于以下的一组命令应该可以工作:

for (int i = 0; i < numBytes; i += 2)
{
    pcmA[i/2] = audioBytesA[i] & 0xff ) | ( audioBytesA[i + 1] << 8 );
    pcmB[i/2] = audioBytesB[i] & 0xff ) | ( audioBytesB[i + 1] << 8 );
}

在上面,audioBytesAaudioBytesB 是两个输入流(名称基于示例中的代码),并且 pcmApcmB 可以是 int 数组或 short 数组,持有适合 short 范围内的值。最好制作 pcm 数组 floats,因为您将进行一些计算,这会导致分数。在下面的示例中使用 floats 只会增加一位的准确性(比使用 int 时更好的舍入),并且 int 会执行得更快。我认为如果音频数据得到 标准化 以用于额外处理,则更常使用浮点数。

由此可见,改变音量的最佳方法是将每个 PCM 值乘以相同的量。例如,要将音量增加 25%,

pcmA[i] = pcmA[i] * 1.25f; 

然后,添加 pcmA 和 pcmB,并转换回字节。您可能还想放入 min 或 max 函数以确保音量和合并不超过可以适合格式的 16 位的值。

我使用以下方法转换回字节:

for (int i = 0; i < numBytes; i++)
{
   outBuffer[i*2] = (byte) pcmCombined[i];
   outBuffer[(i*2) + 1] = (byte)((int)pcmCombined[i] >> 8 );            
}

以上假定 pcmCombined[] 是一个浮点数组。如果是 short[] 或 int[] 数组,转换代码可以更简单一些。

我从我为 my website 上发布的程序所做的开发工作中剪切并粘贴了以上内容,并根据您的情况对其进行了编辑,因此如果出现打字错误或错误,请在评论,我会修复它。