警告:OpenSL ES 已弃用。开发者应使用开源 Oboe 库,该库可在 GitHub 上获取。Oboe 是一个 C++ 包装器,提供与 AAudio 非常相似的 API。当 AAudio 可用时,Oboe 会调用 AAudio;如果 AAudio 不可用,则回退到 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,将其集成到您的构建中。请将以下行添加到 Android.mk
LOCAL_LDLIBS += -lOpenSLES
为了进行可靠的调试,我们建议您检查大多数 OpenSL ES API 返回的 SLresult
值。您可以使用 断言或更高级的错误处理逻辑进行调试;两者在使用 OpenSL ES 方面都没有固有的优势,但其中一个可能更适合特定的用例。
我们在示例中使用了断言,因为它们有助于捕获不切实际的条件,这些条件可能表明存在编码错误。我们对生产环境中更可能发生的其他情况使用了显式错误处理。
除了非零结果码外,许多 API 错误都会生成日志条目。这些日志条目可以提供更多详细信息,对于 Engine::CreateAudioPlayer
等相对复杂的 API 尤其有用。
您可以通过命令行或 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:通过将音频文件放入
assets/
文件夹,Android 原生资产管理器 API 可以直接访问它们。有关这些 API 的更多信息,请参阅头文件android/asset_manager.h
和android/asset_manager_jni.h
。位于 android-ndk GitHub 仓库中的示例代码结合 Android 文件描述符数据定位器使用了这些原生资产管理器 API。 - 网络:您可以使用 URI 数据定位器直接从网络播放音频内容。但是,请务必阅读安全和权限。
- 本地文件系统:只要文件可由应用访问,URI 数据定位器就支持本地文件的
file:
方案。请注意,Android 安全框架通过 Linux 用户 ID 和组 ID 机制限制文件访问。 - 录音:您的应用可以从麦克风输入录制音频数据,存储此内容,然后稍后播放。示例代码对 Playback 片段使用了此方法。
- 编译并内联链接:您可以将音频内容直接链接到共享库中,然后使用带有缓冲区队列数据定位器的音频播放器播放它。这最适合短的 PCM 格式片段。示例代码对 Hello 和 Android 片段使用了此技术。PCM 数据是使用
bin2c
工具(未提供)转换为十六进制字符串的。 - 实时合成:您的应用可以即时合成 PCM 数据,然后使用带有缓冲区队列数据定位器的音频播放器播放它。这是一种相对高级的技术,音频合成的详细信息超出了本文的范围。
注意: 为您的应用查找或创建有用的音频内容超出了本文的范围。您可以使用诸如 interactive audio、game audio、sound design 和 audio programming 等网络搜索词来查找更多信息。
注意: 您有责任确保您在法律上被允许播放或录制内容。录制内容可能涉及隐私方面的考虑。
代码示例
这些示例应用可在我们的 GitHub 页面上找到
- audio-echo 创建一个输入到输出的往返循环。
- native-audio 是一个简单的音频录音机/播放器。
Android NDK 对 OpenSL ES 的实现与 OpenSL ES 1.0.1 的参考规范在许多方面有所不同。这些差异是您直接从 OpenSL ES 参考规范复制的示例代码可能无法在您的 Android 应用中工作的重要原因。
有关参考规范与 Android 实现之间差异的更多信息,请参阅适用于 Android 的 OpenSL ES。