【车载audio开发】【Qualcomm PAL 详解 4】【Session 模块 介绍】

Session 模块 - 从小白到专家

1. 什么是 Session?

如果说 Stream 是"订单",Device 是"餐桌",那么 Session (会话) 就是 厨房和传菜员。

  • 功能 : 它负责建立一条从 CPU (Android) 到 DSP (音频处理器) 再到 硬件接口 (Speaker) 的数据通路 (Graph)。
  • 本质 : Session 管理着底层的 PCM 设备节点 (如 /dev/snd/pcmC0D0p) 和 DSP 上的音频处理图 (Graph)。

2. 核心类结构

Session 屏蔽了底层与内核/DSP 通信的差异。

  • Session (基类): 定义通用接口。
  • SessionAlsaPcm (最常用) :
    • 基于 TinyALSA。
    • 通过打开 PCM 设备节点 (pcm_open) 来传输数据。
    • 通过 Mixer Controls (mixer_ctl_set_value) 来配置 DSP 模块(Tag/Module/Calibration)。
  • SessionAgm :
    • 基于 AGM (Audio Graph Manager) 服务。
    • 新一代架构,通过 IPC 调用 AGM 服务来加载图,不再直接操作 PCM 节点。
  • SessionGsl :
    • 基于 GSL (Graph Services Layer)。
    • 更底层的实现,直接与 GSL 库交互。

代码位置 : session/src/Session.cpp, session/src/SessionAlsaPcm.cpp。


3. 核心概念:FrontEnd (FE) 与 BackEnd (BE)

Session 起到了连接 FE 和 BE 的作用。

  • FrontEnd (前端) : CPU 侧的接口。即 Android 看见的 PCM 设备 (如 pcm0p)。Session 负责分配和打开这个 FE。
  • BackEnd (后端) : 硬件侧的接口。如 Speaker 的 I2S 接口 (如 SLIMBUS_0_RX)。Device 负责管理 BE。

Session 的工作就是把 FE 和 BE 在 DSP 内部连起来。


4. 关键接口与调用流程

4.1 打开会话 (open)

  • 输入 : Stream 指针。
  • 流程 :
    1. 分配 FE : 调用 ResourceManager::allocateFrontEndIds。比如分配了 pcm0p。
    2. 获取 BE : 询问 Stream "你要去哪个设备?",得到 BE 名字 (如 QUAT_TDM_RX_0)。
    3. 建立连接: 告诉底层 "把 PCM0 和 TDM_RX_0 连起来"。
    4. 注册回调: 注册 Mixer Event 回调,用于接收 DSP 事件(如 VAD 唤醒,Buffer 播放完毕)。

4.2 配置参数 (setConfig)

这是 Session 最强大的功能。它用于向 DSP 发送各种参数。

  • Type :
    • MODULE: 设置特定模块参数(如由 GKV 决定的 Tag)。
    • CALIBRATION: 发送校准数据(如 ACDB 数据)。
  • 实现 (SessionAlsaPcm) :
    • 它会将参数打包成 TKV (Tag-Key-Value) 结构。
    • 通过 mixer_ctl_set_array 发送给内核驱动,驱动再转给 DSP。

4.3 准备与启动 (prepare / start)

  • prepare :
    • 通常用于申请 buffer,或者预加载 Graph。
  • start :
    • 对于 SessionAlsaPcm,这里会调用 pcm_start (如果之前已经 write 了数据) 或者确保 PCM 节点处于 Ready 状态。

4.4 读写数据 (read / write)

  • 流程 :
    • 直接调用 pcm_write (TinyALSA) 将音频数据写入内核缓冲区。
    • 如果是 mmap 模式,则直接拷贝到共享内存。

5. 进阶:Graph 与 Tag

Session 的灵魂在于对 Graph 的控制。

  • Graph : DSP 内部的处理流程图。例如:Resampler -> Volume -> Effects -> Mix。
  • GKV (Graph Key Vector) : 一组 Key-Value 对,唯一确定一个 Graph。
    • Session 根据 Stream 的属性(采样率、位宽、用例类型)构建 GKV。
  • Tag Config :
    • 为了配置 Graph 中的某个模块(比如 Volume),我们需要知道它的 Tag ID。
    • Session 通过 XML 解析或硬编码知道:STREAM_VOLUME 对应 Tag ID 0x1234。

6. 总结表格

接口函数 功能 对应厨房的角色 核心操作
open 建立连接 确定哪个厨师(FE)做菜,送到哪个窗口(BE) allocateFrontEndIds, pcm_open
setConfig 配置DSP 告诉厨师:少放辣,多放盐 mixer_ctl_set_array
start 开始处理 开火炒菜 pcm_start
write 传输数据 把切好的菜(PCM)给厨师 pcm_write
getTimestamp 获取时间戳 问厨师菜做到哪一步了 pcm_get_htimestamp

7. 开发者建议

  • 排查无声 :
    1. 检查 open 时 FE 和 BE 是否正确匹配。
    2. 检查 setConfig 是否成功下发,DSP 如果参数错误可能会拒绝运行 Graph。
    3. 查看 pcm_write 是否报错(如 -EPIPE underrun)。
  • 杂音问题: 通常是 Session 配置的采样率/位宽与 Device (BE) 不一致,导致 DSP 内部重采样错误或时钟不同步。
相关推荐
AFinalStone11 天前
Android7 多用户源码解析(五)应用安装与管理隔离机制
系统架构·aosp·多用户
AFinalStone11 天前
Android7 多用户源码解析(二)核心数据结构深度剖析
系统架构·aosp·多用户
AFinalStone12 天前
Android7 多用户源码解析(六)数据隔离与存储机制详解
系统架构·aosp·多用户
AFinalStone12 天前
Android7 多用户源码解析(一)功能演进与系统架构总览
系统架构·aosp·多用户·usermanaher
AFinalStone12 天前
Android7 多用户源码解析(十)Work Profile 企业模式与开发实战指南
系统架构·aosp·多用户
AFinalStone12 天前
Android7 多用户源码解析(九)权限系统与多用户的交互机制
系统架构·aosp·多用户
消失的旧时光-19431 个月前
Android 系统层扫盲 09:AMS、ATMS、WMS、PMS 到底分别管什么?
android·wms·pms·ams·aosp·atms
千里马-horse1 个月前
附录 C:AOSP 不在公共框架 API 中采用 Kotlin 的原因
aosp
千里马-horse1 个月前
65 定制 Android ROM
aosp
千里马-horse1 个月前
第 66 章:在 Android 上运行 Windows 游戏
android·aosp