インパルス応答計測の方法の概略は前回説明しました。 今回は実際にインパルス応答測定のためのパッチ制作を、実際にJitterとGenで作ったパッチの中身を見ながら解説していこうと思います。
インパルス応答測定の流れとMaxで作るメリット
さて、実際にインパルス応答を録るにあたって必要な作業は以下です
- 測定信号の生成
- 測定
- 逆フィルタでインパルス応答復元
大体生成が何らかのスクリプト言語やツールを使って生成するのが一般的です(みんな大好きAudacityにもChirpと呼ばれるもので生成できます。)。そしてDAWなどに書きだした測定信号ファイルを取り込み録音、またプログラムなどに戻ってインパルス応答を復元という流れになります。Audacityとかなら1,2までは出来ますが3に行く時にどうしても別のツールに頼らねばなりません。 これが全部1つのツールで完結すると非常に楽です。
ちなみに、それをPuredataで作ったExpoChirpToolboxというのがあります。
https://www.katjaas.nl/expochirp/expochirp.html これは
\[expochirp~\]というエクスターナルオブジェクトとセットにしたpdパッチで、信号の生成、録音からIRの編集、分析まで全部できます。
ちなみに自分でエクスターナル無しでPdで開発しようとしたところ小数点精度の問題などであえなく挫折しました
Maxであればエクスターナル開発無しでも行けるかも、と思い開発してみました。
JitterとGenでBuffer~操作
先ほど測定信号を作るだけならMSPで写真のようなパッチを組めば十分と書きましたが、最終的にインパルス応答を取り出したければ逆フィルタを畳み込まねばなりません。 この時一番問題になるのは時間領域→周波数領域に変換するFFTで、信号を一定間隔で切り出して順次FFTするような形になっています。切り出し間隔のコントロールは可能ですが一回だけFFTして止める、といった事をするのは至難の技です。
そこで本来映像操作のためのjitterを使って波形を操作しようと言うのが今回の目的です(前置きが長い)。 今回はTSP信号と逆フィルタはGenで生成し、畳込みなどの処理はjitterでやっていきます。
この2つを使うと、Maxメッセージと比べて64bitでの処理ができるというメリットも有ります。
GenでのTSP信号、逆フィルタ生成
Genではpokeを使えばbufferに書き込みが可能です。 counterというサンプル単位で進むカウンターがあるので、外から1/0でカウンターのリセットをしてカウンターを回し始め、あとはほぼ定義通りの計算です。
逆フィルタの生成のほうが時間反転や振幅の計算がある分複雑です。ちなみに逆フィルタは振幅がだいたい-1~+1の範囲を超えますが、32bitfloatの上にこれ単体を再生したりすることは無いので特に気にする必要はありません。
Jitterでの逆畳込み
さて、逆フィルタの処理部分です。 jit.buffer~からbufferの中身を長さ*1のマトリックスとして読み出して計算します。左側が録音した波形、右側が逆フィルターです。 float32で読み込まれるので一度jit.matrix @type float64で型変換します。jitterはアトリビュートの指定だらけになるのでオブジェクトが見にくい事この上ないです。録音した波形は複数回繰り返されて録音されているのでjit.scissorsで分割して足し合わせます。
jit.glueで空の配列を足しているのは空き部分を作っておかないとはみ出した応答がマイナス時間に回りこむのを避けるため(円状畳込みを直線畳込みにするため)です。
jit.packで複素数(虚数成分は0)にしたうえでjit.fftに突っ込みます。
そして周波数領域同士で掛け算をします。サブパッチの中身は複素数の掛け算です。
その後jit.fft @inverse 1で時間領域に戻し、unpackで実数部のみを取り出します。
bufferに戻すためにjit.matrix @type float32で型を戻し、jit.buffer~に書き込み。 これでインパルス応答が復元されます。
これに録音機能(とりあえず4ch録音したかったので4ch仕様です)、インパルス応答のノーマライズ、マイナス時間の削除機能などなどをつけてとりあえず自分が使う分には十分なアプリが完成です。一応公開しておきますがいろいろ足りない機能だらけだと思うので自分で改造する叩き台ということでお願いします。
https://github.com/tomoyanonymous/IR_measurement_toolbox
今後はF特のグラフ書いたり任意のファイルにIR畳み込んだりIRのサンプル数減らすように出来たりしたいですね。plot~の記法がめんどくさすぎて諦めました。
おまけ
完成までに出力された波形の数々