java 如何将两个 wav 文件合并/合并为一个 wav 文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2578862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I combine/merge two wav files into one wav file?
提问by Alex Kapustian
回答by Thamster
If you work with the bytes of a wav file directly you can use the same strategy in any programming language. For this example I'll assume the two source files have the same bitrate/numchannels and are the same length/size. (if not you can probably edit them before starting the merge).
如果您直接处理 wav 文件的字节,则可以在任何编程语言中使用相同的策略。对于本示例,我将假设两个源文件具有相同的比特率/通道数和相同的长度/大小。(如果没有,您可以在开始合并之前编辑它们)。
First look over the wav specificaiton, I found a good one at a stanfordcourse website:
首先查看 wav 规范,我在斯坦福课程网站上找到了一个很好的:
Common header lengths are 44 or 46 bytes.
常见的报头长度为 44 或 46 字节。
If you want to concatenate two files (ie play one wav then the other in a single file):
如果您想连接两个文件(即在单个文件中播放一个 wav,然后播放另一个):
- find out what format your wav files are
- chop off the first 44/46 bytes which are the headers, the remainder of the file is the data
create a new file and stick one of the headers in that.
new wav file = {header} = {44/46} bytes long
add the two data parts from the original files
new wav file = {header + data1 + data2 } = {44/46 + size(data1) + size(data2)} bytes long
modify your header in two places to reflect the new file's length.
a. modify bytes 4+4 (ie. 4 bytes starting at offset 4). The new value should be a hexadecimal number representing the size of the new wav file in bytes {44/46 + size(data1) + size(data2)} - 8bytes.
b. modify bytes 40+4 or 42+4 (the 4 bytes starting at offset 40 or 42, depending on if you have a 44byte header or 46 byte header). The new value should be a hexadecimal number representing the total size of the new wav file. ie {44/46 + size(data1) + size(data2)}
- 找出你的 wav 文件是什么格式
- 砍掉前 44/46 个字节是头,文件的其余部分是数据
创建一个新文件并在其中粘贴一个标题。
新 wav 文件 = {header} = {44/46} 字节长
添加原始文件中的两个数据部分
新的 wav 文件 = {header + data1 + data2 } = {44/46 + size(data1) + size(data2)} 字节长
在两个地方修改您的标题以反映新文件的长度。
一个。修改字节 4+4(即从偏移量 4 开始的 4 个字节)。新值应该是一个十六进制数,以字节 {44/46 + size(data1) + size(data2)} - 8bytes 表示新 wav 文件的大小。
湾 修改字节 40+4 或 42+4(从偏移量 40 或 42 开始的 4 个字节,取决于您有 44 字节的标头还是 46 字节的标头)。新值应该是一个十六进制数,表示新 wav 文件的总大小。即 {44/46 + 大小(数据 1)+ 大小(数据 2)}
If you want to instead merge or mix the two files (so that they both play at the same time then):
如果您想合并或混合这两个文件(以便它们同时播放):
- you won't have to edit the header if both files are the same length.
starting at byte 44/46 you will have to edit each sample to be the value in data1 + the value in data2. so for example if your SampleRate was 8 bits you would modify 1 byte, if your sample rate was 16bits you would modify 2 bytes. the rest of the file is just Samples of 1/2bytes storing an int value representing the waveform of the sound at that time.
a. For each of the remaining samples in the file grab the 1/2 byte hex string and get the int value from both files data1 and data2.
b. add the 1/2 byte integers together convert the result back to hexadecimal and use that value in your output file.
c. You normally have to divide that number by 2 to get an average value that fits back in the original 1/2byte sample block. I was getting distortion when i tried it in objc(probably related to signed or unsigned ints) and just skipped the division part since it will only likely be a problem if you are merging very loud sounds together. ie when data1 + data2 is larger than 1/2 bytes the sound will clip. There was a discussion about the clipping issue hereand you may want to try one of those clipping techniques.
- 如果两个文件的长度相同,则不必编辑标题。
从字节 44/46 开始,您必须将每个样本编辑为 data1 中的值 + data2 中的值。例如,如果您的 SampleRate 是 8 位,您将修改 1 个字节,如果您的采样率为 16 位,您将修改 2 个字节。文件的其余部分只是 1/2 字节的样本,存储了一个代表当时声音波形的 int 值。
一个。对于文件中剩余的每个样本,获取 1/2 字节的十六进制字符串并从文件 data1 和 data2 中获取 int 值。
湾 将 1/2 字节整数相加,将结果转换回十六进制并在输出文件中使用该值。
C。您通常必须将该数字除以 2 以获得适合原始 1/2 字节样本块的平均值。当我在 objc 中尝试它时(可能与有符号或无符号整数有关),我遇到了失真,只是跳过了除法部分,因为如果您将非常响亮的声音合并在一起,它可能只是一个问题。即当 data1 + data2 大于 1/2 字节时,声音将被剪辑。此处讨论了剪裁问题,您可能想尝试其中一种剪裁技术。
回答by Justin Smith
Merge implies mixing, but it sounds like you mean concatenation here.
合并意味着混合,但听起来您在这里的意思是连接。
To concatenate with silence in the middle you need to insert a number of frames of silence into the file. A silent frame is one where every channel has a "0" - if you are using signed samples this is literally a 0, for unsigned, it is maxvalue/2.
要在中间连接静音,您需要在文件中插入一些静音帧。无声帧是每个通道都有一个“0”的帧 - 如果您使用有符号样本,这实际上是一个 0,对于无符号,它是 maxvalue/2。
Each frame will have one sample for each channel. So to generate one second of silence in CD format, you would insert 44100 (hz) * 2 (channels per frame) = 88200 16 bit signed ints with a value of 0 each. I am not sure how to access the raw file abstracted by the Java audio abstractions, but that is the data to insert.
对于每个通道,每一帧都有一个样本。因此,要以 CD 格式生成一秒钟的静音,您需要插入 44100 (hz) * 2(每帧通道数)= 88200 个 16 位有符号整数,每个整数的值为 0。我不确定如何访问由 Java 音频抽象抽象的原始文件,但这是要插入的数据。

