音频帧包含什么?

24
我正在研究如何比较声音文件(wave)。基本上,我想将存储的声音文件(wav)与麦克风捕获的声音进行比较。因此,最终我希望能够预先存储一些自己的语音命令,然后在运行应用程序时,我想将预存的文件与麦克风输入进行比较。 我的想法是在比较时加入一些余量,因为以完全相同的方式连续说出某个词可能会很困难。 经过一些搜索,我发现Python有一个名为wave的模块和Wave_read对象。该对象有一个名为readframes(n)的函数: “读取并返回至多n帧音频,作为字节串。” 这些字节包含什么?我打算逐帧循环遍历波形文件,逐帧进行比较。

3
这些字节包含PCM数据。你是在尝试语音识别吗?听起来好像你有点难以应对。你应该去研究一下这个主题。 - JoshD
啊,那真糟糕 :) 感谢回复。你可以称之为语音识别,但我考虑的方式是简单的文件比较,更加简单明了。在我的情况下,只需要发出相同的声音,而不是分析和试图解释单词。 - Jason94
2
这仍然是语音识别。即使你的声音有轻微的抑扬或速度差异,也会产生截然不同的音频数据,因此你不能仅仅逐帧比较它。 - Soviut
嗯...那真是个糟糕的事情。那么有没有一个Python库可以做我想要的事情呢? - Jason94
不过还有其他具有Python绑定的库。如果你在Windows上,可以使用http://pypi.python.org/pypi/speech/0.5.2。如果不是,则可以参考http://en.wikipedia.org/wiki/Speech_recognition_in_Linux。 - Lennart Regebro
4个回答

47

音频帧或样本在特定时间点包含振幅(响度)信息。为了产生声音,数万个帧将按顺序播放以产生频率。

对于CD品质的音频或无损波形音频,每秒大约有44,100个帧/样本。其中每个帧包含16位分辨率,可以比较准确地表示声音水平。此外,由于CD音频是立体声,因此实际上有两倍的信息,左声道16位,右声道16位。

当您使用Python中的声音模块获取帧时,它将作为一系列十六进制字符返回:

  • 8位单声道信号的一个字符。
  • 8位立体声的两个字符。
  • 16位单声道的两个字符。
  • 16位立体声的四个字符。

为了转换和比较这些值,您首先需要使用Python wave模块的函数来检查位深度和通道数。否则,您将比较不匹配的质量设置。


1
每秒 75 帧?你是不是应该说 44100? - corvuscorax
1
可能存在一些混淆,因为红皮书CD播放器每秒从光盘中读取75个扇区,但这对于本讨论的目的应该是无关紧要的。 - corvuscorax
1
一个八位单声道信号需要一个十六进制字符吗?肯定需要两个十六进制字符才能表示 8 位分辨率的信号。 - user2316667
据我回忆,音频帧以字节形式存储,它们只是在Python中的声音模块中表示为十六进制。 - Soviut
@user2316667 中的“1个字符”是指char类型,而不是一个打印字符。 - Andy V
显示剩余3条评论

8

简单的逐字节比较几乎没有成功匹配的可能性,即使加入一些容差也不行。语音模式识别是一个非常复杂而微妙的问题,仍然是许多研究的课题。


2
补充一下这个答案...问题与我们通常如何数字化表示音频以及我们如何感知声音有很大关系。我们听到的是频率及其相互作用,而不是直接感知波浪的每一个起伏。然而,当我们将音频数字化为PCM时,我们只是记录每秒数千次的压力水平测量值。我们在频域中听到声音,但PCM音频在时间域中。为了开始比较,我们首先需要运行傅里叶变换,将数字音频转换为频域。 - Brad

8

我认为目前描述略有不妥。

在IT技术中,frame这个词与图形格式中的stride类似。对于16位/样本的交错(stereo)数据,帧(frame)大小为2*sizeof(short)=4字节;而对于非交错(stereo)数据,左声道的所有样本是连续的,所以帧大小仅为sizeof(short)


如何检查是否交错?哪种更常见? - jiggunjer

6

你应该做的第一件事是进行傅里叶变换,将数据转化为频率。不过这个过程比较复杂。这里不建议使用语音识别库,因为听起来好像你并没有记录声音。接下来,您可以尝试不同的时间偏移(以防声音不完全对齐),然后选择给您最佳相似度的那一个 - 在这里您需要定义一个相似度函数。哦,您还应该对两个信号进行归一化处理(使其具有相同的最大音量)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接