简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址: Audio工程师进阶系列原创干货持续更新中……】🚀
Android多媒体专栏地址: 多媒体系统工程师系列原创干货持续更新中……】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻1. 前言

本篇目的:

Linux PulseAudio 深度解析之 pa_context_get_source_info_list 调用流程与实战。

要点概括

  • 核心功能:查询当前 PulseAudio Server 中所有输入设备(Source)的详细信息。
  • 工作机制:客户端通过 Native Protocol 向 PulseAudio Daemon 发送 Source 列表查询请求,服务端遍历 core->sources,并把每一个 pa_source 的信息逐条回调给客户端。
  • 典型用途:录音设备列表展示、默认输入设备选择、麦克风调试、Monitor Source 分析。

🌻2. 应用场景与用法

pa_context_get_source_info_list() 是 PulseAudio 输入设备管理体系中的列表查询接口。

在 PulseAudio 中,Built-in Microphone、USB Microphone、Bluetooth Headset Mic、Monitor Source 这类输入端,最终都会对应一个 pa_source 对象。

而该接口用于:

一次性枚举当前系统中所有 Source 输入设备。


函数原型

pa_operation* pa_context_get_source_info_list(
        pa_context *c,
        pa_source_info_cb_t cb,
        void *userdata);

参数说明

c:
PulseAudio Context

cb:
信息返回回调

userdata:
用户私有数据

返回值

返回 pa_operation 对象

用于查询操作状态、管理生命周期,以及等待服务端返回完整 Source 列表结果。


应用场景

pa_context_get_source_info_list() 常见应用场景主要有三类。

第一类是录音设备列表展示。录音软件、音频设置面板或系统音量控制工具,需要展示当前系统中可用的输入设备,例如内置麦克风、USB 麦克风、蓝牙耳机麦克风等。通过该接口可以一次性获取所有 pa_source 的名称、描述、采样格式、声道布局、音量、静音状态和驱动信息。

第二类是默认输入设备选择。在实现“选择录音设备”“切换麦克风”“指定 App 使用某个输入源”这类功能时,需要先通过 pa_context_get_source_info_list() 获取完整 Source 列表,再根据设备名称、描述、Index、Proplist 等信息匹配目标设备。

第三类是音频调试与 Monitor Source 分析。PulseAudio 中除了真实麦克风,还会为输出设备生成对应的 Monitor Source,用来录制系统播放声音。通过该接口可以区分真实输入设备与 Monitor Source,判断录音程序是否接入了正确输入源,以及采样率、声道数、驱动信息是否符合预期。


🌻3. 调用流程剖析

🌻3.1 核心步骤

1. 应用层发起请求

pa_context_get_source_info_list(
        context,
        source_info_cb,
        userdata);

2. 创建 pa_operation

内部创建:

pa_operation

表示:

查询 Source 列表

操作。


3. 封装协议数据

构造:

GET_SOURCE_INFO_LIST

请求。

pa_context_get_source_info_by_index() 不同,列表查询不需要传入单个 Source Index。


4. 发送到 PulseAudio Server

通过:

Native Protocol

发送到 Daemon。


5. 服务端遍历 Source 列表

内部遍历:

core->sources

逐个获取当前系统中的:

pa_source

对象。


6. 提取每个输入设备的属性信息

对每个 pa_source 读取名称、描述、音量、Mute 状态、Driver、SampleSpec、ChannelMap、Monitor Source 标记等信息。


7. 逐条返回查询结果

服务端把每一个 Source 信息封装成 Reply,并逐条发送给客户端。


8. 触发回调并发送结束标记

客户端会多次进入:

source_info_cb(...)

每次回调对应一个 Source;当 eol > 0 时,表示列表查询结束。


🌻3.2 调用流程图

在这里插入图片描述


🌻3.3 Source 列表查询生命周期图

在这里插入图片描述


🌻4. 实战应用案例

#include <pulse/pulseaudio.h>
#include <stdio.h>

static void source_info_cb(
        pa_context *c,
        const pa_source_info *info,
        int eol,
        void *userdata) {

    if (eol < 0) {
        printf("query source list failed\n");
        return;
    }

    if (eol > 0) {
        printf("source list query finished\n");
        return;
    }

    printf("Source Index : %u\n",
           info->index);

    printf("Name         : %s\n",
           info->name ? info->name : "unknown");

    printf("Description  : %s\n",
           info->description ? info->description : "unknown");

    printf("Owner Module : %u\n",
           info->owner_module);

    printf("Mute         : %d\n",
           info->mute);

    printf("Driver       : %s\n\n",
           info->driver ? info->driver : "unknown");
}

void get_source_info_list(
        pa_context *context) {

    pa_operation *op;

    op =
        pa_context_get_source_info_list(
                context,
                source_info_cb,
                NULL);

    if (!op) {
        printf("query source list failed\n");
        return;
    }

    pa_operation_unref(op);
}

int main() {

    pa_context *context;

    /*
     * 假设 Context 已连接成功
     */

    get_source_info_list(context);

    return 0;
}

🌻5. 一句话总结

pa_context_get_source_info_list() 本质上是:

“枚举当前 PulseAudio Server 中所有输入设备的详细信息”。

它负责批量获取 Source 名称、描述、Mute 状态、Source Volume、Driver 信息、SampleSpec 参数和 ChannelMap 信息,是录音设备列表展示、默认输入设备选择、麦克风调试和 Monitor Source 分析中非常常用的查询接口之一。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