[Linux Audio Driver] 声卡与XML匹配流程

QCOM音频Usecase详解
本文详细解析了QCOM内部定义的音频Usecase数据结构,包括其在HAL层的作用、具体应用场景如低延时播放、压缩卸载等,以及如何通过声卡名和XML配置确定输出方案。

0. usecase

usecase是qcom内部定义的一个数据结构,位于hal层,用作处理处理内部声卡逻辑和输出方案。

代码路径: LA.UM.5.6\hardware\qcom\audio\hal\audio_hw.h

/* These are the supported use cases by the hardware.
 * Each usecase is mapped to a specific PCM device.
 * Refer to pcm_device_table[].
 */
enum {
    USECASE_INVALID = -1,
    /* Playback usecases */
    USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
    USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
    USECASE_AUDIO_PLAYBACK_MULTI_CH,
    USECASE_AUDIO_PLAYBACK_OFFLOAD,
    USECASE_AUDIO_PLAYBACK_OFFLOAD2,
    USECASE_AUDIO_PLAYBACK_OFFLOAD3,
    USECASE_AUDIO_PLAYBACK_OFFLOAD4,
    USECASE_AUDIO_PLAYBACK_OFFLOAD5,
    USECASE_AUDIO_PLAYBACK_OFFLOAD6,
    USECASE_AUDIO_PLAYBACK_OFFLOAD7,
    USECASE_AUDIO_PLAYBACK_OFFLOAD8,
    USECASE_AUDIO_PLAYBACK_OFFLOAD9,
    USECASE_AUDIO_PLAYBACK_ULL,

    /* FM usecase */
    USECASE_AUDIO_PLAYBACK_FM,

    /* HFP Use case*/
    USECASE_AUDIO_HFP_SCO,
    USECASE_AUDIO_HFP_SCO_WB,

    /* Capture usecases */
    USECASE_AUDIO_RECORD,
    USECASE_AUDIO_RECORD_COMPRESS,
    USECASE_AUDIO_RECORD_LOW_LATENCY,
    USECASE_AUDIO_RECORD_FM_VIRTUAL,

    /* Voice usecase */
    USECASE_VOICE_CALL,

    /* Voice extension usecases */
    USECASE_VOICE2_CALL,
    USECASE_VOLTE_CALL,
    USECASE_QCHAT_CALL,
    USECASE_VOWLAN_CALL,
    USECASE_VOICEMMODE1_CALL,
    USECASE_VOICEMMODE2_CALL,
    USECASE_COMPRESS_VOIP_CALL,

    USECASE_INCALL_REC_UPLINK,
    USECASE_INCALL_REC_DOWNLINK,
    USECASE_INCALL_REC_UPLINK_AND_DOWNLINK,
    USECASE_INCALL_REC_UPLINK_COMPRESS,
    USECASE_INCALL_REC_DOWNLINK_COMPRESS,
    USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS,

    USECASE_INCALL_MUSIC_UPLINK,
    USECASE_INCALL_MUSIC_UPLINK2,

    USECASE_AUDIO_SPKR_CALIB_RX,
    USECASE_AUDIO_SPKR_CALIB_TX,

    USECASE_AUDIO_PLAYBACK_AFE_PROXY,
    USECASE_AUDIO_RECORD_AFE_PROXY,

    AUDIO_USECASE_MAX
};

usecase 通俗表示音频场景,对应着音频前端,比如:

low_latency:按键音、触摸音、游戏背景音等低延时的放音场景

deep_buffer:音乐、视频等对时延要求不高的放音场景

compress_offload:mp3、flac、aac等格式的音源播放场景,这种音源不需要软件解码,直接把数据送到硬件解码器(ADSP),由硬件解码器(ADSP)进行解码

record:普通录音场景

record_low_latency:低延时的录音场景

voice_call:语音通话场景

voip_call:网络通话场景

但是具体的输出方案与声卡中的mixer_path_xxx.xml相关。

1. platform.c

下面说下如何找到这个XML (以MSM8953、Android10为例子)

首先进入shell,然后用命令cat /proc/asound/cards找到声卡名msm8953-snd-card-mtp。

在这里插入图片描述

然后进入hardware下面找到platform.c的android.mk文件,看具体使用哪个,(此处备注,platform.c的位置不一定在hardware下面,一方面可以借鉴高通音频bring up的文档来看,
另一方面也可以直接grep “speaker”,也可以找到platform.c的位置)

