前回と今回は算法的にはまったく同じ、その差はソフトウエア部品として使い易いようにクラス化するところだけ。だったら簡単じゃん、と甘くみて例のごとくにハマりました。クラス化する「エレガントな」書き方を学ぶべく、1行1行手入力したら間違えてました。ボーっとして入力しているからだ。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
勝手に手習ひさせていただいております教科書は以下です。
三上直樹先生著、工学社『「Armマイコン」プログラムで学ぶデジタル信号処理』
プログラム・ソースはArm社のMbed環境上で公開されています(要無料登録。)
MbedのWeb環境でのビルド結果は左にあるとおりです。以前のものとほぼほぼ変わりはありませんぬ。
しかし、前回と今回ではソースコードの構成が大きくことなります。前回は、1本のCPPファイルの中に全てが関数として収まっていました。それに対して今回は、2つのクラスが独立したファイルとなり、mainのソースコードは非常にシンプルとなりました。
以前から、三上先生のArrayテンプレート・クラスを使わせていただいておりました。クラスの構成は3段のネストとなります。
- IIRフィルタ全体のクラス
- 基本ブロックを並べるためのArrayクラス
- 基本ブロックBiquadクラス
上位層からすると全体クラスを呼び出せばOK。そのフィルタの大筋の構造としてはArrayクラスで基本部品を必要なだけ並べており、基本部品の計算そのものはBiquadに押し込められていると。エレガントな構造であります。
入力ミスに泣く
動くに決まっているサンプルプログラムをそのままビルドしても、「書き方」はいっこうに学ばない、ということで、あえてクラス定義のための新設2ファイルは手入力として「シミジミと味わう」ことにいたしました。だいたい御本を見ながら入力する単純作業なので間違うわけない、と思ったら間違ってました。ちゃんとコード読んでなかったでしょ。2か所も。「シミジミ」ではなく「ボーっと」入力していたです。
そうするとどうなったかというと、フィルタがピクリとも動きませぬ。そのときの振幅特性のグラフを冒頭のアイキャッチ画像に掲げました。ダメだこれは。
そして1か所間違いを見つけ、これに違いないと修正後もダメ。もう1か所間違いが潜んでおったのです。早合点。今回のように動くに決まっているソースがあればソースを比較するだけで問題点は直ぐに発覚しますが、ほんとにデバッグしていると酷いことになったね、きっと。
動作確認
2か所修正後の動作確認が以下に。まずは、例によって入力に365Hzの振幅1V、オフセット0Vの正弦波(黄色C1)を与え、出力(青色C2)を観察してみます。フィルタはLPFで、遮断周波数355Hz設定なので、出力は減衰しかけている筈。
お楽しみの振幅特性(10Hzから5kHz)が以下に。
355Hz付近から急激に-40dBまで落ちております。予定通り。動いていてよかった。ソースが間違っていたら動くわけないわな。
どうもこれで「基本編」終わりみたい。次回からは「応用編」らしいです。手習ひは続く。