いい質問。実機は最強 bin のレベルがしきい値以上、行と列のレベル比が ±6 dB 以内、第二強度との比(ツイスト)が一定範囲、トーン継続時間 40 ms 以上——というように、複数の条件を AND で取って判定する。ノイズで一瞬最強 bin が入れ替わっても、継続時間条件で誤検出が抑えられる。ITU-T Q.24 という規格にきちんと書かれているよ。
🙋
「フレーム長 N」を増やすと、何が変わるんですか?
🎓
N が大きいほど周波数分解能 $\Delta f = F_s/N$ が細かくなり、隣接周波数との分離が良くなる。一方で計算量も比例して増える。F_s=8 kHz, N=205 で $\Delta f \approx 39$ Hz、これが DTMF の標準的な選び方だ。フレーム長が短すぎると bin が DTMF の各周波数からずれて検出強度が下がる。シミュレーターで N を 128 から 1024 まで動かすと、バーグラフの選択性が変わるのが見えるよ。
よくある質問
特定周波数のみ検出したい場面で広く使われます。例えば電力系統の周波数監視(50/60 Hz の高調波解析)、産業用センサのキャリア検波、超音波測距のエコー検出、無線機の CTCSS/DCS トーンスケルチ判定、医療機器のパルス検出など。共通点は「全 N bin は要らない、数個の bin だけ高速に欲しい」というニーズです。
基本形は整数 k を仮定しますが、Generalized Goertzel という拡張があり、任意の実数 k に対応できます。これにより、ターゲット周波数が DFT 格子上にない場合でも、漏れ(spectral leakage)を抑えながら精密に振幅を推定できます。電力系統の周波数推定など、整数 bin に乗らない周波数を扱う応用で重要です。
二次 IIR フィルタは内部状態が発散しやすく、フレーム長 N が大きいと s_n のダイナミックレンジが急増します。入力をあらかじめスケーリング(例 1/N 倍)して桁あふれを防ぐか、各サンプルでガードビット付きの飽和演算を用います。Q1.15 や Q1.31 の固定小数点では、係数 c を Q14 に丸めて誤差を抑える実装が一般的です。
次に多いのが、ターゲット周波数を厳密に DFT 格子に乗せる重要性を軽視することです。標準 Goertzel は k = round(f·N/F_s) として整数化するため、ターゲット周波数 f が bin 中心からずれていると「スカラップ損失」が生じ、最大 3.9 dB(ΔdB ≈ 20log₁₀(sinc(0.5)))も振幅推定が下がります。DTMF では F_s=8000, N=205 が古典的に推奨されますが、これは 8 つの DTMF 周波数がすべて DFT 格子に近くなる絶妙な選び方です。シミュレーターで N を変えるとバー高さが変動するのは、まさにこのスカラップ効果です。
最後に、「Goertzel の出力が大きい=検出成功」と短絡する誤りに注意してください。バーグラフで最強の bin を 1 つ選ぶだけでは、ノイズや音声の高調波で簡単に誤検出します。実機では行・列各々の最強レベルが絶対閾値以上、両者の比が ±6 dB 以内、第二強度との比(ツイスト)が規定範囲、トーン継続が 40 ms 以上、トーン断絶が 40 ms 以上——という複数条件を AND で課して初めて有効キーと判定します。シミュレーターでノイズを 1.0 まで上げると、最強 bin が頻繁に入れ替わる様子が見え、単純な最強判定の危うさが実感できます。