在经历三篇分析文章从乐之邦Monitor 06 Plus等几块USB声卡由浅入深至几乎在被谷歌官方git的Android公开源代码库淹死的“奇妙冒险”后,我们可以得知,除了供电、个体设备兼容性和稳定性等硬性限制外,大多数Android 6.0以上的手机、平板以及机顶盒设备在通过OTG连接USB2.0音频规范的声卡 、解码器耳放时,不仅会出现绝大多数安卓手机都存在的SRC现象,输出的采样率还会自动锁定在192kHz这一频率上。 虽然经历了长时间测验、分析并详细描述了这个现象的起因。但这里还是有必要复习一下Android系统在连接USB声卡时的大致工作机制流程和问题来源,以助于我们最终完成最后一项微小的工作:如何搞定这一问题。 Andorid系统连接USB声卡时SRC依旧存在 Android 4.X以后连接USB音频设备SRC工作流程图 采样率锁定在192的原因 Android 4.X以后连接USB音频设备SRC工作流程图 进一步的深度分析和寻找搞定方案 OPPO R11 智能手机 HTC U11智能手机 - USB Type-C至3.5mm模拟耳机输出转换线 Musiland 乐之邦 Monitor 06 Plus USB声卡 - 采样率切换 第二种方式就是相似Win系统自带的音频API[通常是DirectSound]那样,通过驱动面板指定声卡采样率了。虽然我们没有能力靠自己修改源代码搞定Android SRC问题,但如果能通过简单粗暴的方式搞定让更多人受益也是极好的。因为,在分析完成后,我们通过进一步的测验,又发现了更多关于Android+USB声卡的有趣的现象。在体验Android X86以及Android模拟器时,我们也顺便在一台普通的台式电脑上硬盘安装Android X86系统,并连接了一块乐之邦的数字时代2,惊奇地发现其默认的回放采样率居然是44.1kHz。而通过播放测验和系统日志分析,系统HAL仅能识别44100Hz,并锁定采样率,至少证明了采样率是可以改变的。 这一现象再次引起了我们的兴趣,还对Android X86以及手机平板上运行的Android系统的相关日志分析文件进行了比对,意外让我们发现:Android的默认采样率是可以和Win那样自行修改的。和上文一样,以下涉及Android源代码的分析,对此无兴趣或无了解者可直接跳过。 Android的Audio Policy“音频策略层” 在分析涉及USB声卡的源码时,或许会有一些较为专业的读者会关心Android系统在连接USB声卡时为何会设置192kHz?毕竟底层的usb.c代码片段只是分析声卡的内核驱动所汇报支持的采样率,那么是谁最终决定系统运用哪个采样率的呢?在分析源代码经历了若干香蕉和蛋糕后,我们很快找到了答案。那就是HAL中被称为Audio_policy的“音频策略层”,这个音频策略层运用C++编写,所负责的部分即使不需要仔细阅读源码,也能从源代码代码目录结构中轻易分析出它要干什么:根据某个系统预设的文本文件来设定和管理声卡的驱动设置。这个设置文件名也能在现成的手机中找出来:/etc/audio_policy.conf 通过阅读audio_policy.conf文件,我们大致可以得知这个设置文件管理着Android的内置以及外置音频设备的采样率、位率等常规设定。而在USB设备采样率生命部分,它是这么写的: Google Nexus 9上audio_policy.conf部分内容截图 Musiland 乐之邦 Monitor 06 Plus USB声卡 - 连接Android系统时HAL日志记录片段 在上一篇源代码分析中可以得知,usb.c根本是不认识Dynamic这个所谓“动态”采样率的,会被直接过滤掉。当然这是不是384000采样率“消失”的元凶就根本无从得知了,或许HAL或AudioFlinger在传递采样率参数期间还做了别的事情。至少到Android 8.0[@Nexus6P]为止,这个动态采样率切换仍旧是无法实现的。 临时搞定方案 读到这里,或许已经有人想到这个最“简单”的搞定方式了:没错,就是修改/etc/audio_policy.conf。对于网易云用户来说,只要将usb_device下的sampling_rates从dynamic修改为44100后重新启动手机,就能将USB声卡的初始采样率从192000变更为44100了……虽然影音使用无法得兼,在高清视频等普遍运用48kHz音轨时会SRC至44.1kHz播放,但至少已经做到了可控,对于强迫症用户来说,还可以设置一下声卡回放的位率[XMOS、乐之邦方案默认是32bit,可以切换至24、16bit,语法可参考设置文本其它区域]。要说明的是,如果试图通过在配置文件列举采样率的方式实现动态采样率切换[如44100|48000|96000],是无效的。至于高清音频使用,这一修改并不会对海贝音乐等本来就绕过HAL的使用程序带来造成兼容性影响。 不过,audio_policy.conf是系统文件,也就意味着用户需要pojie手机获得root权限来修改了。这一方式简单粗暴有效,发现和搞定过程似乎不如调教某K860那么有挑战性,但这也意味着设备会失去保修,而修改时由于手痒或手残很容易造成配置文件语法错误导致系统无声甚至无法正常启动的惨剧,另外这个文件并不是通用的,无法通过简单的复制粘贴来搞定。因此我们不鼓励推荐用户自己动手,而是直接反馈给设备厂商来通过系统更新修正更为广谱有效。当然,也可以等待到某天谷歌真的实现动态采样率切换了,将SRC问题彻底扔进垃圾桶里。 |