audioop– 处理原始音频数据


audioop模块包含对声音片段的一些有用的操作。它对由8,16,24或32位宽的有符号整数样本组成的声音片段进行操作,存储在字节对象中。除非另有说明,否则所有标量项都是整数.

在版本3.4中更改:添加了对24位样本的支持。所有函数现在都接受任何字节对象.String输入现在导致立即错误.

该模块支持a-LAW,u-LAW和Intel / DVI ADPCM编码.

一些较复杂的操作只采用16位采样,否则采样大小(以字节为单位)始终是操作的参数.

该模块定义了以下变量和函数:

exception audioop.error

在所有错误上引发此异常,例如未知的字节数例等.

audioop.add (fragment1, fragment2, width

返回一个片段,它是作为参数传递的两个样本的加法.width是样本宽度,以字节为单位,1, 2, 34。两个片段应该具有相同的长度。如果溢出,样品会被截断.

audioop.adpcm2linadpcmfragment, width, state

将Intel DVI ADPCM编解码器片段解码为线性片段。见的描述lin2adpcm()有关ADPCM编码的详细信息。返回一个元组(sample, newstate)其中样本的宽度在width.

audioop.alaw2linfragment, width

将a-LAW编码中的声音片段转换为线性编码的声音片段.a-LAW编码总是使用8位样本,因此width仅指输出片段的样本宽度.

audioop.avgfragment, width

返回片段中所有样本的平均值.

audioop.avgpp (fragment, width)

返回片段中所有样本的平均峰 – 峰值。Nofiltering已经完成,所以这个例程的用处有问题.

audioop.bias (fragment, width, bias )

返回一个原始片段的片段,并在每个样本中添加一个偏差。如果溢出,样品会缠绕.

audioop.byteswap (fragment, width)

“Byteswap”片段中的所有样本并返回修改后的片段。将big-endian样本转换为little-endian,反之亦然.

新版本3.4.

audioop.cross (fragment, width

返回作为参数传递的片段中的过零次数.

audioop.findfactor (fragment, reference)

返回一个因子F这样rms(add(fragment, mul(reference, -F))) isminimal,即返回你应该乘以的因子reference使它尽可能匹配fragment。片段应该包含2字节的样本.

这个例程所用的时间与len(fragment).

audioop.findfitfragment, reference

尝试匹配reference以及fragment的一部分(这可能是更长的片段)。这是(概念上)通过使用fragment取出findfactor()计算最佳匹配,并最小化结果。碎片应该都包含2个字节的样本。返回一个元组(offset, factor)其中offset是(整数)偏移到fragment最佳匹配开始的地方,factor是片段中所有样本的findfactor().

audioop.findmaxfragment, length

搜索fragment得到一片长度length样本(不是字节!),最大能量,即返回i,其中rms(fragment[i*2:(i+length)*2])是最大的。片段应该都包含2个字节的样本.

例程需要的时间与len(fragment).

audioop.getsamplefragment, width, index)成比例

返回样本的值index来自片段

audioop.lin2adpcm// (fragment, width, state)

将样本转换为4位Intel / DVI ADPCM编码。ADPCM编码是一种自适应编码方案,其中每个4位数是一个样本和下一个样本之间的差,除以(变化)步骤。英特尔/ DVI ADPCM算法已被选择供IMA使用,因此很可能成为标准.

state是一个包含编码器状态的元组编码器返回一个元组(adpcmfrag, newstate)newstate应该传递给lin2adpcm()的下一个调用。在初始调用中,None可以作为状态传递.adpcmfrag是ADPCM编码的片段,每个字节包含2个4位值.

audioop.lin2alaw(fragment, width

音频片段中的样本转换为a-LAW编码,并将其作为abytes对象返回。a-LAW是一种音频编码格式,您只需使用8位采样即可获得大约13位的动态范围。它由Sun audio硬件等使用.

audioop.lin2lin (fragment, width, newwidth)

在1字节,2字节,3字节和4字节格式之间转换样本.

注意

在某些音频格式中,例如.WAV文件,16,24和32位样本是有符号的,但8位样本是无符号的。因此,当转换为这些格式的8位宽样本时,您还需要在结果中添加128:

new_frames = audioop.lin2lin(frames, old_width, 1)new_frames = audioop.bias(new_frames, 1, 128)

在从8转换为16,24或32位宽样本时,必须应用相同的相反方法。

audioop.lin2ulawfragment, width

音频片段中的样本转换为u-LAW编码,并将其作为abytes对象返回。u-LAW是一种音频编码格式,您只需使用8位样本即可获得大约14位的动态范围。它被Sun audio硬件使用,等等.

audioop.max (fragment, width)

返回absolute value的(浮点)因子.

audioop.maxppfragment, width

返回声音片段中的最大峰 – 峰值

audioop.minmax// (fragment, width)

返回由声音片段中所有样本的最小值和最大值组成的元组.

audioop.mulfragment, width, factor

返回一个片段,其中包含原始片段中的所有样本乘以浮点值factor。如果溢出,样品会被截断.

audioop.ratecv (fragment, width, nchannels, inrate, outrate, state [, weightA [, weightB]]

转换输入片段的帧速率.

state是包含转换器状态的元组。转换器返回一个元组(newfragment, newstate),而newstate应该传递到ratecv()。初始调用应该通过None作为状态

weightAweightB参数是一个简单的数字过滤器的参数默认为10.

audioop.reverse(fragment, width)

反转片段中的样本并返回修改后的片段.

audioop.rmsfragment, width

返回片段的均方根,即sqrt(sum(S_i^2)/n).

这是对音频信号功率的测量.

audioop.tomonofragment, width, lfactor, rfactor)

将立体声片段转换为单声道片段。左声道乘以lfactor,右声道乘以rfactor,然后再添加两声道来发出单声道信号.

audioop.tostereo(fragment, width, lfactor, rfactor)

从单声道片段生成立体声片段。立体声片段中的每对样本都是从单声道样本中计算出来的,左声道样本乘以lfactor,右声道样本乘以rfactor.

audioop.ulaw2linfragment, width

将u-LAW编码中的声音片段转换为线性编码的声音片段.u-LAW编码总是使用8位样本,所以width仅指输出片段的样本宽度.

注意诸如mul()max()之类的操作不区分单声道和立体声片段,即所有样本都被视为相等。如果这是一个问题,立体声片段应该被分成两个单片段,然后重新组合。这是一个如何做到这一点的例子:

def mul_stereo(sample, width, lfactor, rfactor):    lsample = audioop.tomono(sample, width, 1, 0)    rsample = audioop.tomono(sample, width, 0, 1)    lsample = audioop.mul(lsample, width, lfactor)    rsample = audioop.mul(rsample, width, rfactor)    lsample = audioop.tostereo(lsample, width, 1, 0)    rsample = audioop.tostereo(rsample, width, 0, 1)    return audioop.add(lsample, rsample, width)

如果您使用ADPCM编码器来构建网络数据包,并且您希望协议无状态(即能够容忍数据包丢失),则不仅应传输数据,还应传输状态。请注意,您应该将initial状态(传递给lin2adpcm()的状态)发送到解码器,而不是最终状态(由编码器返回)。如果你想使用struct.Struct以二进制形式存储状态,你可以用16位编码第一个元素(预测值)和第二个(delta指数)编码8.

ADPCM编码器从未尝试过反对其他ADPCM编码器,只针对他们自己。很可能是我误解了标准,在这种情况下,它们不能与各自的标准互操作.

find*()惯例看起来有点滑稽。它们主要用于回声消除。一个相当快速的方法是触摸输出样本中最有活力的部分,在输入样本中找到它并从输入样本中减去整个输出样本:

def echocancel(outputdata, inputdata):    pos = audioop.findmax(outputdata, 800)    # one tenth second    out_test = outputdata[pos*2:]    in_test = inputdata[pos*2:]    ipos, factor = audioop.findfit(in_test, out_test)    # Optional (for better cancellation):    # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],    #              out_test)    prefill = "\0"*(pos+ipos)*2    postfill = "\0"*(len(inputdata)-len(prefill)-len(outputdata))    outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill    return audioop.add(inputdata, outputdata, 2)

评论被关闭。