Android NDK开发详解高性能音频之使用OpenSL ES

OpenSL ES

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

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

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

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

标准 OpenSL ES 头文件 <SLES/OpenSLES.h> 和 <SLES/OpenSLES_Platform.h> 允许音频输入和输出。<SLES/OpenSLES_Android.h> 和 <SLES/OpenSLES_AndroidConfiguration.h> 中提供了其他 Android 专用功能。

本部分首先说明如何将 OpenSL ES 整合到您的应用中。然后,介绍您需要了解的 OpenSL ES 的 Android 实现相关信息,其中首先会重点介绍此实现与参考规范之间的差异,然后介绍用于确保 Android 兼容性的其他扩展。最后,本部分提供一些补充性的编程说明,用于确保正确实现 OpenSL ES。

入门

本部分提供开始使用 OpenSL ES API 时所需了解的信息。

向您的应用添加 OpenSL ES

您可以从 C 和 C++ 代码调用 OpenSL ES。若要向您的应用添加核心 OpenSL ES 功能集,请添加 OpenSLES.h 头文件:

#include <SLES/OpenSLES.h>

若还要添加 OpenSL ES Android 扩展,请添加 OpenSLES_Android.h 头文件:

#include <SLES/OpenSLES_Android.h>

添加 OpenSLES_Android.h 头文件后,以下头文件将自动包括在内:

#include <SLES/OpenSLES_AndroidConfiguration.h>
#include <SLES/OpenSLES_AndroidMetadata.h>

注意:这些头文件不是必需的,显示它们是为了帮助您学习此 API。

构建和调试

您可以在用作 NDK 构建系统的一个 Makefile 的 Android.mk 文件中指定 OpenSL ES,从而将 OpenSL ES 添加到您的 build 中。将以下行添加到 Android.mk 中:

LOCAL_LDLIBS += -lOpenSLES

为了稳健地进行调试,建议您检查大部分 OpenSL ES API 所返回的 SLresult 值。您可以使用断言或更高级的错误处理逻辑进行调试;虽然其中一种或者另一种方式可能更适合给定用例,但在使用 OpenSL ES 时哪种方式都没有任何内在优势。

我们的示例中使用断言,因为断言有助于捕获可揭示编码错误的不切实际的情况。我们已经针对正式版中更可能出现的其他情况进行明确的错误处理。

在许多 API 错误出现时,系统不仅会返回非零结果代码,还会生成日志条目。此类日志条目能够提供额外的详细信息,对相对复杂的 API(如 Engine::CreateAudioPlayer)尤其有用。

您可以从命令行或 Android Studio 查看日志。如需从命令行检查日志,请输入以下命令:

$ adb logcat

若要从 Android Studio 检查日志,请依次选择 View > Tool Windows > Logcat。如需了解详情,请参阅使用 Logcat 写入和查看日志。

示例代码

我们建议您使用受支持且经过测试的示例代码,这些代码位于 android-ndk GitHub 代码库的 audio-echo 和 native-audio 文件夹中,您可以将其用作范本来编写自己的代码。

注意:OpenSL ES 1.0.1 规范在附录中提供示例代码(请参阅 Khronos OpenSL ES Registry 了解更多详情)。不过,“附录 B:示例代码”和“附录 C:用例示例代码”中的示例使用 Android 不支持的功能。某些示例中还存在排版错误,或者使用可能会发生改变的 API。参考这些示例时请务必谨慎;尽管这些代码对于理解完整的 OpenSL ES 标准可能非常有帮助,但不应照搬用在 Android 中。

音频内容

为应用打包音频内容的方法有很多种,下面介绍了其中几种:

