Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

pyrirtool: Pythonで手軽にインパルス応答を測定・録音できるツール

音響分野において指数チャープ信号などを使ったインパルス応答の測定は非常に重要ですが、測定条件に対して柔軟に対応できる測定用ソフトウェアを自前で用意するのは結構手間です。

そこで、Pythonで手軽に利用できるインパルス応答測定ツール pyrirtool を紹介します。

pyrirtoolは再生・録音処理にsounddeviceを利用しているため,最新のバージョンのPythonでも動作します.

利用方法

準備

github.com

こちらの pyrirtoolのファイル一式をダウンロードしてきます。

その後、適当なところにpyrirtool-masterを解凍し、コンソールを開いて回答したフォルダpyrirtool-masterをカレントディレクトリとします。

なお、このままでは録音データの格納先が存在しないためエラーが出てしまいます。そのため、以下のディレクトリを作成してください.

  • pyrirtool-master/recorded/
  • pyrirtool-master/recorded/lastRecording/

コード修正

pyrirtool-master/measure.pyには最後の録音信号の切り出し部にバグがあります。従って、measure.pyの65行目以降を以下のように修正してください。

修正前

        # Truncate
        lenRIR = 1.2;
        startId = testStimulus.signal.shape[0] - args.endsilence*args.fs -1
        endId = startId + int(lenRIR*args.fs)
        # save some more samples before linear part to check for nonlinearities
        startIdToSave = startId - int(args.fs/2)
        RIRtoSave = RIR[startIdToSave:endId,:]
        RIR = RIR[startId:endId,:]

修正後

        # Truncate
        #lenRIR = 1.2;
        #startId = testStimulus.signal.shape[0] - args.endsilence*args.fs -1
        #endId = startId + int(lenRIR*args.fs)
        # save some more samples before linear part to check for nonlinearities
        #startIdToSave = startId - int(args.fs/2)
        RIRtoSave = RIR.copy()#RIR[startIdToSave:endId,:]
        #RIR = RIR[startId:endId,:]

なお、上記の修正を行うと,RIR.npyRIRac.npyは全く同じ信号となります。

また、もし自身でインパルス応答の切り出し処理を実装したい場合は、上記の部分を改良すればOKです。

利用方法

基本的にはmeasure.pyというスクリプトだけを動かします。

初期設定

初回実行時に python measure.pyを実行します.すると、pyrirtool-master/_data/というディレクトリが生成されます.ここには,測定条件が書かれたファイル defaults.npyが置かれています。

この測定条件は、python measure.py --defaultsとすればコンソール上で確認することができます.

なお、この測定条件は測定実行時に設定できるため、このファイルを直接編集する必要はありません。

入出力デバイスの確認

sounddeviceが利用する入出力デバイスを確認します。確認はpython measure.py --listdevでできます。詳しくはsounddeviceの記事を参照してください。

www.wizard-notes.com

バイスを変更する場合、例えば入力デバイス番号が1、出力デバイス番号が2であれば、python measure.py --setdev -indev 1 -outdev 2とすることでデバイスを変更することができます。

測定の実行

以下のコマンドを実行することで測定が開始します.

python measure.py -dur 2 -r 2 -a 0.5 -ss 2 -es 1 -chin 1  -chou 2

各オプションは以下のようになっています。

  • dur: 正弦波スイープ信号の時間長 [秒]
  • r: 正弦波スイープ信号の繰り返し回数
  • a: 正弦波スイープ信号の振幅
  • ss, es: スイープの開始時/終了時の無音の時間 [秒]
  • chin: 入力チャンネル番号
    • chin 1 2 3のようにチャンネルを複数指定することで、複数のマイクで同時に収録することも可能
    • 1オリジン
  • chout: 出力チャンネル番号

このスクリプトを実行すると,

  • pyrirtool-master/recorded/newrirXXX
  • pyrirtool-master/recorded/lastRecording/

の両方に録音信号が保存されます。(XXXは自動で割り振られる数字)

  • sigtest.wav: 測定に利用した正弦波スイープ信号の波形ファイル
  • sigrecX.wav: X番目の録音信号
  • RIRX.wav: X番目の録音信号から算出されたインパルス応答の波形ファイル
  • RIR.npy, RIRac.npy: npy形式で保存されたインパルス応答

測定結果の例

sigtest.wavとsigrec1.wav

RIR1.wav (算出されたインパルス応答) ※振幅を正規化しています。