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

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

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

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

欢迎关注Android系统攻城狮

🌻1. 前言

本篇目的:Linux PulseAudio 深度解析之 pa_context_get_sink_info_by_index 调用流程与实战。

要点概括

  • 核心功能:根据 Sink Index 查询指定输出设备的详细信息。
  • 工作机制:通过 Native Protocol 向 PulseAudio Server 发送查询请求,由服务端返回对应的 pa_sink_info 结构体。

🌻2. 用法与应用场景

pa_context_get_sink_info_by_index
是 PulseAudio 设备管理体系中的核心查询接口之一。

在 PulseAudio 中:

  • Sink 表示输出设备
  • 一个 Sink 对应一个音频输出端

例如:

  • 扬声器
  • HDMI
  • USB 声卡
  • 蓝牙耳机

每个 Sink 都拥有:

唯一的 Sink Index。

函数原型

pa_operation* pa_context_get_sink_info_by_index(
        pa_context *c,
        uint32_t idx,
        pa_sink_info_cb_t cb,
        void *userdata);

参数说明

c:
PulseAudio Context

idx:
Sink Index

cb:
查询结果回调

userdata:
用户私有数据

回调函数原型

typedef void (*pa_sink_info_cb_t)(
        pa_context *c,
        const pa_sink_info *i,
        int eol,
        void *userdata);

应用场景

1. 查询默认扬声器信息

pa_context_get_sink_info_by_index(
        context,
        sink_index,
        sink_info_cb,
        NULL);

用于:

  • 获取设备名称
  • 获取设备描述
  • 获取音量

2. 查询蓝牙耳机信息

例如:

bluez_output.xx.xx.xx

用于:

  • 蓝牙设备管理
  • A2DP 状态查看
  • HFP 状态查看

3. 音频路由管理

例如:

  • HDMI 切换
  • USB 声卡切换
  • 默认设备切换

都需要先获取:

pa_sink_info

结构体。


🌻3. 调用流程剖析

🌻3.1 核心步骤

1. 应用层发起查询
pa_context_get_sink_info_by_index(
        context,
        index,
        sink_info_cb,
        userdata);

2. libpulse 创建 operation

内部创建:

pa_operation

用于表示:

当前异步查询任务。


3. 发送查询请求

客户端发送:

PA_COMMAND_GET_SINK_INFO

到 PulseAudio Server。


4. Server 查找 Sink

服务端根据:

sink_index

查找:

pa_sink

对象。


5. 返回 pa_sink_info

Server 组装:

pa_sink_info

然后发送给客户端。


6. libpulse 触发回调

客户端收到数据后:

sink_info_cb(...)

被自动调用。


🌻3.2 调用流程图

Application

调用 pa_context_get_sink_info_by_index

创建 pa_operation

发送 GET_SINK_INFO 请求

PulseAudio Server

根据 Index 查找 pa_sink

构造 pa_sink_info

返回 Sink 信息

触发 sink_info_cb

应用层处理结果

🌻3.3 Sink 信息查询生命周期图

获得 Sink Index

调用查询接口

创建 operation

发送请求

Server 查询 Sink

生成 pa_sink_info

返回客户端

回调 sink_info_cb

获取设备信息

🌻4. 实战应用案例

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

static void sink_info_cb(
        pa_context *c,
        const pa_sink_info *info,
        int eol,
        void *userdata) {

    if (eol > 0)
        return;

    if (!info)
        return;

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

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

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

    printf("Channels   : %u\n",
           info->channel_map.channels);
}

void query_sink(
        pa_context *context,
        uint32_t sink_index) {

    pa_operation *op;

    op =
        pa_context_get_sink_info_by_index(
                context,
                sink_index,
                sink_info_cb,
                NULL);

    if (!op) {

        printf("query sink failed\n");
        return;
    }

    pa_operation_unref(op);
}

🌻5. 源码层核心原理

pa_context_get_sink_info_by_index
属于:

PulseAudio 异步查询接口。

内部执行流程:

pa_context_get_sink_info_by_index
            ↓
pa_operation_new
            ↓
创建 tagstruct
            ↓
发送 GET_SINK_INFO
            ↓
Server 查找 pa_sink
            ↓
封装 pa_sink_info
            ↓
返回客户端
            ↓
触发回调

本质上:

它不是读取本地缓存。

而是:

真正向 PulseAudio Server 发起一次异步查询。

因此涉及:

  • Socket 通信
  • Native Protocol
  • Operation 生命周期
  • 异步回调机制

属于:

PulseAudio 设备管理体系中的重量级查询接口。

🌻6. 一句话总结

pa_context_get_sink_info_by_index
本质上是:

“根据 Sink ID 获取设备完整档案”。

它负责:

  • 获取设备名称
  • 获取设备描述
  • 获取设备音量
  • 获取设备声道信息
  • 支撑设备管理与音频路由

是 PulseAudio Sink 管理体系中的核心查询接口之一。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