AAudio的概念介绍:

AAudio 是作为 OpenSL ES 库的轻量级原生 Android 替代项而开发。 与 OpenSL ES 相比,AAudio API 不仅较小,而且容易使用。

AAudio 是在 Android O 版本中引入的全新 Android C API。

因此 API 是专为需要低延迟的高性能音频应用而设计。 应用通过读取并将数据写入流来与 AAudio 进行通信。

GitHub :AAudio Android demo地址http:// https://github.com/googlesamples/android-audio-high-performance/tree/master/aaudio

使用Android系统底层的OpenSL ES或者AAudio都可以实现一个高性能的音频程序,尤其是AAudio更是简单易用,性能上,功能上都更佳,但是AAudio 是在 Android O 版本中才引入的全新 Android C API,在以前的系统版本中只能使用OpenSL ES。

  • 那么我们需要做的是在新版本系统中使用AAudio
  • 在不支持AAudio的系统版本中使用OpenSL ES,两套 API 同时使用。

不要怕困难,因为这是一个即面向未来,又兼顾现在的优秀方案。不要害怕这有多么困难,Google已经帮我们实现了——Oboe。

OpenSL ES 谷歌使用文档介绍如下:

注意:开发者应考虑使用开源 Oboe 库,这个库可在 GitHub 上获得。Oboe 是一个 C++ 封装容器,提供与 AAudio 非常相似的 API。Oboe 在 AAudio 可用时对其进行调用,并在 AAudio 不可用时回退到 OpenSL ES。

OpenSL ES™  API 规范的 Android 专用实现。利用这个库,不论您是编写合成器、数字音频工作站、卡拉 OK 应用、游戏还是其他实时应用,都可以使用 C 或 C++ 实现高性能、低延迟的音频。

  • OpenSL ES 与 Android Java 框架中的 MediaPlayer 和 MediaRecorder API 提供类似的音频功能。
  • OpenSL ES 提供 C 语言接口和 C++ 绑定,让您可以从使用任意一种语言编写的代码中调用 API。

OpenSL ES API 可以帮助您开发和提升应用的音频性能。


如何使用oboe?


官方指导文档在这里,可以通过两种方式使用oboe,这里是把源码拉下来编译到项目。

1. 下载oboe库->https://github.com/google/oboe

Oboe GitHub 主页 : GitHub/Oboe

① 简单使用 : Getting Started

② Oboe 全指南 : Full Guide To Oboe

③ Oboe API 参考 : API reference

④ Android 音频框架发展 : Android audio history


OpenSL 的生命周期如下:

为 OpenSL ES 播放器设置 采样率 与 采样缓冲区参数 :

( 1 ) 在 Java 层获取采样率与采样缓冲区大小 :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){AudioManager myAudioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);// 获取采样率String sampleRateStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);int defaultSampleRate = Integer.parseInt(sampleRateStr);// 获取采样缓冲区String framesPerBurstStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);int defaultFramesPerBurst = Integer.parseInt(framesPerBurstStr);// 调用 Native 方法传入本地层 native_setDefaultStreamValues(defaultSampleRate, defaultFramesPerBurst);
}

( 2 ) 在 C++ 代码中设置 OpenSL ES 的参数 :

JNIEXPORT void JNICALL
Java_com_google_sample_oboe_hellooboe_MainActivity_native_1setDefaultStreamValues(JNIEnv *env,jclass type,jint sampleRate,jint framesPerBurst) {oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
}

上述的采样率 和 缓冲区大小是用于 设置 Android 设备内置音频设备 的 , 如 内置扬声器 , 听筒 ;

外置设备 , 如耳机 , 蓝牙音箱 需要设置更大的缓冲区 ;


Oboe 音频流


Oboe 的主要作用是在 Android 应用 和 Android 设备中的 音频 输入 / 输出 设备 之间 操作移动音频数据 ;

Android 应用 输入 / 输出 数据 方案 :

  • 通过使用 回调函数 实现
  • 直接从 音频流 中 读取 / 写出 数据

音频数据读写调用 , 可以是 阻塞的 ( 同步 ) , 也可以是 非阻塞的 ( 异步 ) ;

  • 阻塞 : 调用后 , 阻塞等待回应 , 回应收到后 , 才往下执行 ;
  • 非阻塞 : 调用后 , 不等待回应 , 直接向后执行后续代码 ;

音频流根据如下属性定义 :

  • 音频流方向 : 音频设备作为 数据源 或 流数据接收器 ( 数据目的地 ) ;
  • 共享模式 : 独占模式 / 共享模式 ; 独占模式 下音频流独占该设备 , 其它音频流不允许访问该设备 , 性能高 ; 共享模式 , 多个音频流可以同时访问该设备 , 性能低 ;
  • 采样格式 : 音频流数据的采样格式 ;