资源:将音频文件置于 res/raw/ 文件夹后,可以通过 Resources 的关联 API 轻松访问这些文件。不过,无法对资源进行直接原生访问,所以您必须编写 Java 编程语言代码,将其复制出来后再使用。
资产:将您的音频文件置于 assets/ 文件夹后,可以通过 Android 原生资产管理器 API 直接访问这些文件。如需详细了解这些 API,请参阅头文件 android/asset_manager.h 和 android/asset_manager_jni.h。位于 android-ndk GitHub 代码库的示例代码将这些原生资产管理器 API 与 Android 文件描述符数据定位器结合使用。
网络:您可以使用 URI 数据定位器直接从网络播放音频内容。不过,请务必阅读安全与权限中介绍的内容。
本地文件系统:对于本地文件,URI 数据定位器支持 file: 架构,前提是这些文件可供应用访问。请注意,Android 安全框架限制通过 Linux 用户 ID 和组 ID 机制访问文件。
录制的内容:您的应用可以从麦克风输入录制音频数据,存储此内容,然后回放。示例代码使用此方法来处理“回放”剪辑。
编译和链接的内嵌内容:您可以将音频内容直接链接至共享库,然后使用支持缓冲区队列数据定位器的音频播放器播放。这最适合 PCM 格式的短剪辑。示例代码使用此方式处理 Hello 和 Android 剪辑。PCM 数据已通过 bin2c 工具(未提供)转换为十六进制字符串。
实时合成:您的应用可以动态合成 PCM 数据,然后使用支持缓冲区队列数据定位器的音频播放器播放。这是一种相对先进的技术,详细的音频合成介绍不在本文讨论的范围内。

注意:为应用寻找或创建有用的音频内容不在本文讨论的范围内。您可以使用网页搜索字词(例如,“互动音频”、“游戏音频”、“音效设计”和“音频编程”)查找更多信息。

注意:您必须确保在法律允许的情况下播放或录制内容。录制内容时,需要注意一些隐私权注意事项。

代码示例

我们的 GitHub 页面提供了以下示例应用:

audio-echo 创建从输入到输出的往返循环。
native-audio 是一个简单的音频录制器/播放器。

OpenSL ES 的 Android NDK 实现与 OpenSL ES 1.0.1 的参考规范有诸多不同。从 OpenSL ES 参考规范中直接复制的示例代码之所以无法在您的 Android 应用中使用,这些差异就是一个很重要的原因。

如需详细了解参考规范与 Android 实现之间的差异,请参阅 OpenSL ES for Android。

本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。

最后更新时间 (UTC):2023-11-13。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android NDK开发是指利用NDK(Native Development Kit)将C/C++开发的代码编译成so库,然后通过JNI(Java Native Interface)让Java程序调用。在Android开发中,默认使用的是Android SDK进行Java语言的开发,而对于一些需要使用C/C++高性能计算、底层操作或跨平台需求的场景,可以使用NDK进行开发。 在Android Studio中进行NDK开发相对于Eclipse来说更加方便,特别是在Android Studio 3.0及以上版本中,配置更加简化,并引入了CMake等工具,使得开发更加便捷。首先要进行NDK开发,需要配置环境,包括导入NDK、LLDB和CMake等工具。可以通过打开Android Studio的SDK Manager,选择SDK Tools,在其中选中相应的工具进行导入。 在项目的build.gradle文件中,可以配置一些NDK相关的参数,例如编译版本、ABI过滤器等。其中,可以通过externalNativeBuild配置CMake的相关设置,包括CMakeLists.txt文件的路径和版本号。此外,在sourceSets.main中还可以设置jniLibs.srcDirs,指定so库的位置。 在进行NDK开发时,可以在jni文件夹中编写C/C++代码,并通过JNI调用相关的函数。通过JNI接口,可以实现Java与C/C++之间的相互调用,从而实现跨语言的开发。 综上所述,Android NDK开发是指利用NDK将C/C++开发的代码编译成so库,并通过JNI实现与Java的相互调用。在Android Studio中进行NDK开发相对方便,可以通过配置环境和相应的参数来进行开发。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五一编程

程序之路有我与你同行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值