我尝试使用python中的wave module打开立体声流并将其转换为单声道。 到目前为止,我能够从16位立体声小端文件中编写单个(左或右)通道:
LEFT, RIGHT = 0, 1
def mono_single(cont, chan=LEFT):
a = iter(cont)
mono_cont = ''
if chan:
a.next(); a.next()
while True:
try:
mono_cont += a.next() + a.next()
a.next(); a.next()
except StopIteration:
return mono_cont
stereo = wave.open('stereofile.wav', 'rb')
mono = wave.open('monofile.wav', 'wb')
mono.setparams(stereo.getparams())
mono.setnchannels(1)
mono.writeframes(mono_single(stereo.readframes(stereo.getnframes())))
mono.close()
这可以按预期工作。当我尝试将两个立体声通道缩混为单个单声道时问题就出现了。 我认为左右之间的简单平均值就足够了,这就是我到目前为止所做的:
def mono_mix(cont):
a = iter(cont)
mono_cont = ''
while True:
try:
left = ord(a.next()) + (ord(a.next()) << 8)
right = ord(a.next()) + (ord(a.next()) << 8)
value = (left + right) / 2
mono_cont += chr(value & 255) + chr(value >> 8)
except StopIteration:
return mono_cont
stereo = wave.open('stereofile.wav', 'rb')
mono = wave.open('monofile.wav', 'wb')
mono.setparams(stereo.getparams())
mono.setnchannels(1)
mono.writeframes(mono_mix(stereo.readframes(stereo.getnframes())))
mono.close()
我从中得到的是一个&#34;噼里啪啦的&#34;版本的来源。 我尝试了不同的组合(我可能误解了整个字节序的事情),但到目前为止没有运气。
答案 0 :(得分:1)
您是否愿意使用外部库?
如果是,您可以使用pydub非常少的行轻松完成此操作,如下所示,
from pydub import AudioSegment
mysound = AudioSegment.from_wav("/input_path/infile.wav")
mysound = mysound.set_channels(1)
mysound.export("/output_path/outfile.wav", format="wav")
答案 1 :(得分:0)
结果我不知道audioop内置模块(感谢Anil_M&#39; answer。此外,我在转换立体声格式时都错了和写作(我应该使用struct)。
这使得一切都变得更加容易:
stereo = wave.open('stereofile.wav', 'rb')
mono = wave.open('monofile.wav', 'wb')
mono.setparams(stereo.getparams())
mono.setnchannels(1)
mono.writeframes(audioop.tomono(stereo.readframes(float('inf')), stereo.getsampwidth(), 1, 1))
mono.close()
然后您可以通过修改最新的2个参数(左侧为1, 0
,右侧为0, 1
)或甚至使用1.414
来获得相等的功率而非等幅度来选择单个通道