dsd2pcm
概要
lightMPD v1.2.0からdsd2pcmの拡張を行いました。その背景と設定方法について説明します。
履歴
- 第0版 2019.06.04
dsd2pcmについて
dsd信号を適切なローパスフィルターを通すことによりPCM信号に変換できます。dsd信号には図-1に示すように強烈なノイズを含んでいます。ローパスフィルターはこのノイズを除去出来なければなりません。
図-1 DSDのノイズフロアー
(https://positive-feedback.com/audio-discourse/raising-the-sample-rate-of-dsd-is-there-a-sweet-spot/から引用)
MPDのdsd2pcmでは dsd信号を1/8にダウンサンプリング することでPCM信号に変換します。その際にローパスフィルターがかけられるのですが、そのローパスフィルターの特性は図-2のようになっています。
図-2 dsd2pcmの係数
libsoxr の パラメータではほぼ
- passband_end=0.113
- stopband_begin=1.65
- precision=24
- phase_response=50
ぐらいです。
dsd64の場合は352.8KHzのPCMに変換されますが、このフィルターではノイズが取り切れません。この後でさらにローパスフィルターをかけることが前提になっていると思われます。
図-3 はdsd64の1KHzサイン波のスペクトルです。この信号はWaveGene Ver 1.50で44.1KHz/24の1KHz/0Dbのサイン波を作成し,それをTEAC Hi-Res Editor でdsd64に変換して作成しました。
図-3 DSD64の1KHzサイン波のパワースペクトル
この信号をdsd2pcmに通すと図-4の左側のような波形が得られます。図-4の右側のグラムは図-4のパワースペクトルです。図-4からノイズの除去が不十分で有ることがわかると思います。
図-4 DSD64の1KHzサイン波を352.8KHzのPCMに変換した結果
dsd2pcmの後の処理はDACの能力によって以下の2通りに別れます。
- 8fs以上再生可能なDACの場合は352.8KHzのまま(ノイズを含んだまま)DACに送られます。
- 4fs以下まで再生可能なDACの場合
- mpdではDACの能力を超えた信号を再生する場合はDACの能力に合わせてリサンプリングが行われます。。
- 例えば、4fsまで再生可能なDACの場合はそのサンプリング周波数の上限は192KHzですから、352.8KHz -> 192KHzの変換が行われます。
- この変換にはリサンプラーが使われますが、リサンプラーにlibsoxrを指定した場合、passband_end=0.91ですから87KHz(0.91 x 96KHz)まではフラットです。
- これではdsd2pcmのフィルターで取り切れなかったノイズを充分には除去できません。
- リサンプラーではpassband_endを20KHzあたりに設定するか、出力サンプリング周波数を44.1KHz,88.2KHzあたりに設定する必要があります。
1.,2. いずれの場合もノイズを含んだ信号が送られるので、DACのフィルターで除去する必要があります。現在のDACでは問題にならないと思いますが、DACにはなるべくノイズを除去した信号を出力したかったのと、dsd->pcm変換においてローパスフィルターの性能は音質に影響するのでは、と考えてdsd2pcmの改造を行いました。
図-5は
- passband_end=0.125
- stopband_begin=0.25
- precision=24
- phase_response=50
のローパスフィルターで図-3の信号を352.8KHzのPCMに変換した結果です。30KHzあたりの盛り上りでも-120DBぐらいに抑えられています。
この盛り上がりをなくすにはstopband_beginを0.25より小さくする必要がありますが、そうするとlightMPDが対象としているCPUでは処理が追いつかなくなります。(APU2ではもう少し小さくできます)
図-5 dsd2pcmの変換例
dsd2pcmの改造
1. 出力フォーマット(サンプリング周波数、bit長)を指定できるようにしました
2. その際のローパスフィルターを変換の条件(DSDのサンプリング周波数とPCMのサンプリング周波数)毎に設定できるようにしました
3. libsoxrを使ってローパスフィルターの係数を求めことができるようになりました
4. ローパスフィルターをリサンプラーで行うことが出来るようにしました
- dsd2pcm 単体
- dsd2pcm + リサンプラー
- オリジナルのdsd2pcmと同じようにdsd2pcmで軽い変換を行いリサンプラーで必要なノイズの除去を行うことができます。
- リサンプラー単体
の方法を選択できます。リサンプラーとしてlibsoxrを使う場合はlibsoxrでフィルターの特性を任意に設定できます。
5. 全てdecoderスレッドで行うようにしました
オリジナルのdsd2pcmの場合、リサンプラーはoutputスレッドで動作します。mpdのoutputスレッドはリアルタイムプロセスとして動作しているので負荷の高い処理は行わないほうが安全です。dsd2pcmおよびリサンプラーともdecoderで動作します。
mpd.confでの設定
dsd2pcmのlightMPDで強化した部分を拡張モードと呼びます。
拡張モードの指定
decoderでoutputを指定すると拡張モードになります。
decoder {
plugin "dsd"
output "pcm"
}
decoder {
plugin "dsdiff"
output "pcm"
}
outputで指定出来るのは”pcm"だけです。outputパラメータは今回の改造で新設しました。outputが指定されていない時はオリジナルの動作を行います。
変換ルールの指定
dsd2pcm パラメータで 変換のルールを指定します。dsd2pcmパラメータは今回の改造で新設しました。
dsd2pcm {
フォーマット1 "出力サンプリング周波数:bit長:分周比:フィルターの特性”
フォーマット2 "出力サンプリング周波数:bit長:分周比:フィルターの特性”
。。。
}
フォーマット
dsd64,dsd128,dsd256 が指定できます。この場合のDSDはそれぞれ 64 * 44.1KHz, 128 * 44.1KHz, 256 * 44.1KHzになります。
48KHz系列の場合は、dsd64_48, dsd128_48, dsd256_48 で指定します。(これは未テストです)
このパラメータで指定されていないデータの場合はmpdのデフォルトの動作を行います。
出力サンプリング周波数
変換後のPCMの出力サンプリング周波数を指定します。
分周比
dsd2pcmでダウンサンプリングする分周比を指定します。0および8の倍数で指定します。
- 0の場合
- dsd2pcmではサンプリング周波数の変換を行わず、リサンプラーでサンプリング周波数の変換を行います。
- 8の倍数の場合
- 分周比に従ってdsd2pcmでダウンサンプリングします。その際にフィルターの特性で指定されるフィルターをかけます。
- dsdのサンプリング周波数 / 出力サンプリング周波数 <> 分周比
- の場合、dsd2pcmのあとでリサンプラーで、
- dsdのサンプリング周波数 / 分周比 -> 出力サンプリング周波数
- の変換が行われます。
フィルターの特性
分周比で指定したダウンサンプリングにおけるローパスフィルターの特性を指定します。
以下のように指定します。
SOXR_COEF(precision,passband_end,stopband_begin,phase_response,rolloff,single_stage)
各パラメータについては (libsoxrについて)を参照して下さい。
なお、single_stageは必ず”yes"になります。single_stageは省略可能です。
設定例
dsd64 を 176.4/32 に変換する
- dsd2pcmで行う場合
dsd64 "176400:32:16:SOXR_COEF(24, 0.25, 0.5, 50, 0)"
- dsd2pcmで352.8KHzに変換してから、リサンプラーで352.8KHz -> 176.4KHzの変換を行う。
dsd64 "176400:32:8:SOXR_COEF(24, 0.2, 1.0, 50 , 0)"
- リサンプラーがlibsoxrの場合は 352.8KHz -> 176.4KHzの変換を行う際のフィルターを設定しておきます。
- リサンプラーだけで行う
dsd64 "176400:32:0"
- リサンプラーがlibsoxrの場合は 2822400Hz -> 176400Hzの変換を行う際のフィルターを設定しておきます。