找回密码
 请使用中文注册

手机号码,快捷登录

手机号码,快捷登录

USB声卡解码器连接安卓手机时问题的出现和分析[三]

2023-5-6 09:13| 发布者: 开心| 查看: 238| 评论: 0

阅读字号:

摘要: Musiland 乐之邦 Monitor 06 Plus USB声卡 - 连接小米Note ProOPPO HA-2 便携式耳机放大器及解码器-捆一个绑  在前两篇文章中,我们通过偶然机会发现了Android智能手机 ...
    
Musiland 乐之邦 Monitor 06 Plus USB声卡 - 连接小米Note Pro
OPPO HA-2 便携式耳机放大器及解码器-捆一个绑
  在前两篇文章中,我们通过偶然机会发现了Android智能手机在搭配外接USB声卡、解码器等音频设备时存在的一些兼容性问题。除了OTG模式不稳定、供电不佳、设置无效、经常需要重新启动外,多数Android设备的音乐播放器会将外接USB声卡的播放采样率锁定在一个较高值上[通常是192kHz],而主流的44.1kHz音乐源均会SRC至192kHz播放,对音质体验带来了负面影响。
Android设备连接USB声卡时的工作流程分析

Samsung 三星 Galaxy Nexus [i9250] 智能手机 Android 4.1-频率扫描@48kHz

Google 谷歌 Nexus 6 智能手机 - 音质测评 - 频响扫描[44.1kHz]
  虽然从Android 5.0版本以来,许多Android设备即使存在SRC现象,也比更早时期的Android SRC对音质的负面影响改善不少,处于可以接受的程度。但对于对音质要求更高的运用场合来说,尤其是欣赏无损和高清音乐时,其声音相对应有的正常音质水平还是显著粗糙。那么这个问题从何而来?那么首先应该简单了解一下Android的USB音频架构的大致工作流程。

高通音频子系统于Android2.3的 SRC示意图
  在[Doc]Link=00002164[/Doc]一文中,我们已经简单介绍了Android音频架构的工作流程,虽然这个流程图是用于解释高通手机在Android系统下的音频架构,而在连接USB设备时,其工作原理是完全一致的,只不过硬件驱动由手机内置音频CODEC芯片或SoC厂商的驱动改成了通用的UAC[USB Audio Class]驱动。另外在我们翻译自海外网站的一篇文章[Doc]Link=00006276[/Doc]中,里面有一张动态gif图也直观地体现了Android音频系统的工作流程,将两者结合,我们可以得出一个新的图表。

Android 4.X以后连接USB音频设备SRC工作流程图
  和当前多数Android设备的内置音频系统SRC一样,在连接USB2.0声卡时,系统的采样率会锁定在192kHz采样率上,在运用系统内置的音乐播放器或网易云等使用时,也会统一SRC至192kHz播放。

Android系统外接USB音频设备时采样率锁定深度分析

  虽然明白了Android设备SRC的工作流程,但这并不能解释外接USB声卡时会SRC至192而不是安卓手机更常见的48kHz,一开始我个人初步判断为Android系统去倾向于设置USB声卡或UAC驱动所支持的最高采样率值。然而蛋爷表示,许多USB声卡所支持的最高采样率已经达到384kHz,为何却偏偏是锁定192呢?这里便涉及到一个有关Android系统底层的问题:Android系统是如何获得和设置USB声卡的采样率的?

  为了获得答案,我们首先要确认Android的UAC驱动能支持多高的采样率,和桌面Linux系统一样,Android的内核声卡驱动主要来源自开源的ALSA。其声卡信息会在系统的/proc/asound/目录下显示,我们在接上乐之邦或XMOS声卡后,可以从/proc/asound/card1目录中获得外接USB声卡的信息。

