ChrisKim
Do not go gentle into that good night.
颢天

编译 llusbdac 解决索尼 Walkman 系列 DAC 延迟

老系统的索尼 mp3 一直存在一个问题,如果启用它的 DAC 功能将其当作声卡使用时,会有高达 1~2s 的延迟。如果是听音乐延迟不影响,但如果将其用作电脑声卡看视频、打游戏的话,这个体验将会是灾难性的。

这个问题我一直没有办法解决,直到今天在网上冲浪时,惊喜地发现了一位大佬为解决这个问题编写了一个插件,这个插件提供低延迟 DAC 功能,其 DAC 延迟低至 50ms(即完全不可见),同时该插件也不影响原版的 DAC 功能。可以说是完美解决了这个问题。

下面是这个插件的 GitHub 仓库:

作者提供了中文的用户手册,感兴趣的可以先看下,功能是否符合自己预期:https://github.com/zhangboyang/llusbdac/blob/master/userguide/USERGUIDE_ZH.md

根据 GitHub Issue 和其他论坛内的讨论,该插件适用于:NW-ZX300A、NW-WM1A/Z、NW-A35、NW-A45、NW-A55

但是这个作者只有 NW-ZX300 这台设备,因此作者只为这台设备制作和测试了一键安装包,其他播放器型号就得靠我们自己编译了。

研究了一下午作者的安装源码和脚本,最后终于成功搞定了这个插件的编译和安装,在此分享给大家完整的流程。

warning 警告
安装 LLUSBDAC 需要修改播放器的固件。而修改固件具有一定危险性,可能会导致失去保修,错误操作甚至可能损坏设备。

注意

作者仅为 ZX300A 制作了一键安装包,其他型号需要完整走一遍编译过程,并且作者提供的自动安装脚本也并不能完整使用,有很多手动操作

因此该教程内容非常硬核,请确保你具有以下环境或知识:

  • Windows 系统:作者的安装脚本与 Windows 系统强耦合,仅适配 Windows。
  • Linux 系统:拥有 Linux 物理机 / 虚拟机 / 子系统 / 服务器均可。
  • Linux 基本使用:Linux 基础指令。
  • C 语言编译知识:会跟着这个教程走就行,一般来说不会报错。
  • 支持二进制的文本编辑器:例如 VSCode、Sublime。
  • Python 环境:拥有可用的 Python 解释器环境。
  • Pip 使用方式:会跟着这个教程走就行,一般来说不会报错。
  • Windows 权限管理:会跟着这个教程走就行,一般来说不会报错。

编译插件

准备系统

本文需要 Linux 系统作为编译环境,你可以使用 wsl2,也可以使用虚拟机,也可以租用云服务器。本文使用的环境是 wsl2 中的 Ubuntu 22.04 LTS.

如果你不了解 Linux 操作,建议选择系统的时候选择一样的,防止操作步骤不同(至少也得选 Debian 系的)

配置环境

首先得安装需要用到的软件包。先刷新下软件包列表,可能要输入密码:

sudo apt update

然后安装需要用到的软件包,git 用来拉库、nano 是文本编辑器、make 用来编译、wget 用来下载文件:

sudo apt install -y git nano make wget

拉取代码库

使用 git 从 GitHub 拉取插件源码,如果速度过慢可以尝试使用科学上网:

git clone https://github.com/zhangboyang/llusbdac.git

准备交叉编译工具链

进入刚拉取的仓库:

cd llusbdac/

运行作者写好的配置工具链脚本 get_toolchain.sh,如果速度过慢可以尝试使用科学上网:

./get_toolchain.sh

当出现以下信息的时候,说明运行正确:

gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz: OK

=== TO ADD COMPILER TO YOUR $PATH, PLEASE RUN ===
    . setpath

将工具链加入环境变量(注意,该操作为临时生效,注销/重启过后需要重新进行该操作):

. setpath

