点击下方👇关注 Android系统攻城狮
第201篇原创文章
持续迭代 | Android+Linux多媒体进阶体系
专栏·课程 知识体系持续更新

1


Linux声卡驱动注册完成后,可以通过aplay -l看到ALSA声卡。
例如:
card 2: rockchipes8388 [rockchip-es8388]但是,ALSA已经识别到声卡,并不代表PulseAudio一定能够立即看到这张声卡。
有时会出现下面这种现象:
aplay -l:可以看到ALSA声卡pactl list short cards:没有对应的PulseAudio Card从ALSA声卡出现,到PulseAudio加载对应的声卡模块,中间需要经过一个重要模块:
module-udev-detectmodule-udev-detect模块功能包括:
module-udev-detect负责发现、筛选和跟踪这些声卡。module-alsa-card。module-udev-detect并不直接创建Sink和Source,它的核心任务是:
发现系统中有哪些ALSA声卡,并为符合条件的声卡加载对应的驱动模块。

2


如果没有启动module-udev-detect模块,开发者需要在default.pa中为每一张声卡手动加载设备模块。
例如:
load-module module-alsa-sink device=hw:0,0load-module module-alsa-source device=hw:0,0这种方式存在几个问题:
module-udev-detect就是为了解决这些问题。
PulseAudio默认启动配置中通常会加载:
load-module module-udev-detect模块启动后,会自动寻找当前系统中的ALSA声卡,同时监听后续声卡变化,加载过程如下:


3


module-udev-detect通过udev扫描Linux的sound子系统。
当ALSA声卡驱动注册完成后,系统中通常会出现以下设备节点:
/sys/class/sound/card2/sys/class/sound/controlC2/sys/class/sound/pcmC2D0p/sys/class/sound/pcmC2D0c对应的设备节点可能包括:
/dev/snd/controlC2/dev/snd/pcmC2D0p/dev/snd/pcmC2D0c其中:
card2表示第2号ALSA声卡;controlC2表示这张声卡的控制设备;pcmC2D0p表示第2号声卡的第0号播放PCM;pcmC2D0c表示第2号声卡的第0号录音PCM。udev会根据sysfs信息和udev规则,为设备增加属性,sound子系统中不只有声卡,还包含Control、PCM、Timer等设备。

4


启动时的全量扫描,只能找到PulseAudio启动前已经存在的声卡。
对于运行过程中插入的USB声卡,module-udev-detect还需要持续监听udev事件,模块初始化时会创建:
udev monitor并且只监控sound子系统,当声卡发生变化时,udev monitor的文件描述符会触发,热插拔处理过程:

PulseAudio17源码中的monitor_cb()接收udev事件,过滤非Card路径后交给process_device();remove事件进入remove_card(),初始化完成的change事件进入card_changed()。

5


cat /proc/asound/cardsaplay -larecord -l如果这里没有声卡,说明问题在ALSA驱动链路,还没有进入module-udev-detect模块。
udev识别目标声卡card2信息
udevadm info \ --query=property \ --path=/sys/class/sound/card2监听sound设备变化:
udevadm monitor \ --kernel \ --udev \ --property \ --subsystem-match=soundls -l /dev/snd/getfacl /dev/snd/controlC2如果PulseAudio运行用户没有读写权限,声卡不会正常加载。
fuser -v /dev/snd/*pactl list short modules | grep -E 'module-udev-detect.discovered=1'如果输出:
module-udev-detect.discovered = "1"说明这张PulseAudio Card是由module-udev-detect发现并加载的。

6


pa__init() |
总结一下:
ALSA驱动:负责注册声卡。
udev模块:负责检测、识别声卡。
module-udev-detect模块:负责查找并交接声卡。
若读者朋友发现有错误、疑问的地方,或者好的建议,欢迎拍砖!!!