这篇写什么?
做 ACR(Automatic Content Recognition,自动内容识别) 或其它需要「听本机在播什么」的功能时,通常要一路 Ref(回采)。板上若 LoopbackA 已经被 DSPC 等模块占着,就不能再抢同一路,需要 再开 LoopbackB。
本案例做法:
LoopbackB 挂到 TDM-A(tdmoutA),回采正在往 TDM-A 写的播放数据;格式约定为 48 kHz / 2ch / 16-bit。
一句话:
需求:ACR 要 Ref,但 LoopbackA 已被占用
做法:DTS 启用 loopbackb,datalb_src = tdmoutA,dai-link 暴露 alsaPORT-loopbackb
验证:tinyplay → TDM-A;tinycap → LoopbackB(如 -d 10)@ 48k 2ch

和唤醒侧「Mic+Ref / 抗混叠」的关系见:Mic + Ref 采集、Loopback 抗混叠。本文偏 第二路 Ref 怎么从 TDM 拉出来。
一、背景与目标
| 项目 | 说明 |
|---|---|
| 已有 | LoopbackA:DSPC 在用(capture) |
| 新增 | LoopbackB:给 ACR 等业务取 Ref |
| Ref 来源 | TDM-A 播放通路(硬件上写的是 48k / 2ch / 16bit 一类数据) |
| 验证手段 | tinyplay 往 TDM-A 灌 WAV;tinycap 从 LoopbackB 抓回来听 |
先确认内核里 PCM 节点是否注册成功,例如:
cat /proc/asound/pcm
lsof | grep pcm
实机上常见能看到类似:
00-08 LOOPBACK-A ... alsaPORT-loopback(已被占用)00-10 LOOPBACK-B ... alsaPORT-loopbackb(新增 capture)00-01 TDM-B ...等播放节点(具体 card/device 号以板子为准)

device 号不是写死的——以 /proc/asound/pcm 为准;下文用「card0、device10」仅作示例。
二、DTS 改什么(概念)
机型 DTS(路径因项目而异,例如 .../t7c_..._TY55_1.dts)里通常要动三块。
1)TDM-A 播放链路仍要正确
dai-link 上 TDM-A 作为 I2S master,suffix-name 与 Audio HAL 约定一致(如 alsaPORT-pcm),slot / mclk 与 48 kHz 时钟匹配。业务往这条链路写播放时,LoopbackB 才能「听」到同一路数字声。
2)启用 loopbackb 节点
关键字段(示意):
| 字段 | 本案例取值 | 含义 |
|---|---|---|
datalb_src |
<0> |
回采源 = tdmoutA |
datalb_chnum |
<2> |
2 通道 |
datalb_chmask |
<0x3> |
取前两路 |
datain_src / chnum |
常置空或 0 | 本需求只要 Ref,不绑 PDM mic |
status |
"okay" |
打开 |
datalb_src 取值表(平台注释常见约定):
0tdmoutA,1tdmoutB,2tdmoutC≥3往往表示外部 pad loopback
本需求是 从 TDM-A 出声口环回,所以选 tdmoutA = 0。
3)增加 sound card 的 dai-link,暴露给用户态
例如:
aml-audio-card,dai-link@10 {
mclk-fs = <256>;
continuous-clock;
suffix-name = "alsaPORT-loopbackb";
cpu {
sound-dai = <&loopbackb>;
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&dummy_codec>;
};
};
suffix-name 必须和 Android Audio HAL / 调试脚本认的名字对齐,否则上层找不到设备。
三、编译与烧录(流程级)
- 改完 DTS 后编内核 / boot 相关镜像(项目脚本因仓库而异)
- 产出例如
boot.img、vendor_boot.img adb reboot bootloader后用 fastboot 分别 flash boot / vendor_boot- 开机再查
/proc/asound/pcm,确认 LOOPBACK-B 与alsaPORT-loopbackb出现
具体
./mk_...、-j参数、产物路径以你们树为准;重点是 DTS 进镜像 + 设备节点可见。
四、驱动验证:tinyplay + tinycap
目标:证明「往 TDM-A 写的内容,能从 LoopbackB 原样(或近似)抓回来」。
1)往 TDM-A 播放
准备 48 kHz / 16-bit / 2ch WAV,例如:
tinyplay /data/test_lk/gen_48k_16bit_2ch_cloud.wav -D 0 -d 0
# 若节点要求 32-bit 容器,可试:
# tinyplay ... -D 0 -d 0 -b 32
-d 0 需对应 TDM-A 播放 device(以 pcm 列表为准,不一定是 0)。
2)从 LoopbackB 抓取
另开 shell:
tinycap /data/loopbackb.wav -D 0 -d 10 -c 2 -r 48000
# 或
# tinycap /data/loopbackb.wav -D 0 -d 10 -c 2 -r 48000 -b 32
| 参数 | 示例 | 说明 |
|---|---|---|
-D |
0 |
声卡号 |
-d |
10 |
LoopbackB 的 PCM device(示例) |
-c |
2 |
2 通道 |
-r |
48000 |
与 TDM-A 写端一致 |
-b |
16 / 32 |
与驱动位宽约定一致 |
3)拉回电脑听
adb pull /data/loopbackb.wav .
用 Audacity 按原始参数导入(48k / 2ch / 对应 bit depth)。若听感与 tinyplay 源文件一致(或仅有固定延迟),说明 TDM-A → LoopbackB 回采通路打通。
五、和 LoopbackA / 抗混叠路径的边界
| 路径 | 典型用途 | 采样率习惯 |
|---|---|---|
| LoopbackA | DSPC / 唤醒等已占用 | 常为 16 kHz 多通道 Mic+Ref |
| LoopbackB(本需求) | ACR 等第二路 Ref | 48 kHz / 2ch,跟 TDM-A 播放 |
注意(与抗混叠专文一致):
- 要 48 kHz 原样 Ref:多用 LoopbackB,且 不要强行再走会把数据重采样坏的路径
- 要 16 kHz + 抗混叠:往往走 LoopbackA + resample 一类方案,和本 ACR 需求不是同一条产品路径
两路可以共存,但 业务别抢同一 loopback 节点。
六、验收清单
-
/proc/asound/pcm出现LOOPBACK-B/alsaPORT-loopbackb - LoopbackA 仍在,DSPC 不受影响
-
datalb_src指向 tdmoutA,通道 2 -
tinyplay→ TDM-A 成功 -
tinycap→ LoopbackB @ 48k/2ch 成功 - 拉回 WAV,Audacity 可听、内容对应播放源
总结
ACR 再要一路 Ref 时,不必跟 DSPC 抢 LoopbackA:在 DTS 里 打开 LoopbackB,回采 TDM-A,用 48 kHz / 2ch 与播放端对齐,再以 tinyplay/tinycap 闭环验证。节点号以板级 pcm 列表为准,配错 -d 是最常见踩坑。
相关阅读
评论
还没有评论,来做第一个吧
读完了不评论,作者会以为你在沉思