在 python 中将 Goertzel 算法扩展到 24 kHz、32 kHz 和 48 kHz

Posted

技术标签:

【中文标题】在 python 中将 Goertzel 算法扩展到 24 kHz、32 kHz 和 48 kHz【英文标题】:Extending Goertzel algorithm to 24 kHz, 32 kHz and 48 kHz in python 【发布时间】:2018-12-31 09:35:25 【问题描述】:

我正在学习实现 Goertzel 算法,以从录制的波形文件中检测 DTMF 音调。我从here 用python 实现了一个。它支持以 8 kHz 和 16 kHz 采样的音频。我想扩展它以支持以 24 kHz、32 kHz 和 48 kHz 采样的音频文件。

从我从上面链接得到的代码中,我看到作者设置了以下前置条件参数/常量:

self.MAX_BINS = 8
if pfreq == 16000:
    self.GOERTZEL_N = 210
    self.SAMPLING_RATE = 16000
else:
    self.GOERTZEL_N = 92
    self.SAMPLING_RATE = 8000

根据this的文章,在做实际的Goertzel之前,有两个初步计算是:

    确定采样率。 选择块大小,N

因此,作者明确将 16k 采样输入的块大小设置为 210,将 8k 采样输入设置为 92。现在,我想了解:

    作者是如何得出这个块大小的? 24k、32k 和 48k 样本的块大小是多少?

【问题讨论】:

此问题已被交叉发布at dsp.stackexchange.com。 【参考方案1】:

块大小决定了频率分辨率/选择性以及收集样本块所需的时间。

你的探测器的带宽大约是Fs/N,当然收集块的时间是N/Fs

为了获得相同的性能,您应该保持 FsN 之间的比率大致相同,以便这两个测量值保持不变。

不过,将块大小调整为尽可能接近要检测的波长的倍数也很重要。 Goertzel 算法基本上是一种计算几个选定 DFT 箱的快速方法,这种调整将您希望看到的频率置于这些箱的中心附近。

根据最后一点优化块大小可能是为什么 Fs/N 在您的 8KHz 和 16Khz 采样率的代码中不完全相同的原因。

可以针对您想要支持的其他采样率重新进行此优化,但如果您只使用 N = 210 * Fs / 16000,性能将与您已有的相同

您可以在此处找到块大小选择的详细说明:http://www.telfor.rs/telfor2006/Radovi/10_S_18.pdf

【讨论】:

在问题中引用的双音多频 (DTMF) 检测算法中,Goertzel 算法不限于长度为 N 的离散傅里叶变换 (DFT) 的 bin 的频率。系数初始化为:self.coefs[n] = 2.0 * math.cos(2.0 * math.pi * self.freqs[n] / self.SAMPLING_RATE)。所以 Trajković 论文的结果并不适用,至少不直接适用。 @OlliNiemitalo 确实如此——但他的块长度与该论文中建议的长度非常匹配(除以 2)

以上是关于在 python 中将 Goertzel 算法扩展到 24 kHz、32 kHz 和 48 kHz的主要内容,如果未能解决你的问题,请参考以下文章

使用Goertzel算法识别DTMF信号

核心音频,Goertzel 算法不起作用

Goertzel 算法给出无限结果

检测特定频率的算法? [关闭]

Python 请求 - HTTPDigest:在摘要授权中将哈希算法设置为 SHA-512

从 WAV 文件中解码 DTMF