如何优化两个音频文件的合并?
我写了一段代码,用来合并两个波形文件。当我合并较大的片段时,效果很好,但如果要合并非常小的片段,音质就不太好了。
我了解到,可以使用一种叫做“窗口连接”的信号处理技术来改善文件的合并效果。
公式是这样的:y[n] = w[n]s[n],也就是说,把样本编号为n的信号值乘以一个窗口函数的值。
这里的汉明窗口公式是:w[n] = 0.54 - 0.46*cos(2*Pi*n)/L,L是窗口的长度。
我不太明白如何获取样本n的信号值,以及该怎么实现这个?
the code i am using for joining is
import wave
m=['C:/begpython/S0001_0002.wav', 'C:/begpython/S0001_0001.wav']
i=1
a=m[i]
infiles = [a, "C:/begpython/S0001_0002.wav", a]
outfile = "C:/begpython/S0001_00367.wav"
data= []
data1=[]
for infile in infiles:
w = wave.open(infile, 'rb')
data1=[w.getnframes]
data.append( [w.getparams(), w.readframes(w.getnframes())] )
#data1 = [ord(character) for character in data1]
#print data1
#data1 = ''.join(chr(character) for character in data1)
w.close()
output = wave.open(outfile, 'wb')
output.setparams(data[0][0])
output.writeframes(data[0][1])
output.writeframes(data[1][1])
output.writeframes(data[2][1])
output.close()
在合并时,我是用字节格式来处理帧的。现在我想用整数或浮点数格式来进行操作。如果我想的没错,我该怎么做呢?
2 个回答
简单来说,WAV音频格式包含一个44字节的头部,这里定义了一些必要的信息,比如采样率、声道数量等等。接下来就是实际的音频数据部分。音频其实就是一个随时间变化的振幅曲线。WAV格式允许这个振幅在+1.0到-1.0之间变化,这些值是以浮点数的形式表示的。当录制音频时,这个振幅通常每秒会被测量44100次(这就是采样率)。所以,WAV文件就是存储这一系列的采样值。需要注意的是,WAV格式并不直接存储浮点数,而是将+1到-1的范围存储为从0到2^16的整数。这些16位的样本每个需要两个字节的存储空间。在上面的示例代码中,i>>8表示将音频值向右移动8位。如果你理解了这些概念,并自己写代码来读取或写入WAV文件,你就能更好地解决你的问题了。
这可能不是最好的解决方案,但我相信它能奏效。也许你可以找到一些现成的库来帮助你完成某些步骤,我对Python的情况不太清楚。以下是我建议的步骤:
- 加载波形文件。
- 为每一帧创建样本值(幅度),这取决于帧大小、字节序(小端或大端)、有符号或无符号。
- 将得到的整数值数组分成多个窗口,比如样本0-511,512-1023,等等。
- 对你想要合并的窗口执行窗口函数。
- 进行合并操作。
- 将窗口的数据存回字节数组,这个过程是第一步的反向操作。
旧帖子:你需要计算样本值,在Java中,一个处理2字节/帧音频文件的函数可能是这样的:
public static int createIntFrom16( byte _8Bit1, byte _8Bit2 ) {
return ( 8Bit1<<8 ) | ( 8Bit2 &0x00FF );
}
通常你需要注意文件是否使用小端格式,我不确定Python的库是否会考虑到这一点。
一旦你创建了所有的样本值,你就需要将文件分成窗口,比如每个窗口大小为512个样本。然后你可以对这些值进行窗口处理,并重新生成字节值。对于16位的情况,它可能看起来是这样的:
public static byte[] createBytesFromInt(int i) {
byte[] bytes = new byte[2];
bytes[0]=(byte)(i>>8);
bytes[1]=(byte)i;
return bytes;
}