【Android 高性能音频】AAudio 音频流 缓冲区 简介 ( AAudio 音频流内部缓冲区 | 缓冲区帧容量 | 缓冲区帧大小 | 音频数据读写缓冲区 )

简介: 【Android 高性能音频】AAudio 音频流 缓冲区 简介 ( AAudio 音频流内部缓冲区 | 缓冲区帧容量 | 缓冲区帧大小 | 音频数据读写缓冲区 )

文章目录

I . AAudio 音频流内部缓冲区 与 音频数据读写缓冲区 概念

II . AAudio 音频流内部缓冲区 缓冲区帧容量 BufferCapacityInFrames 与 缓冲区帧大小 BufferSizeInFrames 区分

III . AAudio 音频流内部缓冲区 缓冲区帧容量 BufferCapacityInFrames

IV . AAudio 音频流内部缓冲区 缓冲区帧大小 BufferSizeInFrames

V . AAudio 音频流内部缓冲区 脉冲串

VI . AAudio 音频流内部缓冲区 工作机制 ( 播放音频 )

VII . AAudio 音频流内部缓冲区 优化

VIII . 音频数据读写缓冲区



I . AAudio 音频流内部缓冲区 与 音频数据读写缓冲区 概念


1 . AAudio 音频流内部缓冲区本质 : 该缓冲区是在音频设备中进行维护的 , AAudio 音频流会先将数据传入该缓冲区 , 然后才进行播放 ;



2 . 音频数据读写缓冲区 : 是在内存中维护的 , 其本质就是一个 void* 类型的数组 , 其数组字节大小由用户设定 ;



3 . 概念区分 : 注意将 AAudio 音频流内部缓冲区 与 音频数据读写缓冲区 区分清楚 ; 两个是完全不同的概念 ;




II . AAudio 音频流内部缓冲区 缓冲区帧容量 BufferCapacityInFrames 与 缓冲区帧大小 BufferSizeInFrames 区分


下面要区分两个概念 , 一个是缓冲区帧容量 BufferCapacityInFrames , 一个是缓冲区帧大小 BufferSizeInFrames , 这两个开发者都可以设置 ;


① 缓冲区帧容量 BufferCapacityInFrames : 是音频设备的缓冲区最大值 ;

② 缓冲区帧大小 BufferSizeInFrames : 用户实际使用的缓冲区大小 , 小于等于 缓冲区容量 ;

做一个形象的比喻 , 水杯有 2L 的容量 , 最大可以装 2L 水 , 2L 相当于缓冲区帧容量 ; 但是我们在水杯的 1.5L 位置画了一个最高水位线 , 表示盛水时不能高于 1.5L , 这个 1.5L 就是我们使用的实际缓冲区帧大小 ;


每帧的样本数就是通道数 , 单声道每帧 1 个样本 , 立体声 每帧 2 个样本 , 每个样本的大小与样本格式有关 , 16 位样本 每个样本 2 字节 ;




III . AAudio 音频流内部缓冲区 缓冲区帧容量 BufferCapacityInFrames


AAudio 音频流内部 缓冲区帧容量 : 音频设备的缓冲区最大值 ;


① 设置缓冲区最大容量 : 调用 AAudioStreamBuilder_setBufferCapacityInFrames() 方法可以设置音频设备缓冲区最大容量 ;

② 获取缓冲区最大容量 : 调用 AAudioStream_getBufferCapacityInFrames() 方法可以获取当前音频设备缓冲区的最大容量 ;



IV . AAudio 音频流内部缓冲区 缓冲区帧大小 BufferSizeInFrames


AAudio 音频流内部缓冲区帧大小 : 为音频设备设置了缓冲区最大容量 , 但是我们可能用不了这么大缓冲区 , 只使用其中一部分作为缓冲区 ;


① 缓冲区帧大小 限制 : 缓冲区帧大小 BufferSizeInFrames 只能小于等于 缓冲区帧容量 BufferCapacityInFrames ;

② 设置 缓冲区帧大小 作用 : 增加 缓冲区帧大小 BufferSizeInFrames 会增加音频延迟 , 反之会减小延迟 ;

③ 设置缓冲区帧大小 方法 : AAudioStreamBuilder_setBufferSizeInFrames() ;

④ 获取缓冲区帧大小 方法 : AAudioStreamBuilder_getBufferSizeInFrames() ;



V . AAudio 音频流内部缓冲区 脉冲串


1 . 脉冲串概念 : 音频设备读取 音频内部缓冲区数据时 , 会以离散的脉冲串形式从缓冲区中读取音频数据 , 每个脉冲串都包含多个音频帧 ;



2 . 脉冲串设置 : 脉冲串包含的帧个数 , 以及脉冲串的读取速度 , 这两个属性由 Android 系统控制 , 与音频设备的电路相关 ;