代码路径:LA.UM.8.6.2\hardware\qcom\audio\hal

在这里插入图片描述

我们进入这个Android.mk文件看看。

在这里插入图片描述
然后我们需要知道TARGET_BOARD_PLATFORM这个定义的是啥,一般来说在device目录下面查找。

~/android10/LA.UM.8.6.2$ grep -nr "TARGET_BOARD_PLATFORM" ./device/

在这里插入图片描述

由于我们预先知道了lunch项是msm8953_64,所以此处我们知道了
ARGET_BOARD_PLATFORM的值就是msm8953,

那我们回过头来看这个android.mk文件,发现上面那段ifneq的代码根本不走,我们看下面的。

在这里插入图片描述

filter可以过滤掉TARGET_BOARD_PLATFORM之外的东西,然后ifneq
再判断是不是msm8953,这里意思就是Filter把前面一堆东西除了msm8953都过滤了,然后这里再判断msm8953和TARGET_BOARD_PLATFORM是不是等价的,然后就走后面的代码。

这里我们知道了AUDIO_PLATFORM 就是msm8916,于是我们就知道platform.c的准确位置:

LA.UM.8.6.2\hardware\qcom\audio\hal\msm8916\platform.c

我们进入platform.c,搜索刚才的声卡名:msm8953-snd-card-mtp,找到了如下的
代码。

在这里插入图片描述

2. MIXER_XML_PATH_MTP

MIXER_XML_PATH_MTP就是我们想要知道的XML名字,这玩意是个宏。

在这里插入图片描述

LINUX_ENABLED这个宏并没有开,所以MIXER_XML_PATH_MTP就是
/vendor/etc/mixer_paths_mtp.xml

在这里插入图片描述
再次回到这个代码,strncmp函数将声卡名与msm8953-snd-card-mtp进行对照,发现相等,函数返回0;然后把 “/vendor/etc/mixer_paths_mtp.xml”字符串赋值给mxier_xml_path
这个是char型的数组。

在这里插入图片描述

static void query_platform(const char *snd_card_name, char *mixer_xml_path)

在这里插入图片描述

然后我们看一下这个函数调用的地方,可以看到这个函数的目的就是根据声卡名,找到对应匹配的XML。

3 参考链接

  1. https://blog.youkuaiyun.com/azloong/article/details/79383323

4. 作者注

