我想从波形音频文件中删除噪音(hisss)。全波音频图表在这里:
我正在使用下面的代码。这可能是一个愚蠢的尝试,但在matlab中我注意到噪声部分的幅度在0-3000之间变化。所以我试图将它们全部归零并将新帧保存到新的wav文件中。不知怎的,它不起作用!
import wave
import sys
ip = wave.open(sys.argv[1], 'r')
op = wave.open(sys.argv[2], 'w')
op.setparams(ip.getparams())
for i in range(ip.getnframes()):
iframes = ip.readframes(1)
amp = int(iframes.encode('hex'),16)
if amp > 32767:
amp = 65535 - int(iframes.encode('hex'),16)#-ve
print amp
else:
amp = int(iframes.encode('hex'),16)#+ve
print amp
if amp < 2000:
#make it zero
final_frame = '\x00\x00'
else:
#Keep the frame
final_frame = iframe
op.writeframes(final_frame)
op.close()
ip.close()
运行上面的脚本之后就变成了这个:
噪音部分(&lt; = 2500)仍然存在。所以请建议我如何删除那些不必要的部分!
最诚挚的问候,
答案 0 :(得分:1)
你的第一个问题是你将值解码为big-endian,而它们是actually little-endian。您可以使用struct
module轻松解决此问题。我还添加了abs
函数,因为幅度通常是从零开始的距离,这总是正的。
amplitude = abs(struct.unpack('<h', iframe))
这将使您的代码按预期执行。不幸的是,它没有解决更大的问题,这是完全错误的方法。它不会查看波形本身,它一次只查看一个样本。运行满量程的简单正弦波将有许多样本低于您的阈值,并且您将通过将它们设置为零来引入显着的失真。
答案 1 :(得分:0)
您的数据是真的签名还是未签名?如果已签名,那么您想要做的是,如果振幅的绝对值<3000钳位到0:
if abs(amplitude) < 3000:
final_frame = '\x00\x00'
如果这是真的,你根本不需要修改幅度。
如果它是无符号数据,那么你的0实际上是32768.你可以通过简单地减去你的数字0来将unsigned转换为signed:
amp = int(iframe.encode('hex'),16)
amp -= amp - 32768
注意这会给你一个介于-32768..32767之间的范围。
如果您更喜欢无符号工作,也可以轻松地完成。但是当你写0帧时,将其写入32768,而不是0,就像无符号一样,0是负最大值 - 非常大信号。