当前位置: 首页 > news >正文

pulseaudio的相关操作(二)

这篇文章主要介绍pulseaudio playback的相关API,pulseaudio playback的具体实例可以参考[2]。如果用pulseaudio实现playback,简单地说就是创建一个playback stream,然后指定这个stream的sink,再定期的向这个stream中写数据。

mainloop相关API

pa_mainloop_new

mainloop是pulseaudio的核心,所以首先要用pa_mainloop_new创建一个mainloop实例。

 pa_mainloop *pa_ml = pa_mainloop_new();

pa_mainloop_get_api

获取指向mainloop api的指针

pa_mainloop_api *pa_mlapi = pa_mainloop_get_api(pa_ml);

pa_mainloop_run

启动mainloop消息处理循环,pa_mainloop_run的定义如下,主体部分为一个while循环,此函数在最后调用。

int pa_mainloop_run(pa_mainloop *m, int *retval) {int r;while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);if (r == -2)return 1;elsereturn -1;
}

context相关API

pa_context_new

创建连接上下文,"Simple PA test application"为创建的sink-input的application.name。

pa_context * pa_ctx = pa_context_new(pa_mlapi, "Simple PA test application");

pa_context_connect

把上下文连接到一个指定的server,输入NULL指定为default server。

pa_context_connect(pa_ctx, NULL, 0, NULL); 

pa_context_set_state_callback

设置状态回调函数,当上下文状态改变时,回调函数会触发,pa_ready为回调函数的参数。

pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);

回调函数的大致结果如下,根据当前的context状态做具体的操作。