/******
@article{Linux Audio Driver,
Author = { 1byte ≠ 8bit},
Year = { 2020},
}
******/
<think>好的,我现在需要帮助用户分析audio_hw相关的音频硬件驱动或配置问题。用户之前的问题涉及Android音频框架中的route_output_stream函数,现在转向更底层的audio_hw部分,可能遇到了驱动或配置的问题。让我先回顾一下用户提供的引用内容,看看哪些信息可以利用。 首先,引用[2]提到了Android音频驱动的加载过程,分为三个步骤:hw_get_module_by_class加载HAL模块,audio_hw_device_open打开设备,open_output_stream打开输出流。这应该是分析audio_hw的基础流程。引用[4]指出audio_hw的实现通常位于特定路径,比如vendor/qcom下的primary-hal,这可能帮助定位源码或模块位置。 用户想了解的是audio_hw的驱动分析或配置问题解决方案。我需要结合这些引用和之前的问题来构建回答。可能需要包括HAL层的作用、常见问题如无声或设备加载失败,以及调试方法如日志分析和配置检查。 用户之前的问题中提到了HDMI断开时的路由切换,这可能HAL层的设备管理有关。比如在HAL中如何检测设备状态变化,或者配置文件中是否正确定义了设备优先级。引用[1]提到无声问题的分析框架,可以引用作为常见问题排查步骤。 另外,引用[3]中的sdl_audio_callback涉及音频数据拷贝和时钟同步,虽然HAL层直接关系不大,但可能在应用层HAL交互时出现问题,比如缓冲区配置不正确导致音频中断或延迟,这也可能涉及HAL配置。 我需要组织回答的结构,先介绍audio_hw的作用,然后分析驱动问题,再讨论配置问题,最后给出解决方案和调试方法。确保每个部分都有引用支持,比如引用[2]的加载流程,引用[4]的模块路径,引用[1]的无声问题分析。 还要注意用户提到的“配置问题解决方案”,可能需要检查audio_policy.conf或设备树中的配置是否正确,比如设备节点权限、HAL模块的兼容性设置等。此外,日志分析是关键,如dmesg和logcat中的错误信息,帮助定位HAL加载失败或设备初始化问题。 可能还需要提到具体案例,比如设备无法打开时的错误处理,或采样率不匹配导致的音频异常,这些都需要结合HAL层的实现来排查。最后,生成的相关问题应围绕驱动调试、配置优化和案例分析展开,帮助用户进一步探索。</think>#### 一、audio_hw 音频硬件驱动分析 ##### 1. **HAL层核心机制** - **模块加载流程**: ```cpp hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, "primary", &mod); // 加载厂商实现的HAL模块[^2] audio_hw_device_open(mod, &dev); // 打开音频设备 dev->open_output_stream(dev, ..., &out_stream); // 创建输出流 ``` 若加载失败,需检查`/vendor/lib/hw/`目录下是否存在对应`.so`文件(如`audio.primary.[platform].so`)[^4]。 - **关键结构体**: ```cpp struct audio_hw_device { struct hw_device_t common; // 操作函数指针(如open_output_stream、set_parameters等) }; ``` 厂商需实现这些接口以适配硬件,若函数指针未正确初始化会导致音频服务崩溃[^2]。 ##### 2. **典型驱动问题分析** - **设备初始化失败**: - **日志特征**: ```log E AudioHAL: audio_hw_device_open: Failed to open PCM device (errno 13) E AudioFlinger: loadHwModule: error -2 opening hardware interface ``` 常见原因: 1. 内核层未正确注册声卡(`cat /proc/asound/cards`验证) 2. `/dev/snd/`下设备节点权限不足(需`system:audio`权限) - **音频数据传输异常**: - **症状**:音频播放卡顿/杂音 - **调试方法**: ```shell tinymix -D 0 # 查看混音器寄存器配置 tinyplay /sdcard/test.wav # 验证原始音频输出 ``` 若`tinyplay`正常但应用层异常,可能为HAL层缓冲区管理或时钟同步问题[^3]。 #### 二、audio_hw 配置问题解决方案 ##### 1. **设备策略文件配置** - **audio_policy.conf解析**: ```conf global_configuration { attached_output_devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADPHONE default_output_device AUDIO_DEVICE_OUT_SPEAKER } ``` 若HDMI优先级高于扬声器,设备断开时可能触发路由错误[^1]。 ##### 2. **常见配置错误修复** | 问题现象 | 配置检查点 | 修复方法 | |---------|------------|---------| | 蓝牙耳机无声 | `bluetooth.a2dp.sink`服务状态 | 检查`bluetooth.profile.a2dp.sink.enabled`属性 | | USB音频设备未识别 | `alsa.mixer`路径定义 | 更新`audio.usb.default`模块的`usb_audio_policy_configuration.xml` | | 多声道输出异常 | `channel_masks`声明 | 在HAL层`audio_policy_configuration.xml`中添加`AUDIO_CHANNEL_OUT_5POINT1`支持 | ##### 3. **HAL层调试技巧** - **动态日志过滤**: ```shell adb shell "logcat -s AudioHAL" # 仅显示HAL层日志 adb shell dmesg | grep -i "asoc" # 查看内核音频子系统状态 ``` - **HAL接口测试**: ```cpp audio_hw_device_t* dev; dev->get_microphones(dev, &mic_list); // 验证麦克风枚举功能 dev->dump(dev, STDOUT_FILENO); // 输出设备状态信息 ``` #### 三、案例:USB音频设备加载失败分析 1. **现象**:插入USB声卡后无音频输出 2. **调试步骤**: - 检查内核驱动:`lsmod | grep snd_usb_audio` - 验证HAL配置:`audio_policy_configuration.xml`中是否包含`AUDIO_DEVICE_IN_USB_DEVICE` - 查看权限:`ls -l /dev/bus/usb/001/002`应包含`0666`权限 3. **根本原因**:厂商HAL未实现`usb_audio_device`的`get_parameters`回调 --- #### 四、扩展工具文档 - **Audio HAL验证工具**: ```shell /vendor/bin/hw/android.hardware.audio@X.0-service.XXX_test # 厂商测试工具 atest AudioHalTest # AOSP测试框架 ``` - **关键文档**: - [Android Audio HAL Interface Definition](https://source.android.com/docs/core/audio/hal-interfaces) - [ALSA Driver Debugging Guide](https://www.alsa-project.org/wiki/Debugging) ---
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值