昨日のデジタルフィルタの不具合について考えていると、実験をお願いしている後輩がソフトウェアについての要望を一つ持って来た。
あるシーケンス動作の途中に待ち時間を1つ追加して、ユーザーがその時間を変更できるようにして欲しいというもの。一からやるとかなり面倒なことになりそうだなと思いながらソースを調べてみると、都合が良いことに以前に実装して今は無効にしてあるコードがそのまま使えそうだ。そう言えば今回要望された待ち時間は、初期のバージョンには実装されていた。その後GUIをシンプルにするために画面から消して機能自体も無効にしていたけど、今回のような事態を見越してコードは残しておいたのだった。おかげで昼までの1時間ほどで要望を実現することができた。
ソフトウェアの要望についての未来予測は大抵外れるので、いつもは「いずれ役に立つかもしれないコード」はリファクタリングで削除するようにしている。今回はうっかり見落としていたものがたまたま役に立った。
午後からはデジタルフィルタの問題の解決に当たる。フィルタを通すと信号の振幅がやたらでかくなるというのが問題だった。
白状するとデジタルフィルタのコードは、アルゴリズムをちゃんと理解せずに見よう見まねで参考書のコードを流用してきた。特に今回は、係数を計算とフィルタ演算ごとに参考にした元ネタが別だったので、条件の齟齬を見落としているのだろう。仕方がないので横着は諦めて、ちゃんと参考書を読んで理解に努めた。
夕方近くまでかかったが、ようやく原因が分かった。大抵のバグは原因が分かってしまえば大したことではないものだけど、ご多分にもれず今回も些細な見落としが原因だった。
今回実装したデジタルフィルタはカスケード接続のIIRフィルタで、計算中でのオーバーフローを防ぎ、誤差を小さくするためにスケーリングを行っている。スケーリングをするには、入力信号とフィルタの係数にそれぞれ適切な値を掛けておく。今回の問題は、この入力信号への掛け算が抜けていたのが原因だった。ここを修正して期待通りのフィルタが得られた。

今日はなんとなくグズグズと会社に残ってしまった。反省。それでも9時頃に帰宅した後、車で古本屋とラーメン屋へ。