Provider(1)- 什么是AudioBufferProvider
什么是AudioBufferProvider?
顾名思义,Audio音频数据缓冲提供,就是提供音频数据的缓冲类,而且这个AudioBufferProvider派生出许多子类,每个子类有不同的用途,至关重要;那它在Android哪个地方使用呢?
在PlaybackTread中,接收应用层传递而来的数据,那为什么要专门用这么多Provider类来处理呢?而不只是简单的转发,将应用层的数据转发到PlaybackThread就行了;
No、No、No!因为PlaybackThread负责接收应用层诸多应用的音频数据,每个音源的数据format、channel等不同,需要进行不同format转换、channel扩张/裁剪、down/upMix等,甚至会对其数据做一些音频特性如变速等操作,这就要对数据进行预处理,每一个provider的派生类就是用来做这些的
AudioBufferProvider类派生关系图

整体框架图如上,类的大致用途在图片中已简单标识,简而言之,右侧SourceAudioBufferProvider是专用于数据提供,而左侧的BufferProvider则是对数据进行一些特殊处理,那系统是如何串联这些对象呢?那就和父类的virtual函数有关系,重点关注AudioBufferProvider和PassthruBufferProvider这两个祖先类
AudioBufferProvider
class AudioBufferProvider
{
public:// FIXME merge with AudioTrackShared::Buffer, AudioTrack::Buffer, and AudioRecord::Buffer// and rename getNextBuffer() to obtainBuffer()struct Buffer {Buffer() : raw(NULL), frameCount(0) { }//联合体所有成员共用一个空间union {void* raw;short* i16;int8_t* i8;};size_t frameCount;};// On entry:// buffer != NULL// buffer->raw unused// buffer->frameCount maximum number of desired frames// On successful return:// status NO_ERROR// buffer->raw non-NULL pointer to buffer->frameCount contiguous available frames// buffer->frameCount number of contiguous available frames at buffer->raw,// 0 < buffer->frameCount <= entry value// On error return:// status != NO_ERROR// buffer->raw NULL// buffer->frameCount 0//buffer.raw地址 buffer.frameCount长度,也就是数据是读出来,读到buffer中去virtual status_t getNextBuffer(Buffer* buffer) = 0;
始祖类AudioBufferProvider定义了数据Buffer结构体,而getNextBuffer就是获取音频数据的,调用此方法后数据会存到buffer参数中去;
PassthruBufferProvider工作模式—责任链模式
class PassthruBufferProvider : public AudioBufferProvider {virtual void setBufferProvider(AudioBufferProvider *p) {mTrackBufferProvider = p;}protected:AudioBufferProvider *mTrackBufferProvider;
}
上面是定义,可以按如下伪代码使用:
std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider = AdjustChannelsBufferProvider();
std::unique_ptr<PassthruBufferProvider> mReformatBufferProvider = ReformatBufferProvider().setsetBufferProvider(mAdjustChannelsBufferProvider);
std::unique_ptr<PassthruBufferProvider> mTimestretchBufferProvider = TimestretchBufferProvider().setsetBufferProvider(mReformatBufferProvider);
这样mAdjustChannelsBufferProvider处理完了,就交给mReformatBufferProvider处理,在交给mTimestretchBufferProvider处理,直至处理完成;
在Android中哪个地方使用?
哈哈,据我所知,目前在2个地方看到:
/framework/av/services/audioflinger/threads.cpp
/frameworks/av/media/libaudioprocessing/AudioMixer.cpp
在threads里面的threadLoop_write方法里面,通常写入到sink对象,如下:
ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
{.....ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);....
}
这里就是接收应用层的数据,通常是写入到SourceBufferProvider中去;mNormalSink是MonoPipe类型,而MonoPipe怎么又和SourceBufferProvider扯上关系了呢?见下图:

当write写入到MonoPipe中去了以后,在SourceBufferProvider中,虚函数使用getNextBuffer拉去数据即可
而在AudioMixer中,在混音时通常会创建许多BufferProvider,对音频数据进行预处理,如下:

