26.2.13 更新:更新信息与配置

起源

今年年初我入手了飞傲 JT7 和 iBasso DC04U。在安卓下两者配合使用没有问题,但把 DC04U 接到 Linux 上时,却发现无法直出 DSD。

最后发现设备太新,没有收录到 Linux 内核中,但在 7.0 版本之后就不再需要下面的 patch 了,仅做记录

为设备添加 patch

我尝试过多款播放器:mpd、Strawberry、DeaDBeeF、HQPlayer,但都未能实现 DSD 直出。折腾下来,最高只能输出 PCM 768 kHz。

PCM768
PCM768

查看 ALSA 报告后发现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
iBasso DC04U at usb-0000:00:14.0-2, high speed : USB Audio

Playback:
Status: Stop
Interface 2
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x07 (7 OUT) (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Bits: 16
Channel map: FL FR
Sync Endpoint: 0x83 (3 IN)
Sync EP Interface: 2
Sync EP Altset: 1
Implicit Feedback Mode: No
Interface 2
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 0x07 (7 OUT) (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Bits: 24
Channel map: FL FR
Sync Endpoint: 0x83 (3 IN)
Sync EP Interface: 2
Sync EP Altset: 2
Implicit Feedback Mode: No
Interface 2
Altset 3
Format: S32_LE
Channels: 2
Endpoint: 0x07 (7 OUT) (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Bits: 32
Channel map: FL FR
Sync Endpoint: 0x83 (3 IN)
Sync EP Interface: 2
Sync EP Altset: 3
Implicit Feedback Mode: No
Interface 2
Altset 4
Format: SPECIAL
Channels: 2
Endpoint: 0x07 (7 OUT) (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Bits: 32
DSD raw: DOP=0, bitrev=0
Channel map: FL FR
Sync Endpoint: 0x83 (3 IN)
Sync EP Interface: 2
Sync EP Altset: 4
Implicit Feedback Mode: No

直出 DSD 需要的 DSD_U32_BE(或 DSD_U32_LE),在 Linux 上 ALSA 并未显示该格式。用 aplay 排查,同样不支持:

1
2
3
4
5
6
7
8
aplay -D hw:1,0 --dump-hw-params /dev/zero

...
Available formats:
- S16_LE
- S32_LE
- SPECIAL
- S24_3LE

照理说 iBasso 支持 UAC 2.0,应具备完整能力,但当前 ALSA 并未识别到 DSD_U32_BE。

解决办法

幸运的是,我找到了仓库 xmos-native-dsd。通过修改内核的 sound/usb/quirks.c,为该设备添加一个 quirk 即可识别 DSD_U32_BE。

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 2d9f28558..d550c84e7 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2236,6 +2236,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
DEVICE_FLG(0x0644, 0x806c, /* Esoteric XD */
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
QUIRK_FLAG_IFACE_DELAY | QUIRK_FLAG_FORCE_IFACE_RESET),
+ DEVICE_FLG(0x0661, 0x0883, /* iBasso DC04U */
+ QUIRK_FLAG_DSD_RAW),
DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */
QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */

应用补丁并重编译内核后,再次运行 aplay 检查:

1
2
3
4
5
6
7
...
Available formats:
- S16_LE
- S32_LE
- SPECIAL
- S24_3LE
- DSD_U32_BE

For Arch User

我选择基于 linux-cachyos 的 PKGBUILD 修改来构建 ArchLinux 包。

只需要下载 linux-cachyos快照

编辑 PKGBUILD,在 source 段添加 patch 文件,同时修改 pkgrel

1
2
3
4
5
6
7
8
9
10
...
pkgrel=3 # 请高于原本的值
...
source=(
"https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/${_srcname}.tar.xz"
"config"
"${_patchsource}/all/0001-cachyos-base-all.patch"
"quirks.patch" # patch 文件名
)
...

构建:

#

在此之前,请先确认您的 DAC 能在 Linux 下识别到 DSD 支持:

使用 aplay -D hw:1,0 --dump-hw-params /dev/zero 查看

1
2
3
4
5
6
7
...
Available formats:
- S16_LE
- S32_LE
- SPECIAL
- S24_3LE
- DSD_U32_BE

如果没有 DSD_xx 可能是您的 DAC 没有被 Linux 收录,需要手动 Patch,参见上面折叠部分

因为我在使用 PipeWire,可通过 pw-cat 测试原生 DSD 输出:

1
pw-cat -p -d sample.dsf
DSD512
DSD512

免费的DSD64测试音源:FreeDSD Download NativeDSD Music

音乐播放器

能够输出 DSD 只是完成了第一步,选择一个合适的播放器同样重要。

MPD

我曾尝试过 hqplayer-client hqplayer-embedded rygel deadbeef 等一系列播放器。

但考虑到可扩展性,我决定使用 MPD + Euphonica

MPD 是 C/S 架构的音乐播放器,除了 Euphonica,还有很多 TUI/GUI 可选,详见 MPD 客户端

PipeWire 可以直出 DSD,其 MPD 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
audio_output {
type "pipewire"
name "DC04U"

dsd "yes" # 启用 DSD 直出

# dsd_usb "yes" # 请不要启用
# mixer_type "none" # 禁用软件音量控制
}

music_directory "/run/media/vconet/DATA/Musics/"

bind_to_address "~/.config/mpd/socket"

playlist_directory "~/.config/mpd/playlists"

db_file "~/.config/mpd/database"

sticker_file "~/.config/mpd/sticker.sql"

audio_output {
type "fifo"
name "Visualizer"
path "/tmp/mpd.fifo"
format "44100:16:2"
}

在 PipeWire 下,你仍然可以通过 ALSA 独占,但这会导致 MPD 播放音乐时,会导致其他应用尝试播放音频时,可能会卡死应用。

MPD 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
audio_output {
type "alsa"
name "DC04U"
device "hw:DC04U,0"

dop "no" # 强制优先 DSD Native
# 禁用 MPD 的内置转换
auto_resample "no"
auto_format "no"
auto_channels "no"

# dsd_usb "yes" # 请不要启用
# mixer_type "none" # 禁用软件音量控制
}

music_directory "/run/media/vconet/DATA/Musics/"

bind_to_address "~/.config/mpd/socket"

playlist_directory "~/.config/mpd/playlists"

db_file "~/.config/mpd/database"

sticker_file "~/.config/mpd/sticker.sql"

audio_output {
type "fifo"
name "Visualizer"
path "/tmp/mpd.fifo"
format "44100:16:2"
}

ALSA 设备名可通过 aplay -L 查看

无论是 PipeWire 还是 PipeWire + ALSA,都不能在直出 DSD 的同时播放其他音频。

仅在 PipeWire 下直出 DSD 时,其他应用尝试播放音频时,不会卡死。

应用不再播放音频时,仍可能占用设备,需自行重启 PipeWire 或拔插设备。占用情况可通过 pw-top 查看

不依赖 Systemd 的 MPD 配置,请自行查看 MPD 配置

Euphonica

Euphonica 就很简单了:在设置里指定 socket 地址,在 Visualizer data source 下将 Data Source 设为 MPD FIFO,修改 FIFO file 后点击 Apply 即可。

至此,iBasso DC04U 在 Linux 下可以实现 DSD 直出与常规播放。