测试工具链:

arm-linux-gnueabihf-gcc -v

如果出现以下输出,则工具链配置正确:

Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/chriskim/llusbdac/toolchain/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/snapshots/gcc-linaro-4.9-2017.01/configure SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libmudflap --enable-lto --enable-objc-gc --enable-shared --without-included-gettext --enable-nls --disable-sjlj-exceptions --enable-gnu-unique-object --enable-linker-build-id --disable-libstdcxx-pch --enable-c99 --enable-clocale=gnu --enable-libstdcxx-debug --enable-long-long --with-cloog=no --with-ppl=no --with-isl=no --disable-multilib --with-float=hard --with-mode=thumb --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --enable-threads=posix --enable-multiarch --enable-libstdcxx-time=yes --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/sysroots/arm-linux-gnueabihf --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-checking=release --disable-bootstrap --enable-languages=c,c++,fortran,lto --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu
Thread model: posix
gcc version 4.9.4 (Linaro GCC 4.9-2017.01)

准备对应 Walkman 型号的 Linux Kernel 源码

首先进入 SONY 的源代码下载页面:https://oss.sony.net/Products/Linux/Audio/category01.html

类别为 Digital Media Player 数字媒体播放器的便是我们俗称的 mp3,找到自己具体的 mp3 型号,点击链接跳转到对应页面。例如 NW-A55 的页面是:https://oss.sony.net/Products/Linux/Audio/NW-A57.html

https://assets.zouht.com/img/blog/3550-01.webp

进入页面后,选择 linux-kernel 开头的内核源码,右键复制下载链接。例如 NW-A55 的 Linux 内核源码链接为:https://prodgpl.blob.core.windows.net/download/Audio/NW-A57/linux-kernel-3.10.26.tar.gz

https://assets.zouht.com/img/blog/3550-02.webp

然后在 Linux 系统中下载该文件,使用 wget 命令,命令后跟上刚才复制的链接就能下载了。例如下载 NW-A55 的内核源码:

wget https://prodgpl.blob.core.windows.net/download/Audio/NW-A57/linux-kernel-3.10.26.tar.gz

等进度条走完就行了,如果速度过慢可以考虑科学上网。注意如果这里一定要确保下载的文件完整,中途失败的话文件肯定是损坏的,需要重新下载。

Linux Kernel 编译配置

首先需要解压刚才下载的 Linux 内核源码,注意如果你下载的文件名不是 linux-kernel-3.10.26.tar.gz,需要把指令内的文件名改成你的实际文件名:

(rm -rf kernel && mkdir kernel && tar xzf linux-kernel-3.10.26.tar.gz -C kernel)

进入 kernel 目录:

cd kernel/

查看该型号播放器使用的编译配置:

cat HowToBuild.txt

例如 NW-A55 的内核会输出以下信息:

Kernel Configuration Information

The kernel is configured with following defconfig.

linux-kernel-3.10.26.tar.gz
arch/arm/configs/BBDMP5_linux_debug_defconfig

Please compile using this configuration.

然后将编译配置复制出来,需要注意的是 arch/arm/configs/BBDMP5_linux_debug_defconfig 这一条,一定要使用自己 mp3 型号对应的编译配置,就是上一步输出的信息中的那条,切忌直接复制我这个

cp arch/arm/configs/BBDMP5_linux_debug_defconfig .config

然后就可以开始配置了,按顺序执行下面三条指令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- olddefconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- scripts

过程中可能会出现一些警告,这是正常现象无需在意。但是不能出现错误,出现错误代表有问题。

编译 LLUSBDAC 模块

首先退出 kernel 目录,进入 llusbdac 目录:

cd ../llusbdac/

使用 make 进行编译:

make

过程中可能会出现一些警告,这是正常现象无需在意。但是不能出现错误,出现错误代表有问题。

https://assets.zouht.com/img/blog/3550-03.webp