相关文章:
Provider(1)- 什么是AudioBufferProvider
什么是AudioBufferProvider? 顾名思义,Audio音频数据缓冲提供,就是提供音频数据的缓冲类,而且这个AudioBufferProvider派生出许多子类,每个子类有不同的用途,至关重要;那它在Android哪个地方使…...
加密与安全_密钥体系的三个核心目标之完整性解决方案
文章目录 Pre机密性完整性1. 哈希函数(Hash Function)定义特征常见算法应用散列函数常用场景散列函数无法解决的问题 2. 消息认证码(MAC)概述定义常见算法工作原理如何使用 MACMAC 的问题 不可否认性数字签名(Digital …...
【C++】:继承[下篇](友元静态成员菱形继承菱形虚拟继承)
目录 一,继承与友元二,继承与静态成员三,复杂的菱形继承及菱形虚拟继承四,继承的总结和反思 点击跳转上一篇文章: 【C】:继承(定义&&赋值兼容转换&&作用域&&派生类的默认成员函数…...
昇思25天学习打卡营第13天|基于MindNLP+MusicGen生成自己的个性化音乐
关于MindNLP MindNLP是一个依赖昇思MindSpore向上生长的NLP(自然语言处理)框架,旨在利用MindSpore的优势特性,如函数式融合编程、动态图功能、数据处理引擎等,致力于提供高效、易用的NLP解决方案。通过全面拥抱Huggin…...
nigix的下载使用
1、官网:https://nginx.org/en/download.html 双击打开 nginx的默认端口是80 配置文件 默认访问页面 在目录下新建pages,放入图片 在浏览器中输入地址进行访问 可以在电脑中配置本地域名 Windows设置本地DNS域名解析hosts文件配置 文件地址…...
nginx+lua 实现URL重定向(根据传入的参数条件)
程序版本说明 程序版本URLnginx1.27.0https://nginx.org/download/nginx-1.27.0.tar.gzngx_devel_kitv0.3.3https://github.com/simpl/ngx_devel_kit/archive/v0.3.3.tar.gzluajitv2.1https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20240626.tar.gzlua-nginx-m…...
算法学习笔记(8.4)-完全背包问题
目录 Question: 图例: 动态规划思路 2 代码实现: 3 空间优化: 代码实现: 下面是0-1背包和完全背包具体的例题: 代码实现: 图例: 空间优化代码示例 Question: 给定n个物品…...
C++catch (...)陈述
catch (...)陈述 例外处理可以有多个catch,如果catch后的小括弧里面放...,就表示不限型态种类的任何例外。 举例如下 #include <iostream>int main() {int i -1;try {if (i > 0) {throw 0;}throw 2.0;}catch (const int e) {std::cout <…...
Redis实践
Redis实践 使用复杂度高的命令 如果在使用Redis时,发现访问延迟突然增大,如何进行排查? 首先,第一步,建议你去查看一下Redis的慢日志。Redis提供了慢日志命令的统计功能,我们通过以下设置,就…...
【Lora模型推荐】Stable Diffusion创作具有玉石翡翠质感的图标设计
站长素材AI教程是站长之家旗下AI绘图教程平台 海量AI免费教程,每日更新干货内容 想要深入学习更多AI绘图教程,请访问站长素材AI教程网: AI教程_深度学习入门指南 - 站长素材 (chinaz.com) logo版权归各公司所有!本笔记仅供AIGC…...
vscode 远程开发
目录 vscode 远程连接 选择 Python 环境 vscode 远程连接 按 CtrlShiftP 打开命令面板。输入并选择 Remote-SSH: Open SSH Configuration File...。选择 ~/.ssh/config 文件(如果有多个选项)。在打开的文件中添加或修改你的 SSH 配置。 这个可以右键…...
前端Vue组件化实践:打造灵活可维护的地址管理组件
随着前端技术的不断演进,复杂度和开发难度也随之上升。传统的一体化开发模式使得每次小小的修改或功能增加都可能牵一发而动全身,严重影响了开发效率和维护成本。组件化开发作为一种解决方案,通过模块化、独立化的开发方式,实现了…...
虚幻引擎ue5游戏运行界面白茫茫一片,怎么处理
根剧下图顺序即可调节游戏运行界面光照问题: 在大纲里找到post,然后选中它,找到Exposure 把最低亮度和最高亮度的0改为1即可...
《代理选择与反爬虫策略探究:如何优化网络爬虫效率与稳定性》
代理IP如何选以及常见反爬策略 为什么需要代理? 因为有的网站会封IP,用户如果没有登录,那IP就是身份标识,如果网站发现用户行为异常就非常可能封IP 什么是代理IP 就是让一个人帮你转交请求,帮你转交的人对面不熟&a…...
Kotlin Flow 防抖 节流
防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 一:防抖(debounce)的概念: 防抖是指当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次, 如果设定时间到来之前&#x…...
Android Studio下载与安装
Android Studio下载与安装_android studio下载安装-CSDN博客...
【LC刷题】DAY24:122 55 45 1005
122. 买卖股票的最佳时机 II class Solution { public:int maxProfit(vector<int>& prices) {int result 0;for(int i 1; i < prices.size(); i ){result max(prices[i] - prices[ i - 1], 0);}return result;} };55. 跳跃游戏 link class Solution { public…...
从零开始的python学习生活2
接上封装 class Phone:__volt0.5def __keepsinglecore(self):print("让cpu以单核运行")def if5G(self):if self.__volt>1:print("5G通话已开启")else:self.__keepsinglecore()print("电量不足,无法使用5G通话,已经设置为单…...
【并发编程】进程 线程 协程
进程(Process)、线程(Thread)和协程(Coroutine)构成了计算机科学中实现任务并发执行的三种核心抽象机制。通常,为了提高程序的执行效率,开发者会根据应用场景和性能需求,…...
Vue的生命周期函数有哪些?详细说明
Vue.js 的生命周期函数包括以下几个阶段,每个阶段都有相应的钩子函数可以用来在特定时机执行自定义的逻辑。这些生命周期钩子函数使得我们可以在组件的不同阶段进行操作,从而管理组件的状态和行为。 1. beforeCreate: - 描述:…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