3 . 脉冲串属性固定 : 脉冲串的大小 和 速度 是无法修改的 , 可以根据 内部缓冲区 包含的脉冲串数量 设置内部缓冲区大小 ;



4 . 脉冲串 性能相关 设置 : AAudio 音频流的 内部缓冲区帧大小 是 脉冲串大小的整数倍时 , 音频延迟最短 ;




VI . AAudio 音频流内部缓冲区 工作机制 ( 播放音频 )


1 . 写出数据到内部缓冲区 : 使用 AAudio 音频流 播放音频时 , 先将数据写入 AAudio 音频流的内部缓冲区 , 该过程会阻塞线程 , 直到写入完成 ;


该缓冲区为音频设备内部维护的



2 . AAudio 音频流 会以 离散的 脉冲串形式 , 读取内部缓冲区中的音频数据 , 然后播放出来 ;



3 . 图示 : 内部缓冲区工作机制如下图 ;

image.png





VII . AAudio 音频流内部缓冲区 优化


1 . AAudio 音频流内部缓冲区优化步骤 : 设置一个合适的 缓冲区帧大小 BufferSizeInFrames , 先设置一个较大的缓冲区 , 逐步减小该缓冲区大小 , 监控 XRun ( 超限 或 欠载 ) 数值 , 当出现了上述情况 , 说明缓冲区减小到极限 , 出现了播放问题 , 此时再稍微将缓冲区调大 , 最终的缓冲区大小刚合适 , 兼顾性能与功能 ;


备选方案 : 先设置肯定出问题一个最小值 , 此时肯定会出现缓冲区不足的情况 , 逐步增加缓冲区大小 , 直到流畅读写为止 ;



2 . 调整时间 : 缓冲区大小调整的过程几乎是一瞬间完成的 , 在开始播放第一帧数据时就已经完成 ;



3 . 静音调整 : 缓冲区调整时 , 可以静音初始化缓冲区大小 , 确保用户听不到电流声 ;



4 . 不断调整 : 在音频播放的过程中 , 系统的性能可能随时改变 , 这个缓冲区的大小也要跟着实时修改 , 一旦监测到了 欠载 UnderRun 或 超限 OverRun 就马上调整缓冲区大小 ;



该过程可以参考上一篇博客 : 【Android 高性能音频】AAudio 缓冲区控制 ( XRun | 欠载 UnderRun | 超限 OverRun | 获取缓冲区大小 | 设置缓冲区大小 )




VIII . 音频数据读写缓冲区


1 . 概念区分 ( AAudio 内部缓冲区 / 音频读写缓冲区 ) : 该缓冲区是由用户自己维护的 , 与 AAudio 音频流缓冲区没有任何关系 , 不要混淆这两个概念 ;



2 . 缓冲区本质 : 音频读写缓冲区是在堆内存中维护的 , 其本质就是一个 void* 类型的数组 , 其数组字节大小由用户设定 ;



3 . 读写缓冲区作用 : 读取音频数据时 , 将音频数据先读取到该缓冲区中 ;



4 . 性能分析 : 该音频数据读写缓冲区 与 采样效率相关 , 采样是需要消耗额外性能的 , 如果该缓冲区很大 , 一次采集很多样本 , 采样的效率会很高 , 但是减少了灵活性 , 如果采样太少 , 就会额外消耗很多性能 ;


目录
相关文章
|
1月前
|
数据库 Android开发 开发者
构建高性能微服务架构:从理论到实践构建高效Android应用:探究Kotlin协程的优势
【2月更文挑战第16天】 在当今快速迭代和竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性和独立部署能力而受到企业的青睐。本文将深入探讨如何构建一个高性能的微服务系统,涵盖从理论基础到具体实现的各个方面。我们将重点讨论服务拆分策略、通信机制、数据一致性以及性能优化等关键主题,为读者提供一个清晰、实用的指南,以便在复杂多变的业务环境中构建和维护健壮的微服务体系结构。 【2月更文挑战第16天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着技术的不断进步,Kotlin作为一种现代编程语言,在Android开发中被广泛采用,尤其是其协程特性为异步编程带来了革命性的改进。本文旨在深入
238 5
|
3月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
38 0
|
3月前
|
安全 网络协议 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
27 0
|
3月前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
21 0
|
14天前
|
XML Java Android开发
Android每点击一次按钮就添加一条数据
Android每点击一次按钮就添加一条数据
21 1
|
1月前
|
存储 Android开发 C++
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
29 3
|
2月前
|
JavaScript Java 数据安全/隐私保护
安卓逆向 -- POST数据解密
安卓逆向 -- POST数据解密
21 2
|
3月前
|
编解码 测试技术 开发工具
如何实现Android视音频数据对接到GB28181平台(SmartGBD)
如何实现Android视音频数据对接到GB28181平台(SmartGBD)
|
3月前
|
数据采集 编解码 图形学
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
|
3月前
|
JSON Java Android开发
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
24 0