Android设备连接乐之邦数字时代2时显示的硬件信息
  从显示信息来看,数字时代2在Android下最高支持至384kHz,看来锁定192并非来自硬件驱动的限制。看来这个问题是源自Android系统自身了,很大概率问题是出现在Android的硬件抽象管理层HAL驱动上,那么我们所获得的信息是否就到此为止了呢?答案当然是否定的,由于Android的绝大部分代码是开源的,任何人都能在网上通过网页浏览器和git等开发工具软件随意查看。本着还残留一些码农的编程基础和Linux系统知识,在花费了两小时后,找到了锁定采样率的真正原因,由于涉及编程知识,对这方面缺乏了解的读者如果觉得内容实在太硬,可以直接跳过看本文结尾的总结。

  Android的HAL部分源代码基本公开,其USB音频管理部分源码位于/hal/audio_extn/usb.c中。从代码片段中,我们可以轻易找到涉及采样率的几个关键点:
Android HAL的USB音频源码片段

Android HAL的USB音频源码片段
  这两段代码片段包含的内容是:定义了一个数组,里面包含了USB音频设备支持的采样率集合supported_sample_rates{44100, 48000, 64000, 88200, 96000, 176400, 192000, 384000}。还定义了一个整数为MAX_SAMPLE_RATE_SIZE,也就是这个集合的最高值,根据算式可以得出结果为八[即384000,384kHz,在编程语言中数组集合从0开始,实际结果是7]。而在初始化usb_card_config中,系统设定的采样率正是最高的MAX_SAMPLE_RATE_SIZE。也就意味着,在正常的情况下,Android系统的USB外接音频设备初始化采样率应该是设备所支持的最大值而非192kHz。

  根据这三段代码线索,我们在同一个代码文件中找到了HAL获得USB设备采样率的方式函数usb_get_sample_rates。毫不意外的是,HAL正是读取/proc/asound目录中的声卡信息获得了采样率列表,然而在判断声卡最大采样率上,源代码是这么写的:

Android HAL的USB音频源码片段
  由于在这段遍历循环代码中,由于需要判断声卡实际支持的采样率和supported_sample_rates中的数字对应,也就是合集,由于剔除了许多USB声卡不支持的64000采样率,以及supported_sample_rates中没有的352800,HAL自己所知的设备采样率将永远是合集{44100, 48000, 88200, 96000, 176400, 192000, 384000},也就是七个数,而supported_sample_rates第七个数是192000[计算机语言中是supported_sample_rates[6]]。这也正是初始化USB声卡usb_card_config时所获得的最大值,如果是SA9027或PCM270X等采样率低于192kHz的USB音频方案,则采用声卡硬件驱动所支持的采样率最大值,例如48kHz、96kHz等,这也就是Android系统设备在连接乐之邦、XMOS等USB2.0高性能异步音频方案时锁定192kHz的“罪魁祸首”。

总结

Android 4.X以后连接USB音频设备SRC工作流程图
  造成如此奇妙的SRC问题,原因却如此的简单:只是单纯的由于Android HAL抽象层源代码开发者的一个简单错误,就造成了USB音频设备在Android系统下采样率锁定在192kHz的问题。为何至今却没有被谷歌旗下任何高级攻城狮和码农们发现和搞定?最直接的原因自然是Android源代码的拥有者谷歌对于这部分使用从来没有真正上心过,安卓手机是现在普及度最高的个人终端设备,音频爱好者自然会对音质有更高的要求,那谷歌在Android 6.0开始就着力在PDF上宣传的所谓专业Android音频系统,到底是对谁说的?
  尽管外接USB音频设备时,Android用户的确还有海贝音乐使用这一选择,也有相似OPPO R11等系统自带USB音频采样率自动识别切换的手机个例,但海贝毕竟无法支持云音乐使用,而OPPO则是由于自身也是高端音频设备的厂商,自然需要让HA-2等便携式或台式解码器在OPPO手机下正常工作。对于广大安卓手机用户群体以及忠实的云音乐用户来说,是否就只能等待谷歌或者手机厂商自己去良心发现或利益需要后才能搞定呢?

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|手机版|家电维修论坛 ( 蜀ICP备19011473号-4 川公网安备51102502000164号 )

GMT+8, 2025-5-26 02:23 , Processed in 0.430689 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

返回顶部