void pa_state_cb(pa_context *c, void *userdata) {pa_context_state_t state = pa_context_get_state(c);switch  (state) {// TODO}
}

stream相关API

pa_stream_new

pa_stream_new用来创建一个stream,并指定音频流参数,如下:

pa_sample_spec ss;
ss.rate = 44100;
ss.channels = 1;
ss.format = PA_SAMPLE_S16LE;
playstream = pa_stream_new(pa_ctx, "Playback", &ss, NULL);// create a new stream
if (!playstream) {printf("pa_stream_new failed\n");
}

设置回调函数
可以设置的回调函数比较多,具体的回调函数可以查询API手册,对playback而言最重要的回调函数是write的回调函数,当pulseaudio需要往流中写入数据时会触发该函数,每次调用回调函数的间隔并非等间隔,且每次需要写入数据的大小不定,由pulseaudio的内部机制决定。
 

pa_stream_set_write_callback(playstream, stream_request_cb, NULL);

write回调函数的原型如下:

typedef void(* pa_stream_request_cb_t) (pa_stream *p, size_t nbytes, void *userdata);

在回调函数中的主要任务就是调用pa_stream_write函数,把数据写入到stream中。

pa_stream_connect_playback

下来要把stream连接 到一个device上,对playback而言就是要连接到一个sink device上,pa_stream_connect_playback的函数原型如下:

int pa_stream_connect_playback	(pa_stream * 	s,const char * 	dev,const pa_buffer_attr * 	attr,pa_stream_flags_t 	flags,const pa_cvolume * 	volume,pa_stream * 	sync_stream )	
  • s : 创建的stream
  • dev:stream要连接的sink device,NULL为默认的sink device
  • attr:定义了playback和record的缓冲区指标,pulseaudio对playback和record都有自己内部定义的buffer,而attr参 数即是对buffer参数的设置,需要根据自己的实际情况选择合适的参数。

    参数

    含义

    maxlength

    buffer大小(字节),-1为能支持的最大值,如果是低延时场景,此值应该设置较小且配合PA_STREAM_ADJUST_LATENCY flag,如果buffer设置小会导致更多的under run。

    tlength

    仅用于playback。当buffer中的数据少于tlength时会请求向stream写数据,触发write callback函数。如果设置为-1的话,pulseaudio内部会自适应设置一个值。 当 PA_STREAM_ADJUST_LATENCY 未设置时,该值仅影响每个流的播放缓冲区大小。当 PA_STREAM_ADJUST_LATENCY 设置时,sink的延迟加上播放缓冲区大小共同受此值影响。如果对调整总体延迟感兴趣,应设置 PA_STREAM_ADJUST_LATENCY。如果你只对配置服务器端每个流的播放缓冲区大小感兴趣,则不应设置 PA_STREAM_ADJUST_LATENCY。

    prebuf

    仅用于playback。此值为当buf中大小超过此值时,server才会播放,即初始播放的预留量,此值设为-1时表示此值和tlength一样。

    minreq

    仅用于playback。write back中请求的最少数据大小,如果设为-1,则由pulseaudio内部生成一个默认的值。

    fragsize

    仅用于recording。 server以 fragsize 字节大小的块发送数据。较大的值会降低与其他连接上下文操作的交互性,但会减少控制开销。设为-1的话pulseaudio会把其初始化为一个合理的值。如果设置了PA_STREAM_ADJUST_LATENCY,则总体源延迟将根据此值进行调整。如果不设置 PA_STREAM_ADJUST_LATENCY,则源延迟保持不变。

  • flags: 设置的额外的flags,具体的参考pa_stream_flags定义。
  • volume : 初始的默认音量,建议为NULL
  • sync_stream:此stream是否要和其它stream同步,如果设为NULL则各stream独立。

    清理工作

    当mainloop退出时需要做一些清理工作,回顾前面我们所作的工作,有创建了mainloop,创建了context,创建了stream,所以我们需要在最后清理这些我们创建的实例。 其中stream不用清理,因为pulseaudio用了类似智能指针的技术,当stream的引用计数为0时,会自动清理。所以我们清理的只有context和mainloop。清理的示意代码如下:

    // clean up and disconnect
    pa_context_disconnect(pa_ctx);
    pa_context_unref(pa_ctx);
    pa_mainloop_free(pa_ml);

    参考

    https://gavv.net/articles/pulseaudio-under-the-hood/ [1]

    Async Playback – Developer Documentation – PulseAudio [2]

相关文章:

pulseaudio的相关操作(二)

这篇文章主要介绍pulseaudio playback的相关API,pulseaudio playback的具体实例可以参考[2]。如果用pulseaudio实现playback,简单地说就是创建一个playback stream,然后指定这个stream的sink,再定期的向这个stream中写数据。 mai…...

Selenium自动化测试工具

一 .Selenium简介 是一个用于Web应用程序测试的工具 Selenium的核心功能之一是测试软件在不同浏览器和操作系统上的兼容性,确保软件功能与用户需求的一致性,提升用户体验。 自动化脚本生成与执行 Selenium支持自动录制用户操作并生成多种编程语言的测…...

优化UVM环境(九)-将interface文件放在env pkg外面

书接上回: 优化UVM环境(八)-整理project_common_pkg文件 My_env_pkg.sv里不能包含interface,需要将my_intf.sv文件放在pkg之外...

mysql 主从安装

登录看第二篇 WINDOWS系统搭建MYSQL 8.0主从模式_windows mysql8.0.34主从配置-CSDN博客 Windows下MySQL8.0最新版本超详细安装教程_windowsserver安装mysql8.0-CSDN博客 启动两个服务 可执行文件路径一致问题解决: windows,同一台机器安装两个mysq…...

【C++刷题】力扣-#121-买卖股票的最佳时机

题目描述 给定一个数组 prices,其中 prices[i] 表示第 i 天的股票价格。假设你可以在第 i 天买入并在第 j 天卖出股票(i ≤ j),设计一个算法来计算你所能获取的最大利润。注意你只能持有一股股票,并且你不能同时参与多…...

Python量化交易(二):金融市场的基础概念

引言 大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年10月学习赛的Python量化交易学习总结文档;在现代社会中,投资已成为个人、机构和政府追求财富增长和资源配置的重要方式。…...

Java方法的递归调用

Java中的方法可以通过调用自身来实现递归调用。 递归调用在解决一些问题时非常有用,特别是那些可以分解为相同结构的子问题的情况。递归调用可以让问题的解决过程更加简洁和优雅。 下面是一个简单的示例,展示了如何使用递归调用来计算一个数字的阶乘&a…...

JavaScript 第30章:综合项目

看起来您想要了解如何在一个JavaScript为主的项目中进行项目规划、技术选型、开发流程以及维护等方面的内容,并且希望结合Java的源代码来进行详细的讲解。不过,JavaScript和Java是两种不同的编程语言,通常它们的应用场景也不同。JavaScript 主…...

GB/T28181-2022规范解读、应用场景和技术实现探究

GB/T28181-2022和GB/T28181-2016区别 GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》与 GB/T28181-2016 相比,主要有以下区别: 术语和定义方面: 术语删减:GB/T28181-2022 删除了 “联网系统信息”“数…...

Docker容器间链路管理

Docker容器是一个轻量级的、可移植的软件打包技术,它允许开发者将应用程序及其依赖项打包到一个独立的容器中,然后发布到任何支持Docker的环境中运行。容器是完全使用沙箱机制,相互之间不会有任何接口,容器性能开销极低。 可以将…...

python画图|在三维空间的不同平面上分别绘制不同类型二维图

【1】引言 前序已经完成了基础的二维图和三维图绘制教程探索,可直达的链接包括但不限于: python画图|3D参数化图形输出-CSDN博客 python画三角函数图|小白入门级教程_正余弦函数画图python-CSDN博客 在学习过程中,发现一个案例&#xff1…...

与ai一起作诗(《校园清廉韵》)

与ai对话犹如拷问自己的灵魂,与其说ai助力还不如说在和自己对话。 (笔记模板由python脚本于2024年10月19日 19:18:33创建,本篇笔记适合喜欢python和诗歌的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free&…...

python matplotlib

一、图形函数 函数名称描述Bar绘制条形图Barh绘制水平条形图Boxplot绘制箱型图Hist绘制直方图his2d绘制2D直方图Pie绘制饼状图Plot在坐标轴上画线或者标记Polar绘制极坐标图Scatter绘制x与y的散点图Stackplot绘制堆叠图Stem用来绘制二维离散数据绘制(又称为火柴图&…...

秋招面试题记录_半结构化面试

c八股(可能问的多一点) 1.简单说说C11语法特性 答: 1.auto以及decltype自动类型推导,避免手动声明复杂类型,减少冗长代码提升了可读性和安全性。 2.智能指针 自动释放内存 (具体说说) 有shared和unique 差异主要体现在所有权、内存开销、…...

Java项目-基于springboot框架的疫苗接种管理系统项目实战(附源码+文档)

作者:计算机学长阿伟 开发技术:SpringBoot、SSM、Vue、MySQL、ElementUI等,“文末源码”。 开发运行环境 开发语言:Java数据库:MySQL技术:SpringBoot、Vue、Mybaits Plus、ELementUI工具:IDEA/…...

Android 12.0进程保活白名单功能实现

在Android 12.0系统中,实现进程保活白名单功能是为了确保某些重要的应用程序即使进入后台也能长时间保持运行状态,不被系统自动杀死。这一功能的实现涉及多个核心类和文件,以下是具体的实现步骤和核心功能分析: 一、实现步骤 …...

vscode 功能、设置备忘

2024年10月18日 crtl p 按文件名搜索,输入> 开始搜索命令 设置文件显示过滤和搜索过滤: ctrlp 输入 >settings 选择Preferences:Open Settings(UI),搜索exclude 配置 Files Exclude 修改显示过滤 配置 Search Exclude 修…...

错误 Failed to connect to xx.xx.xx.xx port xx: No route to host

Failed to connect to xx.xx.xx.xx port xx: No route to host 系统环境: Oracle Cloud(OCI)Ubuntu20.4 问题: 连接本机IP正常访问,连接内网ip可正常访问,但连接外网IP报错:Failed to conne…...

Redis环境的搭建

Redis环境的搭建可以分为Linux系统和Windows系统两种情况。 一、Linux系统下Redis的搭建 1. 安装前准备 确保Linux系统已安装GCC环境,可以使用yum install gcc-c命令安装。下载Redis安装包,例如redis-6.2.6.tar.gz,并将其上传到Linux服务器…...

Git Push(TODO)

最近经常碰到GIT push不上去的问题。到处求人解决也真是尴尬,想自己看看,所以刚刚在github上建了一个仓,试了下。结果如下: 暂时可能还不行,因为数据都是加密的,没法看到具体GIT的交互信息。。。 后面再想办…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

CSS | transition 和 transform的用处和区别

省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...