python中的立体声到单波插值

Posted

技术标签:

【中文标题】python中的立体声到单波插值【英文标题】:Stereo to mono wave interpolation in python 【发布时间】:2017-03-27 20:40:37 【问题描述】:

我正在尝试使用 python 中的wave module 打开立体声流并将其转换为单声道。 到目前为止,我能够从 16 位立体声 little endian 文件中写入单个(左或右)声道:

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()

我从中得到的是源代码的“破解”版本。 我尝试了不同的组合(我可能误解了整个字节序),但到目前为止没有运气。

【问题讨论】:

【参考方案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")

【讨论】:

谢谢,我没有意识到 pydub 能够做到这一点。事实上,它看起来像是在使用我不知道的 audioop 模块,所以我想我会检查它的代码并编写我自己的函数(我宁愿避免使用 pydub,因为我会仅在这种情况下需要它)。【参考方案2】:

原来我不知道audioop内置模块(感谢Anil_M的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 等功率而不是等幅度

【讨论】:

天才。非常感谢。可以在这里使用临时文件吗?我需要将立体声转换为单声道,因为 Google STT API 不接受立体声。我宁愿不写入磁盘。使用 wave.open 似乎需要磁盘上的实际文件。

以上是关于python中的立体声到单波插值的主要内容,如果未能解决你的问题,请参考以下文章

Python中的圆插值

使用空间插值python填充shapefile中的缺失数据

极地立体投影中的Python点密度图

将两个立体声通道组合成单声道?

Python将立体声.flac转换为单声道

mysql多字段内容并到单字段中的操作