libsoxrの設定
概要
libsoxrはリサンプリングで生じるノイズを除去する為にFIRフィルターによるローパスフィルターを内蔵しています。libsoxrはパラメータとして入力信号のサンプリング周波数と出力サンプリング周波数の他にリサンプリング後のフィルターの特性を指定できます。
libsoxrのパラメータ
下記のパラメータでフィルターの特性を指定します。
- passband_end
-3db減衰し始める周波数。ナイキスト周波数を1とする割合で指定します。
- stopband_begin
遮断周波数。ナイキスト周波数を1とする割合で指定します。
- precision
遮断周波数での減衰量を精度(16 から 32)で指定します。
実際の減衰量(stopband_attenuation)は precision x 20.0 x log(2) db になります。
- phase_response
0から100で指定する。よくわかってないので、説明ができません。phase_response以外のパラメータを固定して、phase_responseを50,0,100とした場合のフィルター係数をそれぞれ図−2、図−3、図−4に示します。
- rolloff
パラメータとしてはあるのですが、どのような効果があるかわかりません。係数はいずれの場合も同じになります。下記の値が設定できることになっています。
- 0 slow
- 1 medium
- 2 none
図−1 libsoxrのパラメータ
備考
ナイキスト周波数は
・アップサンプリング時 入力信号のサンプリング周波数の1/2
・ダウンサンプリング時 出力信号のサンプリング周波数の1/2
で、passband_end,stopband_beginにナイキスト周波数をかけるとpassband_end,stopband_beginでの周波数が得られます。
FIRフィルターの係数の例
precision 24
passband_end 0.91
stopband_begin 1.0
phase_response 50
で作成した係数を図-2に示します。
図−2 FIRフィルターの係数の例(precision=24,passband_end=0.91,stopband_begin=1.0,phase_response=50)
図-2の左側の図が係数になります。横軸は係数の個数(tap数)で、この条件でのtap数は897になります。
右上段はフィルターの遮断特性、右下段はその位相特性になります。
横軸はアップサンプル時は出力サンプリング周波数の1/2,ダウンサンプリング時は入力サンプリング周波数の1/2が1として正規化されています。
上記の条件でphase_responseを0とした場合、100とした場合の係数をそれぞれ図-3,図-4に示します。
図−3 FIRフィルターの係数の例(precision=24,passband_end=0.91,stopband_begin=1.0,phase_response=0)
図−4 FIRフィルターの係数の例(precision=24,passband_end=0.91,stopband_begin=1.0,phase_response=100)
lightMPDでの変更点
passband_end,stopband_begin
libsoxrではpassband_end,stopband_beginの設定範囲は
0.0 < passbnad_end < stopband_begin < 2.0
で、2.0 以上の値が設定された場合は% で指定されたとみなします。
この仕様はちょっと混乱するので、lightMPDではこの制限を外し2.0以上の値も設定できます。(2.0以上の値に意味があるかわかりませんが)
single stage
lightMPDではsingle stage というパラメータを追加しました。
libsoxrでは整数倍のリサンプリングにおいても、複数回のリサンプリング処理によって目的のサンプリング周波数に変換します。
libsoxrではリサンプリング処理をstageと読んでいます。
stageが複数になる条件は以下のようになります。倍率(アップサンプリング),分周比(ダウンサンプリング)は2のべき乗とします。
2のべき乗でない場合はもっと複雑になります。
- アップサンプリング
- 8倍以上のアップサンプリングでは,倍率をmとすると下記のように2回のアップサンプリングが行われます。
- stage-1 2倍のアップサンプリング
- stage-2 m/2倍のアップサンプリング
- 8倍以上のアップサンプリングでは,倍率をmとすると下記のように2回のアップサンプリングが行われます。
- ダウンサンプリング
- 分周比が2になるまで1/2のダウンサンプリングを行います。このstageでは非常に軽いローパスフィルターがかけられます。
- 最後のステージで目的の特性を得るためのローパスフィルターを伴った1/2のダウンサンプリングを行います。
dsd2pcmではダウンサンプリングを行う時のフィルターの係数をlibsoxrで求めることができます。
係数が複数になると困るので、上記の場合でも1stageで処理されるような変更を行いました。
係数のexport
libsoxrのインターフェイスを拡張して、libsoxrが生成した係数を外部へ取り出せるようにしました。
また、libsoxrの係数を外部へ取り出すユーティリティも用意しました。
mpd.confでの設定
mpd.confのaudio_format で出力のサンプリング周波数を指定するとリサンプリング処理が行われます。
リサンプラーは resampler パラメータで指定します。
audio_format
lightMPDでは出力サンプリング周波数の指定は基本周波数(44.1KHz,48KHz)の倍数で指定できます。
下記のように指定します。
audio_format "Xn1Ln2,n3:bit depth:channel"
1. Xn1Ln2,n3
出力サンプリング周波数を指定します。
- n1
出力サンプリング周波数を入力周波数のn1倍にする
- n2
44.1KHz 系列の信号の上限をn2 * 44.1KHz にする
- n3
48KHz 系列の信号の上限をn3 * 48KHzにする、n3を省略した場合は n3 = n2 とする
2. bit depth
出力のビット長を指定します。設定できるのは 8,16,24,32 です。
最近のmpdの仕様では
- f
-1.0 から 1.0 の単精度浮動小数点数
- dsdXX
dsdを指定できるようですが、不明です。
3. channel
出力チャンネル数を指定します。
参考
audio_outputのformatとの違い
audio_format の他に audio_output での formatパラメータでも出力フォーマットの指定ができます。両者の違いは処理されるスレッドで audio_formatで指定した場合、decoder スレッドで処理が行われます。
audio_outputのformatで指定した場合はoutputスレッドで行われます。mpdではoutputスレッドはFIFOモードで動作しているので、outputスレッドでリサンプラーのような高負荷の処理は行わないほうがいいでしょう。
従って出力フォーマットの指定はaudio_format で行うほうがいいです。
audio_formatでoutput デバイスの能力以上のサンプリング周波数を指定するとoutputスレッドでoutputデバイスに合わせてリサンプリングが行われるので注意して下さい。
将来的に
audio_formatで入力サンプリング周波数毎に出力のサンプリング周波数を指定出来るように検討しています。
resampler
resampler でlibsoxrのパラメータを設定できます。
1. 従来の設定方法
resampler {
plugin "soxr"
quality "very high"
}
qualityでローパスフィルターの特性を指定します。
qualityの設定値とその時のローパスフィルターの特性の表を表-1に示します。
表-1 quality の諸元
参考
"VERY HIGH","HIGH","MEDIUM"のpassband_endは下式で求めています。
passband_end = 1 - 0.05 / ((1.6E-6 * a - 7.5E-4) * a + 0.646)
a : stopband_attenuation
2. 詳細設定
qualityが無いときに下記のパラメータでローパスフィルターの特性を指定できます。下記パラメータを指定してもqualityがあるとqualityを優先します。
- precision
stopband_beginでの減衰量を指定します。設定範囲は16 から 32です。
実際の減衰量は
precision * 20.0 * log(2)
になります。
- passband_end
減衰し始める周波数をナイキスト周波数を1とする割合で指定します。0.0 より大きい値を指定します。
- stopband_begin
precisionで指定した減衰量になる周波数をナイキスト周波数を1とする割合で指定します。
0.0 < passband_end < stopband_begin
の範囲で指定します。
- rolloff
どのような効果があるかわかっていません。この値を変化させても係数は変わりません。
下記の値を指定できます。
"0" small rolloff
"1" medium rolloff
"2" none
- phase_response
0.0 - 100.0の範囲で指定します。
- single_stage
”yes"を指定すると1stageで処理を行います。"no"を指定すると条件によっては複数stage で処理がおこなれます。
”yes"を指定したほうが負荷は高くなります。
- threads
"0"を指定すると全チャンネルの処理を同時に行います。lightMPDでは"0"を指定して下さい。
- quality_spec_xx
変換規則を指定します。xxは規則を識別するもので任意のアルファベット及び数字からなる文字列。
変換規則はリサンプリングの条件毎にフィルターの特性を指定します。
変換規則
変換規則は下記のように指定します。
入力サンプリング周波数:出力サンプリング周波数=precision:passband_end:stopband_begin:phase:rolloff:single_stage
入力サンプリング周波数:出力サンプリング周波数がリサンプリング条件になります。
リサンプリング処理では変換規則にリサンプリング条件があればそのパラメータを用いてリサンプリングを行います。
それ以外の場合はprecisionからsingle_stageまでのパラメータを使用します。
設定例
resampler {
plugin "soxr"
precision "24"
passband_end "0.91"
stopband_begin "1.00"
rolloff "0"
phase_response "50.0"
single_stage "yes"
threads "0"
quality_spec_01 "88200:352800=24:0.54:1.0:50.0:0:yes"
quality_spec_02 "176400:352800=24:0.27:1.0:50.0:0:yes"
quality_spec_03 "88200:705600=24:0.54:1.0:50.0:0:yes"
quality_spec_04 "176400:705600=24:0.27:1.0:50.0:0:yes"
quality_spec_11 "96000:384000=24:0.5:1.0:50.0:0:yes"
quality_spec_12 "192000:384000=24:0.25:1.0:50.0:0:yes"
quality_spec_13 "96000:768000=24:0.5:1.0:50.0:0:yes"
quality_spec_14 "192000:768000=24:0.25:1.0:50.0:0:yes"
quality_spec_31 "2822400:705600=24:0.0625:0.125:50.0:0:yes"
}
この設定例はlightMPDに付属のmpd.confのものです。
上記のパラメータでは
44.1KHzを176.4KHzに変換する場合
20KHz(44.1KHz / 2 * 0.91)から減衰し始めて22.05KHzで150dBまで減衰させます。
192KHzを768KHzに変換する場合
87KHz(192KHz / 2 * 0.91)から減衰し始めて96KHzで150dBまで減衰させます。
44.1KHzの場合はCDが20KHz以上の信号が記録されていないことを考慮すると妥当だと思われます。
192KHzにおいては、いわゆるハイレゾ音源でも80KHzの信号が入っていることはまずありませんし、あったとしても聞こえません。
この事を考慮すると24KHzあたりから減衰させても問題ないと考えて quality_spec_14で 24KHz(192KHz / 2 * 0.25)から減衰させるように設定しています。
quality_spec_31はdsd64を705600(16fs)のpcmに変換する規則です。
22.05KHzから減衰し始めて44.1KHzで150dB減衰します。
passband_endをもう少し大きくして24KHzあたりにもっていきたいのですが、そうするとapu2でも処理が間に合わなくなります。
stopband_beginを大きくするとdsd64のノイズが取り切れなくなります。ノイズといっても80KHzあたりからですので気にしなければもう少し大きくできます。