如何将两个wav文件合并成一个wav文件?

4

如何使用Java合并两个wav文件?

我尝试了这个方法,但它没有正确工作,还有其他的方法吗?


2
它为什么不能正常工作?出了什么问题? - Buhake Sindi
结果文件太短了。你需要考虑到我尝试合并的每个文件都只需要1秒甚至更短的时间。也许这就是原因。 - Alex K
所以每个文件都是1秒钟或更短的吗?最大的歌曲长度将会是2秒钟吗?这不是你正在做的吗? - Buhake Sindi
我想我知道问题出在哪里了。 我该如何在这两个文件之间添加1秒(或更多)的空白音频? - Alex K
2个回答

14

如果你直接使用wav文件的字节,那么你可以在任何编程语言中使用相同的策略。在这个例子中,我假设两个源文件具有相同的位率/通道数和相同的长度/大小(如果不是,你可以在开始合并之前对它们进行编辑)。

首先查看一下wav格式规范,我在斯坦福大学课程网站上找到了一个很好的规范。

常见的头文件长度为44或46字节。

如果你想连接两个文件(即在单个文件中播放一个wav,然后播放另一个wav):

  1. 了解你的wav文件的格式
  2. 去掉头部的前44/46个字节,剩余的部分就是数据
  3. 创建一个新文件并将其中一个头部添加到该文件中。

    new wav file = {header} = {44/46} bytes long

  4. 添加原始文件中的两个数据部分

    new wav file = {header + data1 + data2 } = {44/46 + size(data1) + size(data2)} bytes long

  5. 修改头文件的两个位置以反映新文件的长度。

    a. 修改第4+4个字节(即从偏移量4开始的4字节)。 新值应为十六进制数,表示新wav文件的大小为{44/46 + size(data1) + size(data2)}-8字节。

    b. 修改第40+4或42+4个字节(从偏移量40或42开始的4个字节)。 新值应为十六进制数,表示新wav文件的总大小。即{44/46 + size(data1) + size(data2)}

如果你想合并或混合这两个文件(使它们同时播放):

  1. 如果两个文件的长度相同,则无需编辑头文件。
  2. 从第44/46个字节开始,您需要编辑每个采样,使其值等于data1加上data2中的值。例如,如果您的采样率为8位,则需要修改1个字节;如果您的采样率为16位,则需要修改2个字节。 其余部分仅是存储在1/2字节中的int值,表示该时间声音的波形的采样。

    a. 对于文件中剩余的每个采样,获取1/2字节十六进制字符串,并从data1和data2中获取int值。

    b. 将1/2字节整数相加,将结果转换回十六进制,并在输出文件中使用该值。

    c. 您通常需要将该数字除以2,以获得适合原始1/2字节采样块的平均值。当data1 + data2大于1/2字节时,声音会裁剪。关于裁剪问题,这里有一个讨论here,您可能想尝试其中一种裁剪技术。


嗨Thamster,我想合并两个wav文件。我已经这样做了,但在合并后我们可以听到两首歌曲以及伴随着噪音。请帮帮我... int a = buffer_1 [i] / 2; int b = buffer_2 [i] / 2; int c =(a + b); datafinal [i] =(byte)c; - sandeep
感谢您提供的解决方案。对于未来可能遇到此问题的任何人来说,不除以2会导致失真。我正在为16位PCM文件逐个添加每个字节。 - Anshuul Kai

2
合并意味着混合,但在这里听起来像是指连接。
要在中间插入静默并进行连接,您需要将一定数量的静默帧插入文件中。 静默帧是每个通道都具有“0”的帧 - 如果使用的是有符号样本,则字面上为0,如果使用的是无符号样本,则为maxvalue/2。
每个帧将具有每个通道的一个样本。 因此,要生成CD格式的一秒钟的静默,您需要插入44100(hz)* 2(每帧的通道数)= 88200个16位有符号整数,每个整数的值为0。 我不确定如何访问Java音频抽象所抽象的原始文件,但那就是要插入的数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接