OpenSL ES 简介
OpenSL ES 是 Khronos Group 开发的免费音频处理库,它为嵌入式移动多媒体设备上的应用开发者提供了一套标准化的、高性能的 API。与其他音频库相比,OpenSL ES 拥有以下优势:
- 跨平台性: OpenSL ES 可以在多种平台上使用,包括 Android、iOS、Linux 和 Windows 等。
- 高效性: OpenSL ES 提供了高度优化的音频处理算法,可以实现高效的音频解码、编码、混音等操作。
- 低延迟: OpenSL ES 的设计目标是实现低延迟的音频处理,适合实时音频应用。
- 标准化: OpenSL ES 提供了一套标准化的 API,方便开发者快速学习和使用。
OpenSL ES 在 HarmonyOS 中的应用
在 HarmonyOS 上,OpenSL ES 可以应用于各种音频场景,包括:
- 音频播放: 播放本地音频文件或网络音频流。
- 录音: 录制音频数据。
- 音效处理: 添加音频特效,例如回声、混响、均衡器等。
- 音频引擎: 构建更复杂的音频处理系统,例如音乐播放器、语音识别、音频编辑等。
音频播放示例
下面以一个完整的代码示例展示如何使用 OpenSL ES 实现音频播放功能:
#include "SLES/OpenSLES.h"
#include "SLES/OpenSLES_OpenHarmony.h"
#include "SLES/OpenSLES_Platform.h"
int main() {
// 1. 创建引擎对象
SLObjectItf engineObject = nullptr;
slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
(*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
// 2. 获取引擎接口
SLEngineItf engineEngine = nullptr;
(*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
// 3. 配置播放器信息,创建音频播放器
SLDataLocator_BufferQueue slBufferQueue = {
SL_DATALOCATOR_BUFFERQUEUE,
0
};
// 具体参数需要根据音频文件格式进行适配
SLDataFormat_PCM pcmFormat = {
SL_DATAFORMAT_PCM,
2, // 通道数
SL_SAMPLINGRATE_48, // 采样率
SL_PCMSAMPLEFORMAT_FIXED_16, // 音频采样格式
0,
0,
0
};
SLDataSource slSource = {&slBufferQueue, &pcmFormat};
SLObjectItf pcmPlayerObject = nullptr;
(*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject, &slSource, nullptr, 0, nullptr, nullptr);
(*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE);
// 4. 获取缓冲队列接口
SLOHBufferQueueItf bufferQueueItf;
(*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
// 5. 打开音频文件,注册缓冲队列回调
static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size) {
SLuint8 *buffer = nullptr;
SLuint32 pSize;
(*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, &pSize);
// 将待播放音频数据写入 buffer
// ...
(*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
}
void *pContext; // 可传入自定义的上下文信息,会在 Callback 内收到
(*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, pContext);
// 6. 获取播放接口,开始播放
SLPlayItf playItf = nullptr;
(*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf);
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
// 7. 结束音频播放
// ...
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
(*pcmPlayerObject)->Destroy(pcmPlayerObject);
(*engineObject)->Destroy(engineObject);
return 0;
}