Oboe 音频设备


音频设备与音频流对应关系 : 每个 Oboe 音频流都需要关联一个单独的音频设备 ; 注意对应关系 , 一个音频设备可以关联多个音频流 , 但是 一个音频流只能关联一个音频设备 ;

音频设备作用 : 音频设备是一个硬件接口或者虚拟端口 , 一般作为 连续的数字音频数据流的 源端 或 目的端 ; 音频设备作为 数据源 或 流数据接收器 ( 数据目的地 ) ;

音频设备举例 : Android 设备的 内置麦克风 , 扬声器 , 电话听筒 , 或外接的耳机 , 蓝牙音箱 等 ;

获取音频设备 : Android 6.0 Marshmallow( API Level 23 ) 及以上的版本 , 可以通过调用 AudioManager 的 getDevices() 方法 , 获取当前的可用音频设备 , 该方法会返回设备的类型和信息 ;

音频设备 ID : 每个音频设备都有一个 唯一的 ID 标识 , 使用该标识 , 可以实现将 音频流 与 指定的 音频设备进行绑定 ; 多数情况下 , 用户不需要自己设置音频设备 , Oboe 会自动选择主设备 , 推荐让 Oboe 自动选择 , 不要进行手动干预 ;

音频流方向 : 音频设备 可以 决定该音频流是 输入流 还是 输出流

  • 输入流 : 麦克风 , 采集音频数据 ; 设备 -> 内存 ;
  • 输出流 : 扬声器 , 播放音频数据 ; 内存 -> 设备 ;

打开 Oboe 音频流时 , 系统会检查音频流方向 , 如果你设置的是麦克风 , 但是音频流方向设置成了输出方向 , 那么打开音频流操作就会出错 ;


使用总结:


第一步:导入oboe头文件

第二步:创建builder并设置参数

第三步:设置回调接口

第四步:播放音频

第五步:关闭音频流


下面提供一下Oboe使用实例:

