Linux で Sony WALKMAN NW-A45 を DSD Direct に対応させる備忘録です.
はじめに
Sony WALKMAN の最近の Aシリーズ(NW-A45 とか NW-A55 とかですね.残念ながら NW-A100 系はダメですが)は USB-DAC として使えるのですが,残念ながら Linux で使う場合はそのままだと DoP (DSD over PCM) でしか使えません.
NW-A45 の場合は DoP だと DSD64 だけ対応,DSD Direct だと DSD128 までの対応と,入力できる DSD の範囲が変わってきますので,どうせなら Linux でも DSD128 に対応させてみようと色々やってみた備忘録です.なお,
とか
あたりの記事がとても参考になりました.
DAC の DSD Direct 対応有無の確認
まず,自分の持っている DAC が Linux で DSD Direct に対応しているか否かを確認する方法ですが,これは次のようにすれば分かります(/proc/asoud/WALKMAN 以下はもちろん自分の DAC のものに読み替えてください).
$ sudo cat /proc/asound/WALKMAN/stream0 ..... Sony WALKMAN at usb-0000:01:00.0-1.2, high speed : USB Audio Interface 1 Altset 6 Format: S16_LE Channels: 2 Endpoint: 1 OUT (ASYNC) Rates: 44100, 48000, 88200, 96000, 176400, 192000 Data packet interval: 125 us Bits: 16 Channel map: FL FR Interface 1 Altset 7 Format: SPECIAL Channels: 2 Endpoint: 1 OUT (ASYNC) Rates: 44100, 48000, 88200, 96000, 176400, 192000 Data packet interval: 125 us Bits: 32 DSD raw: DOP=0, bitrev=0 Channel map: FL FR
結果を見ると,例えば NW-A45 は PCM 44100, 2ch, 16bit に対応していることが見てとれますが,DSD に関係するのは Format: SPECIAL の部分です.上の表示は DAC が DSD Direct に対応していない場合,下が DSD Direct に対応している場合となります.
$ sudo cat /proc/asound/WALKMAN/stream0 Sony WALKMAN at usb-0000:01:00.0-1.1, high speed : USB Audio ...... Interface 1 Altset 7 Format: SPECIAL DSD_U32_BE Channels: 2 Endpoint: 1 OUT (ASYNC) Rates: 44100, 48000, 88200, 96000, 176400, 192000 Data packet interval: 125 us Bits: 32 DSD raw: DOP=0, bitrev=0 Channel map: FL FR
つまり,DSD_U32_BE (DSD_U32_LE という表示になる DAC もあるっぽい)という表示があるか否かで DSD Direct に対応しているか否かを見分けることができます.
そして,この DSD Direct の対応有無を実際に判定しているのは,Linux Kernel で,対応するソースコードの位置は,sound/usb/quirks.c です.
ソースコード(とコメント)を眺めてみればすぐに分かりますが,ソースコードのこの部分はサウンドインターフェースの「癖 (quirk)」を吸収する部分になっていて,結構泥臭くサウンドインターフェースのメーカーや機種ごとの動作切り替えや対応形式の判定を行っています.
つまり,基本的には quirks.c に自分の持っているDACに対応する動作切り替え・対応形式の判定ルーチンを付け加え,カーネルを再コンパイルすれば DAC を DSD Direct に対応させられるということになる訳です.
Raspberry pi OS の場合の対応例
これを Raspberry pi OS で実際にやってみた手順が以下の通りです.
まず,Raspberry pi OS のインストール等をやらないとダメですが,これについては本家
や他にもいろいろなところに記事がありますので省略します.
次に Kernel の書き換えとコンパイルをしなければなりませんが,Raspberry pi OS の場合は
に公式の手順が示されています.
まず,Kernel をコンパイルするために必要なパッケージを持ってきます.
$ sudo apt install git bc bison flex libssl-dev make
次に,Kernel ソースコードを準備します.
$ mkdir src $ git clone --depth=1 https://github.com/raspberrypi/linux
これで Kernel が手元に準備できましたので,必要な部分を書き換えます.
$ cd src/linux $ cp sound/usb/quirks.c sound/usb/quirks.c.orig $ vi sound/usb/quirks.c
WALKMAN に対応させるためにはたった1行付け加えれば良いだけです.
$ diff -p sound/usb/quirks.c.orig sound/usb/quirks.c *** sound/usb/quirks.c.orig 2022-02-04 00:22:28.796438144 +0900 --- sound/usb/quirks.c 2022-02-04 02:25:28.610620540 +0900 *************** u64 snd_usb_interface_dsd_format_quirks( *** 1816,1821 **** --- 1816,1822 ---- * from XMOS/Thesycon */ switch (USB_ID_VENDOR(chip->usb_id)) { + case 0x054c: /* Sony devices */ case 0x152a: /* Thesycon devices */ case 0x20b1: /* XMOS based devices */ case 0x22d9: /* Oppo */
ここで 0x054c というのは Sony に対応する USB VENDOR ID です.つまり Sony の USB Audio Interface なら強制的に DSD_U32_BE に対応させています.なお,USB VENDOR ID の調べ方ですが,これは良くやるように
$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 005: ID 054c:0b8c Sony Corp. WALKMAN Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
で分かります.上記は NW-A45 の場合で,この場合は USB VENDOR ID が 054c で USB PRODUCT ID が 0b8c だということですね.
ただし,USB-DAC ならどれでも同様なやり方で対応させられる訳ではないようです.ソースコードを見ると,TEAC とかのものだと DOP と DSD Direct を切り替える処理が必要みたいですし,ある程度遅延を入れないといけないようなものもあるっぽい.
しかし,NW-A45 の場合はこれで必要な書き換えは全てなので,あとは Kernel のコンパイルと置き換えを行います(本当は ver 表記なんかをきちんと書き換えてやった方が良いとは思いますが面倒なので省略しています.また,以下は Raspberry pi 4 64bit kernel の手順です.その他の場合については公式ページを参照してください).
$ cd linux $ KERNEL=kernel8 $ make bcm2711_defconfig $ make -j4 Image modules dtbs $sudo make modules_install $ sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/ $ sudo cp arch/arm64/boot/dts/overlays/*.dtb* /boot/overlays/ $ sudo cp arch/arm64/boot/dts/overlays/README /boot/overlays/ $ sudo cp arch/arm64/boot/Image /boot/$KERNEL.img
Raspberry pi4 でだいたい小1時間かかります.
Kernel のコンパイルと導入が完了したら再起動すればこれで手持ちの DAC の DSD Direct 出力に対応したものになっているはずです.試しに,
$ sudo cat /proc/asound/WALKMAN/stream0 Sony WALKMAN at usb-0000:01:00.0-1.1, high speed : USB Audio ...... Interface 1 Altset 7 Format: SPECIAL DSD_U32_BE Channels: 2 Endpoint: 1 OUT (ASYNC) Rates: 44100, 48000, 88200, 96000, 176400, 192000 Data packet interval: 125 us Bits: 32 DSD raw: DOP=0, bitrev=0 Channel map: FL FR
のように USD_U32_BE の文字列が入ることを確認してください.
実際に DSD を再生してみる
ここまでで Linux 自体をお手持ちの USB-DAC での DSD Direct に対応させることはできましたが,実際に音がなるかどうかはキチンと試してみなければ分かりません.
その為にはまずは各種フォーマットの DSD 音源を準備する必要がありますが,ありがたいことに,
にサンプル音源を公開してくれている方がおられます.
このサンプル音源を用いて実際に手持ちの DAC での DSD Direct 再生ができるかどうか試すには,以下のようにやるのが一番簡単だと思います(http://… 以下はもちろん試す DSD 音源の URL に置き換えてください).
$ wget http://www.lindberg.no/hires/test/2L-145/2L-45_stereo_01_DSF_2822k_1b.dsf $ aplay -D hw:CARD=3,DEV=0 -v -f DSD_U32_BE -c 2 -r 88200 2L-45_stereo_01_DSF_2822k_1b.dsf
ただし,ここでいくつか注意しないといけないことがあります.
まず,hw:CARD=3 の部分は,aplay -l の表示を見て変更する必要があります.例えば,
$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7 card 1: vc4hdmi0 [vc4-hdmi-0], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0] Subdevices: 1/1 Subdevice #0: subdevice #0 card 2: vc4hdmi1 [vc4-hdmi-1], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0] Subdevices: 1/1 Subdevice #0: subdevice #0 card 3: WALKMAN [WALKMAN], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0
なら,WALKMAN は CARD 3 となっているので,hw:CARD=3 です.
また,-r 88200 の部分も DSD 音源の種類に応じて以下のように変える必要があります.
- DSD64: 88200
- DSD128: 176400
- DSD256: 352800
今回のサンプル音源の場合は DSD64 なので 88200 です.
最後に,この方法で再生した場合は曲にノイズが入ります.これは,aplay の仕様で仕方がないことらしいのですが,このあたりについては,記事
を参照してください.
ノイズが入らないように再生したければ,これ以外の方法を試さざるを得ませんが,比較的簡単なのは mpd と mpc を使う方法だと思います.やり方についてはググって頂ければいくらでも見つかると思います.
おわりに
上記の方法で私の持っている NW-A45 の場合は DSD64 と DSD128 を DSD Direct で再生することができました,しかし,意味があるのかと言われると,多分自己満足できたこと以外の意味はないです.
と言うのも,NW-A45 は DSD を中で PCM に変換してから再生する,つまりDSD の直接再生には対応していませんし,そもそも私はサンプル以外の DSD 音源を持ってません.持っている音源は PCM のものだけです.さらに現行の A100 シリーズと ZX500 シリーズは残念ながら USB-DAC 機能が省かれてしまっています.
と言うことで,やってみたは良いがなんだかなぁ……と思っていましたが,つい先日発表された WM1 シリーズ (NW-WM1ZM2 と NW-WM1AM2) では USB-DAC 機能が復活しているよう.そして,仕組みから考えて多分同じ方法で WM1 シリーズでも全く同じようにやれば DSD Direct に対応した USB-DAC として使えるんじゃないかんと思います.
WM1 シリーズ,DSD の直接再生に対応してますし,何と言っても16万円以上するフラグシップ機で,このシリーズ買うような人なら DSD 音源も多数所有しているでしょうから,この記事にも意味が出てくるんじゃないかと.まぁ,私のお小遣いでは WM1 系ってとても手が届かないんですけどね(悲).
しかし,今回試してみて Linux でコンソールで簡単に DSD 音源を再生する方法がなさそうなのには困りました.正直試すだけに mpd とか mpc とか設定するの大変すぎます.
もしどなたか簡単な方法御存知の方おられましたら,教えていただけると助かります.あと,WM1 シリーズで DSD Direct この方法で対応できたよって人おられたら教えてください.
以上!