オーディオのシステムはちょっとしたことで、色々と音質が変化します。前回は周波数特性だけを分析するソフトにしましたが、文献を調べてみると同時に歪も測定するアルゴリズムがありました。
https://www.semanticscholar.org/paper/Simultaneous-Measurement-of-Impulse-Response-and-a-Farina/aeaba8bb33cad2f6914cc02c76c52064d58a8136
この論文は2000年に発表された古いものですが、改めてPythonで実装してみました。
ポイントはLogスイープ信号を生成しオーディオシステムで鳴らす。それをコンデンサマイクロホンで入力し、Logスィープ信号を時間反転し、0dBから-6*Log2(w2/w1)まで6db/オクターブで補正する。これをインパルス応答に変換すると、1次、2次、3次、4次、5次の歪成分がそれぞれインパルスとして時間的に分離するので、それぞれを再度フーリエ変換するとそれぞれの次数に対する歪周波数特性が得られる。
Pythonで88.2kspsまたは96kspsに対応する測定システムにしました。
出力信号は低周波の開始位相が0degになるように工夫が必要で、これをおこたると折返し歪が発生して測定がうまくいかなくなります。
Logスイープ信号(10秒間)
<Pythonで必要なモジュール>
#入出力制御、音声ハードとソフトの間をFIFOバッファでデータをやり取り
import pyaudio
#数値計算、ベクトル、FFT、iFFTなど
import numpy as np
#結果をグラフ表示
import matplotlib.pyplot as plt
#32bitや24bitデータと8bitデータに分解してバッファでやり取り
import struct
#現在時間を文字列で取得して測定結果ファイル名に反映するため
import datetime
出力端子は、USB Mic AKG Lyra3のヘッドホンアナログ出力
入力端子は USB Mic AKG Lyra3 デジタル入力
このマイクを使えば入出力それそれに個別にフォーマット設定が可能で、Windowsのサウンド設定の追加のプロパティ、詳細設定で88,2kspsまたは96ksps,24bitのモードで測定できます。
今回は歪特性以外に位相特性も同時表示できるようにしました。
論文のアルゴリズムをプログラミングするだけ、と簡単に言っても、実際はFFTの意味合いやインパルス応答の意味合いと実際の要素の位置関係などをしっかりと把握してプログラミングしないとなかなかうまくいきません。
実際にプログラムを記述すると約600行ほどのプログラムになってしまいました。
pythonだからもっと簡潔に記載できると思ったのですが、グラフ表示したり実際のデータを音声データの24bitフォーマットに変換したり、結構ややこしい処理が必要になりました。
家のステレオはデジタルアンプDENON PMA-50とスピーカーDALI ZENSOR1で、USBでパソコンから出力して測定しました。
一応ハイレゾと呼ばれる類のシステムです。
測定結果Lch 30cm 88.2ksps24bit
同じくサンプリングレートのみ変更して測定
測定結果Lch 30cm 96ksps24bit
30cmでの位置での測定結果は、50Hz~20kHzまで非常にいい周波数ゲイン特性を持っていることが分かりました。しかしながら、位相特性をみると低域でかなり位相が進んでいることがわかりました。これは、アナログである限り、低い周波数でゲインが下がってしまうため、理論的に位相が進んでしまうのはいたしかたありません。家の安価なシステムでも結構いい特性が出ているもんだと感心しました。ちなみに大掛かりなシステムではチャンネルデバイダで複数の帯域に分けて、ゲインや遅延量を調整することで低域の位相進み特性や高域の位相遅れ特性を補正しています。
歪については2次歪~5次歪で、12kHz付近を除き1%(-40dB)以下の特性が出ていることに関心しました。
色々なシステムを測定してみたくなり、家電量販店にどんなステレオやスピーカーが売っているか見にいくと、ほとんどの音響商品が、BluetoothやUSB、Ethernetなどのインターフェースで、アナログ入力端子を持つアンプはわずかしかありませんでした。オーディオ入出力はアナログしか思い浮かばない古い人間には衝撃でした。
つぎはBluetoothやUSBインターフェースでも測定できるように改造して、測定できるスピーカーを増やして報告していきます。