Skip to main content

Адъ меломана: NB Linux USB DAC DSD support

DSD (dsf) on linux native support, mpd (0.20.11) + cantata, DSD support (DOP transport). Играет “нативно”, через USB-транспорт, DSD64 и DSD128, чип TI DSD1796, транспорт XMOS U8,  малопригодный и неудобоваримый усилитель для наушников, чистопородный китаец, одним словом 😉

К счастью, в современном ядре (4.9-4.13) есть все, что нужно для работы данного устройства, никаких патчей или сложных поисков в интернетах не потребовалось – mpd суть умеет “запихать” Native DSD, да вот только устройство не умеет его переварить (пока я так думаю).

Два ключевых момента.

Один важный параметр в mpd.conf – dop (ценителям покопаться для души – сюда , поиск по enable_dsd и далее по тексту). В alsa есть нативная поддержка Native DSD, DoP НЕ нужен, используется для устройств, которые только с DoP и умеют работать, mpd умеет “напихать” нужный формат, если устройство прописано правильно – суть конфиг значения НЕ имеет, если все правильно работает – главное, правильно прописать устройство.

pid_file "/run/mpd/mpd.pid"
db_file "/var/lib/mpd/mpd.db"
state_file "/var/lib/mpd/mpdstate"
playlist_directory "/var/lib/mpd/playlists"
#music_directory "/mnt/snooky_music"
music_directory "/storarray/music"

audio_output {
        type            "alsa"
        name            "DSD1796"
        device          "hw:0,0"        # optional
#       format          "44100:16:2"    # optional
        mixer_device    "hw:0"       # optional
        mixer_control   "HIFI-Ref Output"         # optional
        mixer_index     "1"             # optional
        dop             "yes"
}

Разница, как говорится, на лицо (DSD/DoP off (DSD to PCM decode)):

# mpc 
lossless/DSDdemo/2L-038_stereo-DSD128_01.dff
[playing] #1/1   0:51/9:15 (9%)
volume: n/a   repeat: off   random: off   single: off   consume: off
# sar 1 4
Linux 4.9.60-1-ARCH (kangaroo)  09.11.2017      _armv7l_        (4 CPU)
01:05:22        CPU     %user     %nice   %system   %iowait    %steal     %idle
01:05:23        all     72,36      0,00      1,76      0,00      0,00     25,88
01:05:24        all     70,03      0,00      4,53      0,00      0,00     25,44
01:05:25        all     57,86      0,00     10,97      0,00      0,00     31,17
01:05:26        all     72,10      0,00      4,94      0,00      0,00     22,96
Среднее:     all     <strong>68,08</strong>      0,00      5,56      0,00      0,00     26,36
#

А вот магия DoP (dop = “yes”):

# mpc 
lossless/DSDdemo/2L-038_stereo-DSD128_01.dff
[playing] #1/1   3:55/9:15 (42%)
volume: n/a   repeat: off   random: off   single: off   consume: off
# sar 1 4
Linux 4.9.60-1-ARCH (kangaroo)  09.11.2017      _armv7l_        (4 CPU)
01:09:02        CPU     %user     %nice   %system   %iowait    %steal     %idle
01:09:03        all      1,30      0,00      2,34      0,00      0,00     96,35
01:09:04        all      1,05      0,00      2,10      0,00      0,00     96,85
01:09:05        all      2,09      0,00      1,83      0,00      0,00     96,08
01:09:06        all      0,78      0,00      3,37      0,00      0,00     95,85
Среднее:     all      <strong>1,30</strong>      0,00      2,41      0,00      0,00     96,28
#

68 и 1.3 процента – есть за что стоит побороться на “малине” 😉

Ну и на вкусное – Native DSD, без DoP, нас интерисует Altsetting 2 (спс китайцам 😉 :

$ git diff sound/usb/quirks.c
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 7613b9e07b5c..c7eefbf2bc46 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1353,11 +1353,11 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
        case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
        case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
        case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
+       case USB_ID(0x20b1, 0x000a): /* HIFI-Ref XMOS Ltd */
                if (fp-&gt;altsetting == 2)
                        return SNDRV_PCM_FMTBIT_DSD_U32_BE;
                break;
 
-       case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */
        case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
        case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
        case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */

Неким Gustard’ом пришлось пожертвовать во имя науки 😉 Да и фиг с ним.

$ sudo mv /lib/modules/`uname -r`/kernel/sound/usb/snd-usb-audio.ko.gz ~/
$ make -j 4 sound/usb/snd-usb-audio.ko
$ gzip sound/usb/snd-usb-audio.ko
$ sudo mv sound/usb/snd-usb-audio.ko.gz /lib/modules/`uname -r`/kernel/sound/usb/snd-usb-audio.ko.gz
$ sudo depmod -a

Для справки:

Native DSD

decoder: audio_format=dsd128:2, seekable=true
alsa_output: opened hw:1 type=HW
alsa_output: buffer: size=46..131072 time=260..743039
alsa_output: period: size=23..65536 time=130..371520
alsa_output: format=DSD_U32_BE (Direct Stream Digital, 4-byte (x32), big endian, oldest bits in MSB)
alsa_output: buffer_size=131072 period_size=65536
output: opened "DSD1796" (alsa) audio_format=dsd128:2

DoP

decoder_thread: probing plugin dsdiff
decoder: audio_format=dsd128:2, seekable=true
alsa_output: opened hw:1 type=HW
alsa_output: buffer: size=90..131072 time=255..371520
alsa_output: period: size=45..65536 time=127..185760
alsa_output: format=S32_LE (Signed 32 bit Little Endian)
alsa_output: buffer_size=131072 period_size=65536
alsa_output: DoP (DSD over PCM) enabled
output: opened "DSD1796" (alsa) audio_format=dsd128:2

soxr resampler

decoder_thread: probing plugin dsdiff
decoder: audio_format=dsd128:2, seekable=true
alsa_output: opened hw:1 type=HW
alsa_output: buffer: size=48..131072 time=250..682667
alsa_output: period: size=24..65536 time=125..341334
alsa_output: format=S32_LE (Signed 32 bit Little Endian)
alsa_output: buffer_size=131072 period_size=65536
output: opened "DSD1796" (alsa) audio_format=192000:32:2
soxr: soxr engine 'single-precision'
soxr: samplerate conversion ratio to 0.27
output: converting in=dsd128:2 -&gt; f=dsd128:2 -&gt; out=192000:32:2