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

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

文章目录

一、获得最佳延迟

二、Oboe 音频流

三、Oboe 音频设备



Oboe GitHub 主页 : GitHub/Oboe


① 简单使用 : Getting Started


② Oboe 全指南 : Full Guide To Oboe


③ Oboe API 参考 : API reference


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



在 【Android 高性能音频】Oboe 开发流程 ( 导入 Oboe 库 | 使用预构建的二进制库和头文件 | 编译 Oboe 源码 ) 博客中介绍了 如何导入 Oboe 函数库到项目中 , 本博客中在导入 Oboe 函数库的基础上 , 进行 Oboe 播放器功能开发 ;


在 【Android 高性能音频】Oboe 开发流程 ( 包含头 Oboe 头文件 | 创建音频流 | 设置音频流 | 音频流回调类 AudioStreamCallback ) 介绍了如何创建 AudioStreamBuilder , 以及 创建 AudioStreamCallback 回调 ;


在 【Android 高性能音频】Oboe 开发流程 ( 创建并设置 AudioStreamCallback 对象 | 打开 Oboe 音频流 | 日志封装 logging_macros.h ) 博客中介绍了 设置 AudioStreamCallback 对象 , 打开 Oboe 音频流 操作 , 以及 Google 官方提供的日志封装有文件 ;


在 【Android 高性能音频】Oboe 开发流程 ( 检查 Oboe 音频流属性 | 开始播放 | 停止播放 | 关闭 Oboe 音频流 | 重新配置 Oboe 音频流属性 ) 博客中介绍了 如何开始 Oboe 音频流播放 , 以及 播放完毕后的收尾工作 ;


在 【Android 高性能音频】Oboe 开发流程 ( Oboe 完整代码示例 ) 博客中 , 介绍了 一个最简单的 Oboe 播放器开发流程 , 所有代码及应用配置 ;







一、获得最佳延迟


Oboe 库的目标是 提供低延迟音频流 ;


如果当前手机是 Android 8.0 Oreo( API Level 26 ) 及以上系统 , 就会自动选择 AAudio 打开音频流 , 系统会自动选择最佳配置 , framesPerBurst 也由 AAudio 提供 ;


如果当前手板版本 低于 Android 8.0 Oreo( API Level 26 ) , 此时会调用 OpenSL ES , OpenSL ES 播放器的参数需要完全由手动进行设置 ;



为 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 音频流时 , 系统会检查音频流方向 , 如果你设置的是麦克风 , 但是音频流方向设置成了输出方向 , 那么打开音频流操作就会出错 ;


目录
相关文章
|
6天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
11天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
13天前
|
存储 API 开发工具
探索安卓开发:从基础到进阶
【10月更文挑战第37天】在这篇文章中,我们将一起探索安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和建议。我们将从安卓开发的基础开始,逐步深入到更复杂的主题,如自定义组件、性能优化等。最后,我们将通过一个代码示例来展示如何实现一个简单的安卓应用。让我们一起开始吧!
|
网络协议 开发工具 Android开发
|
13天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
15天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
14天前
|
存储 XML JSON
探索安卓开发:从新手到专家的旅程
【10月更文挑战第36天】在这篇文章中,我们将一起踏上一段激动人心的旅程,从零基础开始,逐步深入安卓开发的奥秘。无论你是编程新手,还是希望扩展技能的老手,这里都有适合你的知识宝藏等待发掘。通过实际的代码示例和深入浅出的解释,我们将解锁安卓开发的关键技能,让你能够构建自己的应用程序,甚至贡献于开源社区。准备好了吗?让我们开始吧!
24 2
|
15天前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
23天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
21天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
30 5