网络资源
-
pulseaudio故障排除 https://wiki.archlinux.org/index.php/PulseAudio/Troubleshooting 这里是pulseaudio的可能故障及解决办法,例如破音等,可以参考下。
(注 Arch Linux:这个网站可以先mark,有很多别的知识,比如 蓝牙,wifi,网络,蓝牙耳机, pulseaudio 如何配置蓝牙耳机等,可以学习) -
pulseaudio 的代码框架,模块,基础组件等的介绍,可以对 pulseaudio 的服务端和客户端源代码有个系统的认知 https://gavv.github.io/articles/pulseaudio-under-the-hood/#about-pulseaudio
-
这个人是 pulseaudio 源码现在的维护者:可以关注下https://www.patreon.com/tanuk
-
pulseaudio的配置文件路径 :/etc/pulse/
有4个配置文件 具体配置介绍:https://wiki.archlinux.org/index.php/PulseAudio/Configuration
pulseaudio stream流架构图
架构图
sink和sink-input是输出设备,source和source-output是输入设备例如麦克风(目前在搭建捕捉环境中需要使用,正式场景下应用场景没有使用),它们都应用于服务端。
sink-input的数据来源是客户端通过发送命令或数据利用socket本地协议(也可以远程)传递过来的。
调试过程技巧及注意点
-
pulseaudio 启动脚本路径: /etc/init.d/*
-
pulseaudio 服务端程序路径: /usr/bin/
-
开启服务端日志
调试的时候,先杀掉pulseaudio服务,然后再启动,最后要记得重启我们的主进程 (A113 lua版本的activation进程,yodaos 的vui进程,因为要让客户端重连服务器)
pulseaudio --system --daemonize=no --log-level=4 ......
--log-level参数: 设置日志等级 4级就是debug级
typedef enum pa_log_level {
PA_LOG_ERROR = 0, /* Error messages */
PA_LOG_WARN = 1, /* Warning messages */
PA_LOG_NOTICE = 2, /* Notice messages */
PA_LOG_INFO = 3, /* Info messages */
PA_LOG_DEBUG = 4, /* Debug messages */
PA_LOG_LEVEL_MAX
} pa_log_level_t;
- 使用gdb调试
关于必现的问题,很多时候只需要gdb跟踪代码就会很轻易的找到问题的原因。在调试前需要搭建好调试环境,需要准备:
- 通过openwrt编译目标板的gdb。
- 重新编译(增加cflags=-g)带符号表的动态库替换目标板。
在进入到实际应用时gdb可以有很多手段来复原刚才的必现问题。
- pactl命令的使用
pactl 是pulseaudio的自带命令,这些命令可以辅助我们知道当前pulseaudio的状态和每个sink、sink-input、source、source-output的状态。它可以帮助我们做以下的事情:
pactl命令表
上述命令中,列举一些目前使用到的命令:
- pactl load-module 通过命令行加载模块,这个命令在搭建监听环境时需要用到。
- pactl move-(sink-input|source-output) #N SINK|SOURCE 移动当前input的链接sink。
- pactl set-(sink|source)volume 设置音量
- pactl set-(sink|source)-mute #N 1|0|toggle
设置静音。其中toggle是翻转的意思。
同样我们也可以使用pulseaudio提供的pacmd命令字来达到上述的操作以及更多
-
捕捉硬件监听的pcm数据
$ vspdump -m b -d 10 -O
其中10为监听的时长,单位秒。
- 模拟播放playback应用
我们可以播放正常的声音来确认sink-input到sink这条链路是否正常。
-
输入命令播放wav格式音乐
$ paplay input.wav
- 捕捉sink pcm数据
如果需要捕捉sink的pcm数据可以使用如下的方式:
-
加载模块pipe sink
$ pactl load-module module-pipe-sink file="$(pwd)/output.pcm"
-
加载模块loopback
$ pactl load-module module-loopback
-
使用pactl命令将loopback sink-input 链接到 pipe sink
-
使用pactl 命令将loopback source-output 链接到sink monior(每个sink都会默认生成一个监听)
-
开始捕捉pcm数据
$ pacat output.pcm
- 捕捉sink-input pcm数据
-
加载pipe sink module
$ pactl load-module module-pipe-sink file="$(pwd)/output.pcm"
-
播放playback流
$ paplay input.wav
-
利用pactl 将sink input 链接到pipe sink.
4.开始捕捉pcm数据$ pacat output.pcm
- 捕捉sink input 并转换为wav格式
比之前到捕捉更节省空间。
-
加载null sink
$ pactl load-module module-null-sink
2.开始播放playback流
$ paplay input.wav
3.开始记录
$ parecord output.wav
- 利用pactl命令将sink-input链接到null sink。
- 利用pactl命令将source-output链接到null sink monitor.