|
楼主 |
发表于 2024-10-1 00:38
|
显示全部楼层
来自 上海市浦东新区
本帖最后由 wxwxwx0 于 2024-10-2 13:43 编辑
三、软件播放
bit-perfect
尽管jitter是不可避免的,但bit-perfect播放是相对容易的,从追求hifi的角度说:应该尽可能达到或者至少接近。
bit-perfect是指音频数据被送往音频设备(甚至送往DAC芯片)之前不被任何形式的DSP修改,包括音量控制、重混音、SRC(采样率转换)/升频处理、dither...
尽管DAC内部也通常会有超采样,但并不等于前面取得bit-perfect是无意义的。
如何确保(或接近)bit-perfect?
1)使用没有ASRC的DAC
2)驱动程序不修改数据
3)操作系统音频层不修改数据
-- 对window来说就是选择WASAPI/ASIO,并且配置成exclusive mode(独占模式)
-- 注意共享模式下哪怕只有一条音频流、采样率设置一致,最终声音也会加入dither,光这个就会影响音质
4)播放软件本身不修改数据(不使用任何音效处理、不做采样率转换等)
软件播放过程与音频架构(windows)
这是张有点老的图了,windows的音频架构自win vista开始就(大刀阔斧地)改成这样了,原本需要kernel mode完成的很多处理都搬到了应用层,并且有了WASAPI和exclusive mode、Audio Engine这些新的概念。
(windows应用层就能做很多比较核心的事情,而不用在应用进程/内核进程之间来回切换,这也是为什么我觉得windows比linux更有利于hifi)
首先 无论哪种播放软件,基本不会是播放软件自己控制播放,它只会根据设备or驱动(显性or隐性的)反馈来更新进度条。播放软件只负责解码文件到PCM,(经过内置音效处理)输出到一个应用级的buffer里(这个buffer可以很大)。
在shared mode(共享模式)下,音频会经过audio engine,不仅路径很长而且数据会不知不觉经历各种修改。而在exclusive mode下,应用通过wasapi与驱动直接交互。
而驱动程序(对usb来说)负责确定下一次发送多少数据、从endpoint buffer中读数据,然后在指定的时间节点打包发出去。
实时性问题
于是就有个问题:音频数据是如何从应用级buffer到了endpoint buffer呢?
WASAPI提供了两种方式:push模式和event模式。push模式下应用以固定的时间间隔轮询,询问下面要补多少数据,这个时间间隔会受到系统定时精度(10ms)的影响;而event模式下底层会通知应用,相当于下面直接从应用buffer中搬数据了。
应用本身大部分时间都处于睡眠状态,需要工作的时间点才被唤醒。push模式下它是被10ms精度的定时器唤醒,而event模式下是被下面的通知唤醒。
因此event模式是更实时、让音频的路径更直接的方式,event模式下endpoint buffer通常也很小只有几十ms(它保证了回放的总体低延迟)。
应用中用来访问endpoint buffer的线程通常需要很高的优先级(来保证实时性),windows系统提供了一套MMCSS(Multimedia Class Scheduler Service)方法让这些线程运行在高优先级。
要想取得最好的实时性,应该用尽可能好的音频设备/驱动,除此外还要保证系统运行时的低负载(比如音频无关的进程优先级尽可能低)。否则每次写入buffer的数据就会不及时、偏多/偏少。
而反过来说,对于播放软件来说,越是想有广泛的适用性、对音频设备的兼容性,它越是不能设计得对实时性要求太高。
四、异步能解决问题吗?
总的结论是:异步协议并不保证音质,优势并不在于异步设计而在于具体实现(Asynchronous mode is not better by design but by implementation.)
从现实角度,它确实能以相对更简单的方法达到相对更好的效果(简单说就是性价比高),因而受到开发者的普遍青睐。
而从理想出发,达到理想的效果取决于DAC如何构建出独立的时钟域。
减少传输jitter的手段再讨论
ASRC通过对输入数据重新采样+升频,完全抛弃了包含在原数据中的时钟信息,从而让本地时钟可以自由运行,实现时钟的隔离。
然而重采样+升频这种处理过程本身会引入数据失真:比如当原有码率低于新的采样率就要补0,原有码率高于新采样率就要合并...
因此人们经常觉得ASRC有声音不自然、高频发硬的问题。所以就算解码芯片内部有ASRC,好的方案也会选择绕开它。
有人会想到一个足够大FIFO就可以完全隔离时钟,但从两方面说:
一是会产生比较大的延迟,从设备的专业性、普遍通用性、用户体验的角度说,几乎不会有人愿意这么干;
二是方案的灵活性,完全隔离了前端时钟域就没法再接收同步信号,DAC只能做主控了,你前面再有牛x的转盘也没用了。
所以最后还是回到了PLL(锁相环)。于是USB界面通常也需要跟踪数据的速率,来合成一个新的时钟,而这个合成的具体做法决定了最终的效果。
因为PLL本身同步的过程就会产生jitter,所以当源信号本身质量非常好,再经过了性能一般的PLL电路之后就有可能会变差。(这也是为什么一些界面的“洗水”实际用起来觉得很鸡肋)
一些高级的机器会采用两个PLL级联,来获得更低jitter。这种方案先不说效果是否绝对出色,首先它基本不会用在中低端的DAC上。
而更为常规普遍的做法是PLL结合了FIFO:数据首先进入一个(不太大的)FIFO,然后接收芯片来合成时钟,而FIFO的指针也参与了合成时钟的过程,与此同时界面通过反馈通路告诉前端:下一次应该发多少数据。这样做的目的就是保证FIFO既不会溢出也不欠载,也就是说这仍然是一套速率匹配/流量控制机制。
转盘为什么还是会影响声音?
为什么两台数播jitter测量结果差不多,声音还是很不同?或者为什么pchifi的情况下:随便换个播放器/操作系统,动一动哪里的设置,声音也会有很大区别?
一种解释是:还是硬件与串扰问题,电源干扰或电磁/射频干扰(以无关于jitter的形式)传导给DAC从而影响了声音。甚至软件的实时性影响也有人解读为干扰,因为理论上数据发送速率的变化也会引起携带的无关噪声分布变化。
而实际上就算DAC已经隔离了前端干扰,你还是听得出这些变化。更为诡异的是:对于同一台DAC无论用usb(异步的;但没有很好的隔离)还是用光纤/蓝牙(同步的;但有天然的隔离),你会发现各种前端音源(以及不同播放软件+各种设定变化)对各种连接方式下声音的影响取向上是一样的!
这已经说明了:串扰不能解释一切,软件本身也会有影响,而且这种影响是相关于数据本身的。(消除隔离干扰当然也是重要的,这方面的内容可以看参考④、⑤)
而软件会产生什么样的影响,拿windows系统来说,分不同的情况看:
1)系统数字部分达到了bit-perfect这个前提下,你还是会发现不同的操作系统、不同的播放器(都以独占模式输出)、不同的播放器进程优先级、不同的设定(push/event模式、buffer大小):它们还是会影响声音...
2)没有达到bit-perfect情况下:比如说没有用独占模式音频流额外走了audio engine,那么调节audio engine的进程优先级也会影响声音;或者当外置声卡本身有混音器(尽管它实际没干啥),你去调节这个混音器的进程优先级它也会影响声音。并且这一类的声音影响还挺大的...
3) 除此外当软件的任一环节上有SRC或比较重的DSP处理,除了它们本身会影响声音,而且这种情况下你再去做别的优化调节,会发现那个调节带来的区别似乎更加放大了。
而所有软件上的这些影响,都并非是你预想的:产生了爆音中断什么的,而只是让音质非常稳定地更好、或非常稳定地更差...
这一切都是为什么呢?前面的内容其实已经给出解释:异步也无法做到根本隔离时钟域,而常规的方案往往又是技术上的折衷选择。
比如当FIFO成为PLL的一环,它就有速率匹配的问题,只要存在速率匹配就无法避免受实时性的影响。它当然比单纯的PLL更好(一定程度上减少了耦合)而且更灵活,比如当buffer大一点速率调节就会慢一点,可能听起来影响就小一点。
同时人们也推测这种实时性问题带来的影响,并不反映在jitter的量,而是改变了jitter的分布特征,这就是为什么设备jitter测量值通常也不能说明问题。
对于那些没有用PLL而是ASRC的方案,因为ASRC本身会修改数据,速率的不稳定会让这个修改数据的行为也更不稳定。
五、理想与现实
接近理想的思路
论坛里phoexi就说过接近理想的方案:
1)用IIS(HDMI IIS)传输,并选择有直通模式的解码比如rockna 26
2)选择自带高性能PLL的解码(精确锁相不需要缓冲 变成了同步锁相模式)比如DA2 8XR
两种方案具体谁更好也不一定,重点在于它代表了两种截然不同的方向:你是要提升解码,还是要提升前端。
通俗说要接近理想 那就是买买买:买超超旗舰的数播、超超旗舰的解码... 但也要买得聪明,因为瞅准了一个方向努力会更有效果。
另外本文的讨论也都是基于没有独立时钟的系统,如果有高性能的外部时钟,就可能会有更多(理想的)方向。
现实的思路
1)力所能及的情况下选择好的设备、硬件
-- 可以尝试下专业级的设备,因为我发现(也可能是偏见)民用hifi级的器材经常会糊弄人,而专业级的往往不会
2)尽可能做好隔离,减少供电干扰和电磁干扰,这会起到很重要的保底作用
3)对于pchifi玩家:系统、软件的优化仍然是重要的。
-- 软件可能不如硬件重要,但是可以决定上限
4)USB(经常)未必是最好的传输方式;应该各种方式都多换着听听
5)独立界面,从前面的讨论就可以知道:独立界面要想真正发挥价值,它既应该比你的转盘更强,也要比解码自带界面更强...
-- 因此独立界面的现实意义在于 当你的系统已经基本定型了,再看看能不能补补
6)用网络的方案:我个人倒没什么经验和意见,但有人说过这样的话:usb都不能解决的问题,就别指望网络(这么复杂的东西)能解决了
参考
Jitter in Digital Audio Data Streams
https://www.positive-feedback.com/Issue43/jitter.htm
拒绝YY 从基础讲解USB/UAC运作原理
http://erji.net/forum.php?mod=viewthread&tid=1987631
Exclusive-Mode Streams
https://learn.microsoft.com/en-us/windows/win32/coreaudio/exclusive-mode-streams
网络和数播(专业数播/PC HIFI/树莓派)对声音的影响
http://erji.net/forum.php?mod=viewthread&tid=2344118
尝试从原理上说明为什么前端(PC或其他设备)会对异步USB产生影响
http://erji.net/forum.php?mod=viewthread&tid=2142522
|
|