录制器:

 setupCommonStreamParameters(oboe::AudioStreamBuilder *builder) {builder->setAudioApi(mAudioApi)->setSharingMode(oboe::SharingMode::Exclusive)->setPerformanceMode(oboe::PerformanceMode::LowLatency);return builder;setupRecordingStreamParameters(oboe::AudioStreamBuilder *builder ,bool isCallBack) {builder->setCallback(this)->setDirection(oboe::Direction::Input)return setupCommonStreamParameters(builder);oboe::AudioStream *mRecordingStream = nullptr;oboe::AudioStreamBuilder builder;setupRecordingStreamParameters(&builder);oboe::Result result = builder.openStream(&mRecordingStream);if (result == oboe::Result::OK && mRecordingStream) {oboe::Result result = mRecordingStream->requestStart();  //开始录制。}

播放器:

 setupCommonStreamParameters(oboe::AudioStreamBuilder *builder) {builder->setAudioApi(mAudioApi)->setSharingMode(oboe::SharingMode::Exclusive)->setPerformanceMode(oboe::PerformanceMode::LowLatency);return builder;setupPlayStreamParameters(oboe::AudioStreamBuilder *builder ,bool isCallBack) {builder->setCallback(this)->setDirection(oboe::Direction::output)return setupCommonStreamParameters(builder);oboe::AudioStream *mPlayStream = nullptr;oboe::AudioStreamBuilder builder;setupPlayStreamParameters(&builder);oboe::Result result = builder.openStream(&mPlayStream);if (result == oboe::Result::OK && mPlayStream) {oboe::Result result = mPlayStream->requestStart();  //开始播放。}oboe::DataCallbackResult LiveEffectEngine::onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) {render(audioData,numFrames); //audioData放入数据即可播放。return oboe::DataCallbackResult::Continue;}


使用Android高性能音频--OpenSL ES和AAudio相关推荐

  1. 【Android 高性能音频】Oboe 播放器开发 ( 为 OpenSL ES 配置参数以获得最佳延迟 | Oboe 音频流 | Oboe 音频设备 )

    文章目录 一.获得最佳延迟 二.Oboe 音频流 三.Oboe 音频设备 Oboe GitHub 主页 : GitHub/Oboe ① 简单使用 : Getting Started ② Oboe 全指 ...

  2. 【Android 高性能音频】AAudio 音频流 数据回调细节 ( 数据回调函数优先级 | 数据回调函数 | 采样率 | 采样数 | 缓冲区调整 | 线程不安全 )

    文章目录 I . 数据回调函数优先级 II . 数据回调函数 相关内容 III . 采样率 处理细节 IV . 数据回调函数 每次 采样个数 numFrames V . 数据回调函数 缓冲区 ( AA ...

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

    文章目录 I . AAudio 音频流内部缓冲区 与 音频数据读写缓冲区 概念 II . AAudio 音频流内部缓冲区 缓冲区帧容量 BufferCapacityInFrames 与 缓冲区帧大小 ...

  4. 【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )

    文章目录 一.Oboe 输出测试参数面板 二.Oboe 输出测试参数 API 及 设备选择 三.Oboe 输出测试参数 音频参数 四.Oboe 输出测试参数 播放偏好 五.Oboe 输出测试参数 ( ...

  5. 【Android 高性能音频】OboeTest 音频性能测试应用 ( 应用简介 | 测试内容 | 输出测试 | Oboe 缓冲区 与 工作负载修改 | 测试案例 )

    文章目录 一.Oboe 测试应用 二.Oboe 测试内容 三.Oboe 输出测试 四.Oboe 缓冲区 与 工作负载修改 五.Oboe 输出测试 ( Pixel 2 | Android 10 ) 一. ...

  6. 【Android 高性能音频】Oboe 函数库简介 ( Oboe 简介 | Oboe 特点 | Oboe 编译工具 | Oboe 相关文档 | Oboe 测试工具 )

    文章目录 一.Oboe 简介 二.Oboe 特点 三.Oboe 编译工具 四.Oboe 文档 五.Oboe 测试 一.Oboe 简介 Oboe 简介 : ① 函数库 : Oboe 是 C++ 函数库 ...

  7. OpenSL ES与AAudio简单介绍

    原因:在耳返功能时,如果使用AudioRecord和AudioTrack进行采集与播放会造成延迟问题,故需要涉及到openSL ES与AAudio的使用. 概况:OpenSL ES与AAudio简单理 ...

  8. 【Android 高性能音频】Oboe 音频流打开后 耳机 / 音箱 插拔事件处理 ( 动态注册广播接收者监听耳机插拔事件 | 重新打开 Oboe 音频流 )

    文章目录 一.动态注册广播接收者监听耳机插拔事件 二.jni 层的 Oboe 播放器代码 ( 重新打开 Oboe 音频流 ) 三.相关资料 基于 [Android 高性能音频]Oboe 开发流程 ( ...

  9. 【Android 高性能音频】Oboe 开发流程 ( Oboe 音频帧简介 | AudioStreamCallback 中的数据帧说明 )

    文章目录 一.音频帧概念 二.AudioStreamCallback 中的音频数据帧说明 Oboe GitHub 主页 : GitHub/Oboe ① 简单使用 : Getting Started ② ...

最新文章

  1. 近期活动盘点:2019清华大数据系统软件峰会(9.15)
  2. linuxDNS服务器的部署
  3. 朋友圈里的一张组合逻辑图
  4. 下单问题分析及解决方式
  5. 为什么Kubernetes要引入pod的概念,而不直接操作Docker容器
  6. Codeforce-CodeCraft-20 (Div. 2)-B. String Modification (找规律+模拟)
  7. Linux笔记-bash中执行命令并将执行的命令结果存储为变量
  8. if-else嵌套太深?教你一个新手都能掌握的设计模式搞定!
  9. 003 python 注释/数据类型/运算符/输入输出/格式化输出
  10. extjs 兼容性问题解决方案
  11. 影响电缆特性阻抗的三个方面
  12. java怎么加锁_JAVA多线程(3)——如何加锁
  13. python3中26个英文字母排序_26个英文字母的排序是怎样排的?
  14. kettle设置mysql时区_kettle中通过 时间戳(timestamp)方式 来实现数据库的增量同步操作(一)...
  15. 天数最少的年份_农历辛丑年仅有354天是怎么回事 平年比闰年少几天
  16. 简单几步轻松获取WiFi密码
  17. HtmlEditor在线编辑器V3.0提供
  18. 【字符串】Hash表
  19. c语言编写一个程序计算某年某月有几天,c语言编写程序,输入某年某月,求该月的天数...
  20. 东大22春电子政务X《电子政务》在线平时作业3参考非答案

热门文章

  1. 可执行文件组成及内存映射
  2. Java学习 第四章 java面向对象(二)
  3. 【程序5】 题目:利用条件运算符的嵌套来完成此题:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。 1.程序分析:(ab)?a:b这是条件运算符的基本例子。...
  4. Linux产生随机数的几种常见方法
  5. ios使用支付宝进行支付,注意事项 集成支付宝钱包支付iOS SDK的方法与经验。...
  6. HDU_1874 畅通工程续(SPFA)
  7. Grafana分析Nginx日志
  8. 使用Emit反射建立运行时实体模型
  9. Object调用静态方法
  10. operator、explicit与implicit