解包官方更新包

下载官方更新器

首先前往索尼官网下载自己型号的更新器:https://www.sony-asia.com/electronics/support/digital-music-players-nw-nwz-a-series

例如 NW-A55 的页面是:https://www.sony-asia.com/electronics/support/digital-music-players-nw-nwz-a-series/nw-a55/downloads/00016314

提取官方更新包

首先尝试能否使用压缩软件打开更新器,如果能打开,那么就前往 Data/Device 找到 NW_WM_FW.UPG 解压出来即可。对于新版本的型号,就没办法直接解压出来了,就得用下面的方法。

然后运行更新器,会闪过一个解压进度条:

https://assets.zouht.com/img/blog/3550-04.webp

然后就会进入更新器主页面:

https://assets.zouht.com/img/blog/3550-05.webp

此时不要点继续,也不要关闭它。我们打开任务管理器,找到更新器解压的临时路径:

https://assets.zouht.com/img/blog/3550-06.webp

然后会弹出资源管理器,然后我们进入 Data 目录,再进入 Device 目录,里面名为 NW_WM_FW.UPG 便是系统更新包了:

https://assets.zouht.com/img/blog/3550-07.webp

我们把它复制出来,然后就可以把更新器先关掉了。

解包官方更新包

我们需要名为 SonyNWUPGTool 的工具进行索尼更新包的解包和重打包,程序官网在:https://www.rockbox.org/wiki/SonyNWUPGTool

我们下载 Windows 版本的工具:https://www.rockbox.org/realwiki/pub/Main/SonyNWUPGTool/upgtool-v3.exe

然后把工具和更新包放到同一个目录下,然后按 SHIFT + 右键,选择“在此处打开 Powershell 窗口”.

https://assets.zouht.com/img/blog/3550-08.webp
型号代号
NW-A30nw-a30
NW-A40nw-a40
NW-A50nw-a50
NW-WM1Anw-wm1a
NW-WM1Znw-wm1z
NW-ZX300Anw-zx300

然后在 Powershell 中输入以下指令解包,注意将 nw-a50 替换为你对应型号的代号:

.\upgtool-v3.exe -d -e -o UNPACK -m nw-a50 NW_WM_FW.UPG

运行后,可以发现 NW_WM_FW.UPG 被解包成了若干个 UNPACK*.bin 文件:

https://assets.zouht.com/img/blog/3550-09.webp

修改升级脚本

其中,第一个就是升级脚本,我们用支持二进制模式的文本编辑器例如 VSCode、Sublime 打开它。然后拉到最底下,在图片指示的位置粘贴额外的升级脚本:

https://assets.zouht.com/img/blog/3550-10.webp

添加的内容如下:

sleep 3
mount -o remount,rw /contents
(cd /contents && busybox sha256sum -c LLUSBDAC.SUM && busybox sh LLUSBDAC.DAT && rm -f LLUSBDAC.SUM LLUSBDAC.DAT)
mount -o remount,ro /contents
sync
sync
sleep 3

由于我们使安装脚本变长了,因此需要将文件尾部的 0 填充删除一部分。

按 Ctrl + A,左下角指示共 8393 字符,比原本的 8192 字符多了 201 个字符,因为我们正好粘贴进去 201 个字符。如果大家跟我差几个,那可能是差几个空格和换行。

大家只需要算出来自己多了多少个字符,然后删去对应数量的 0 填充然后保存即可:

https://assets.zouht.com/img/blog/3550-11.webp

打包修改后的更新包

在 Powershell 中使用以下指令重新打包:

.\upgtool-v3.exe -d -c -m nw-a50 MYFW.UPG UNPACK0.bin UNPACK1.bin UNPACK2.bin UNPACK3.bin UNPACK4.bin UNPACK5.bin UNPACK6.bin UNPACK7.bin UNPACK8.bin

