Goertzel アルゴリズム シミュレーター 戻る
信号処理シミュレーター

Goertzel アルゴリズム シミュレーター — DTMF 単一周波数検出

DTMF の 16 キーを Goertzel 法で検出。二次 IIR フィルタで 8 つの DFT bin を O(N) で計算し、行・列の最強周波数からキーを判定する仕組みを、リアルタイム可視化で学べます。

パラメータ設定
DTMF キー番号
ノイズ レベル
サンプリング F_s
Hz
フレーム長 N

キー配列 — 0:'1' 1:'2' 2:'3' 3:'A' / 4:'4' 5:'5' 6:'6' 7:'B' / 8:'7' 9:'8' 10:'9' 11:'C' / 12:'*' 13:'0' 14:'#' 15:'D'

計算結果
検出キー
最強行周波数
最強列周波数
Goertzel 演算量 N·M
入力信号と Goertzel 検出強度

上段=入力信号 x[n](青)/下段=8 周波数の |X_k|(赤=行、青=列、黄=最強)

理論・主要公式

Goertzel アルゴリズムは、ターゲット周波数 f に最も近い bin k = round(f·N/F_s) について、二次の IIR 漸化式で振幅²を直接計算します。

角周波数 ω と係数 c:

$$\omega = \frac{2\pi k}{N},\qquad c = 2\cos\omega$$

二次 IIR 漸化式(s_{-1} = s_{-2} = 0):

$$s_n = x_n + c\,s_{n-1} - s_{n-2}$$

N サンプル後の振幅²(bin パワー):

$$|X_k|^2 = s_{N-1}^2 + s_{N-2}^2 - c\,s_{N-1}\,s_{N-2}$$

1 bin の計算量は O(N)、M 周波数なら O(N·M)。FFT 全体の O(N log N) と比べ、検出したい bin が少ないほど Goertzel が有利です。

Goertzel アルゴリズム シミュレーターとは

🙋
FFT があるのに、なぜわざわざ Goertzel という別のアルゴリズムが必要なんですか?
🎓
ざっくり言うと、Goertzel は「1 つの周波数 bin だけ知りたい」ときの専門家だよ。FFT は N 点ぶん全部の bin を計算してしまうけど、たとえば DTMF 検出で必要なのは 8 つの周波数だけだ。Goertzel は 1 bin あたり O(N)、しかも 3 つの変数しか持たない二次 IIR フィルタで済むから、組込みマイコンに向いている。シミュレーターでキーを変えると、検出したいのは行 1 つ・列 1 つの計 2 周波数だけだとわかるはずだ。
🙋
「二次 IIR」って何ですか?フィルタって聞くとちょっと身構えちゃうんですけど…
🎓
難しくないよ。$s_n = x_n + c\,s_{n-1} - s_{n-2}$ という漸化式を 1 サンプル進めるだけ。係数 $c = 2\cos(2\pi k/N)$ は最初に 1 回だけ計算しておけば OK。状態変数は $s_{n-1}$ と $s_{n-2}$ の 2 つだけだから、メモリも 3 ワードで足りる。最後に $|X_k|^2 = s_{N-1}^2 + s_{N-2}^2 - c\,s_{N-1}s_{N-2}$ で振幅²が出る。DSP の Mul-Acc 命令と相性抜群なんだ。
🙋
シミュレーターで「ノイズレベル」を上げると、バーグラフが暴れますね。実機ではどう判定するんですか?
🎓
いい質問。実機は最強 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 値 X_k = s_{N-1} − e^{-jω} s_{N-2} を計算すれば実部・虚部が得られ、atan2 で位相角が求まります。本シミュレーターは振幅検出のみを行いますが、AM/FM 復調や同期検波では位相が重要なので、実装時には複素出力版を使います。位相を不要にすれば乗算 1 回ぶん削減できるのが Goertzel のシンプルな利点です。

実世界での応用

電話通信の DTMF デコード:固定電話・IP 電話・自動応答装置 (IVR) で、ユーザーが押したキーをリアルタイム検出する標準手段が Goertzel 法です。アナログ回線では送話器からの音声に DTMF が重畳されており、受信側で 8 個の Goertzel フィルタを並列に走らせ、レベル比・継続時間・ツイスト等の判定で有効キーを抽出します。VoIP では RFC 2833 のように DTMF をデジタル送信する方式も併用されますが、相互運用のため Goertzel デコーダは依然として現役です。

電力系統の周波数解析:50 Hz/60 Hz とその高調波(150/180, 250/300, 350/420 Hz など)の振幅を継続監視する電力品質モニタで使われます。FFT を全周波数に対して回す代わりに、対象とする数本の高調波だけを Goertzel で常時計算し、CPU 負荷を抑えつつ即応性のあるアラーム判定を行います。Generalized Goertzel と組み合わせると、系統周波数が 50 Hz からわずかにずれた場合でも正確な振幅推定ができます。

無線機の CTCSS/DCS トーン検出:業務用無線・アマチュア無線では、特定の低周波サブオーディブルトーン(67〜250 Hz の 50 種程度)でグループ識別を行う CTCSS 方式が使われます。受信機は対象トーンの Goertzel 出力を常時監視し、しきい値を超えたときだけスピーカーをアンミュートします。低周波・少数バンドの検出という Goertzel が最も得意な領域です。

組込み機器のキャリア検波:FSK モデムのプリアンブル検出、超音波センサのエコー強度測定、医療機器のパルスオキシメータの心拍同期など、ARM Cortex-M クラスの組込み MCU で「数本の周波数だけ FFT 並みの精度で測りたい」用途に多用されます。CMSIS-DSP ライブラリにも arm_biquad_cascade_df1_q15 などを応用した Goertzel 実装が用意されており、ハードウェア乗算器を活かして数 µs で 1 フレーム処理できます。

よくある誤解と注意点

最も多い誤解は、「Goertzel は常に FFT より速い」と思い込むことです。実は損益分岐点があり、検出したい周波数の本数 M が log₂N 程度を超えると FFT の方が有利になります。例えば N=1024 では log₂N = 10。10 本以上の bin が必要なら FFT 一発でまとめて計算した方が速いのです。シミュレーターの「演算量」カードは Goertzel の N·M を表示していますが、これと FFT の N·log₂N を頭の中で比較する習慣をつけましょう。「少数本」かつ「対象 bin が事前にわかっている」場合に限り Goertzel が勝ちます。

次に多いのが、ターゲット周波数を厳密に 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 が頻繁に入れ替わる様子が見え、単純な最強判定の危うさが実感できます。