我有一些原始的PCM音频文件。我可以成功地从这些文件中读取字节流,并通过音频播放机制播放它们,该机制接受PCM数据作为输入。
当我从这些文件中读取数据时,我将其存储在byte []中。这些轨道具有相同的尺寸,并且在声音方面是互补的(它们听起来很好)。因此,我想将包含PCM数据的几个byte []添加到相同大小的单个字节[]中,代表最终的音乐。
我通过简单的方式轻松地尝试了它:
for(int i=0; i<finalbytes.length; i++)
{
finalbytes[i] = (byte) (music1bytes[i] + music2bytes[i]);
}
实际上并不是那么糟糕。最后的声音确实是两个音轨的补充。问题是,当添加几首曲目时,有时在歌曲的特定部分,可以听到静电噪声的峰值。这可能是由于添加导致非限制值或其他东西,我不知道如何解决。
那么,如何添加两个或多个PCM数据的字节数组?
答案 0 :(得分:2)
我假设这些原始音频文件的样本是8位签名。
发生的事情是溢出。如果两个样本的总和大于127或小于-128,则无法获得正确的结果 - 您将获得整数溢出。
您可以将每个结果样本除以2:
finalbytes[i] = (byte) ((music1bytes[i] + music2bytes[i]) / 2);
这样,即使每个音频文件都有最大样本值,您也不会溢出。缺点是生成的文件可能有点安静。
另一种选择是剪辑:
int sample = music1bytes[i] + music2bytes[i];
sample = Math.min(sample, Byte.MAX_VALUE);
sample = Math.max(sample, Byte.MIN_VALUE);
finalbytes[i] = (byte)sample;
如果两个音频源都非常响亮,那么可能会有很多剪辑,听起来可能不那么好。
您也可以尝试使用JavaSound中的SoftMixingMixer并让它为您进行混音。由于你需要定义RAW音频文件的音频格式,因此实际上可能会以更多的方式工作,但它可能会产生最佳的声音效果。使用此选项,您需要将openStream(AudioFormat)
与输出文件的音频格式一起使用,并告诉调音台通过线路播放2个RAW音频文件。