注意后面的一串 UNPACK*.bin,需要按照你的实际情况,把刚才解包出来的所有内容按顺序跟在后面。

运行指令打包好后,可以发现目录下多了一个 MYFW.UPG,这个就是我们打包出来的新更新包。

安装更新

连接 Walkman

将 Walkman 用数据线连接到电脑,并且打开大容量储存设备,资源管理器中应当能识别到 Walkman 的储存空间。

上传脚本

我们首先把 Linux 系统里编译好的 llusbdac 复制出来到 Windows,我们只需要的内容

然后我们需要使用 Python 来运行安装脚本,如果电脑没有 Python,需要去安装一个 Python 3.8,然后进入命令行,安装 wmi 包:

pip install -i https://opentuna.cn/pypi/web/simple wmi

然后运行安装脚本。该安装脚本是给 ZX300A 设计的,但是我们只用它上传脚本而不会完整地运行它,这部分是和型号无关的,因此即使你不是 ZX300A,跟着做就行:

python .\llusbdac_installer.py

根据需求勾选选项,我这里的选项如下:

https://assets.zouht.com/img/blog/3550-12.webp

然后点击开始安装,然后到下面这个界面的时候,直接叉掉中断就行了

https://assets.zouht.com/img/blog/3550-13.webp

然后进入 Walkman 的根目录,如果出现下面两个文件,便代表着安装脚本上传成功了:

https://assets.zouht.com/img/blog/3550-14.webp

替换官方升级器的升级包

然后我们运行官方原版的升级器,用跟之前提取 UPG 一样的方法找到升级器的解压目录,我们的目标就是用我们刚才打包好的 MYFW.UPG 替换官方升级器的 NW_WM_FW.UPG.

由于权限问题我们没法直接拖进去,我们得改下权限。首先进入 Data 目录,右键 Device 目录,选择属性,然后按照下图进行操作。

https://assets.zouht.com/img/blog/3550-15.webp
https://assets.zouht.com/img/blog/3550-16.webp
https://assets.zouht.com/img/blog/3550-17.webp

完成上面这步后,剩下的直接确定关闭就行。然后我们就获取了 Device 目录的权限,我们首先把 NW_WM_FW.UPG 删掉,然后把 MYFW.UPG 拖进去,并且把它重命名为 NW_WM_FW.UPG,这样就完成了升级包的替换。

安装更新

然后回到安装器,继续安装即可。

https://assets.zouht.com/img/blog/3550-18.webp

我们等待安装器走完进度条,安装应该就能成功了,整个过程在 2~3min 左右。如果只走了几秒钟就重启了,那说明安装不正常。

https://assets.zouht.com/img/blog/3550-19.webp

测试功能

在首页点击 DAC,进入 DAC 页面后三击“上一首”、“下一首”、“暂停”任意一个实体按键,即可启用该功能,调出低延迟 DAC 的界面,然后就能插上电脑识别出来了:

https://assets.zouht.com/img/blog/3550-20.webp

同时,也可以进入设置,调整 DAC 的位深和采样率:

https://assets.zouht.com/img/blog/3550-21.webp

实测,若使用低延迟 DAC,延迟基本上不可见,声音是实时的。

如果要关闭该功能,重启播放器即可。另外该功能的其他用法参见作者的用户手册。

本文链接:https://www.zouht.com/3550.html
本文使用:CC BY-NC-SA 4.0 许可
# # # # # #
首页      教程      编译 llusbdac 解决索尼 Walkman 系列 DAC 延迟

发表回复

textsms
account_circle
email

颢天

编译 llusbdac 解决索尼 Walkman 系列 DAC 延迟
老系统的索尼 mp3 一直存在一个问题,如果启用它的 DAC 功能将其当作声卡使用时,会有高达 1~2s 的延迟。如果是听音乐延迟不影响,但如果将其用作电脑声卡看视频、打游戏的话,这个体验将…
扫描二维码继续阅读
2023-11-02