背景简介
OpenSL ES是一种针对嵌入式系统特别优化过的硬件音频加速API,无授权费并且可以跨平台使用。它提供的高性能、标准化、低延迟的特性实现为嵌入式媒体开发提供了标准,嵌入式开发者在开发本地音频应用也将变得更为简便,利用该API能够实现软/硬件音频性能的直接跨平台部署,降低了执行难度,促进高级音频市场的发展。
OpenSL ES的框架图
硬件实现:
软件实现:
Android应用中的音频录入会有延迟,而声音输出至扬声器之前也会耽误一些时间。在大多数基于ARM和x86的设备上,经过测量,音频RTL可能会延迟到300毫秒,大多是采用面向音频的Android方法开发的应用。用户群无法接受这种延迟范围,预期延迟必须低于100毫秒,在大多数情况下,低于20毫秒才是最理想的RTL。还需要考虑是音频处理延迟和缓冲区队列的总数。
与其他API一样,OpenSL ES的工作原理是采用回调机制。在OpenSL ES中,回调仅用于通知应用,新缓冲区可以排队(用于回放或录制)。在其他API中,回调还可以处理指向有待填充或使用的音频缓冲区的指示器。但在OpenSL ES中,更具选择,可以实施API以便回调以信令机制的形式运行,从而将所有处理维持在音频处理线程上。这样在收到分配的信号后,将包含为所需的缓冲区排队。
OpenSL ES使用流程
利用系统的AudioRecord进行数据采集有一定延时, 虽然5.0以后google针对音频做了一定的优化,延迟稍微改善,但是效果还是差强人意。所以为了更好的返听效果,OPENSL是最合适的,主要原因是以下三点。
- OpenSL ES使用的缓冲区队列机制,使其在Android媒体框架中更加高效。
- 如果手机支持低延迟特性那么就需要要使用OpenSL ES了(google原文:Low-latency audio is only supported when using Android’s implementation of the OpenSL ES? API and the Android NDK.)
- 由于该实施为原生代码,所以它可以提供更高的性能,因为原生代码不会受制于Java或Dalvik VM开销
因此这种方法有助于基于Android的音频开发。以下是OpenSL ES的初始化流程图。
在OpenSL中所有的操作都是通过接口来完成,和java的接口类似,接口提供底层的方法调用。常用的接口有以下几种:
- SLObjectItf :对象接口
- SLEngineItf :引擎接口
- SLPlayItf:播放接口
- SLBufferQueueItf :缓冲队列接口
- SLVolumeItf : 声量接口
以下分为四个部分:初始化,音频数据采集,音频数据传输,音频数据播放。
初始化
初始化主要包括,OpenSL ES引擎初始化,录音/播放器初始化。
OpenSL ES引擎初始化
OpenSL ES引擎初始化主要的点在于新建引擎对象连接JNI与底层交互,设置引擎的采样参数,包括采样平率,采样帧大小,采样声道以及采样深度,并且初始化音频数据的缓冲区队列。需要注意的是本次实验中使用的发送端与服务端的采样参数需要设置相同。
SLresult result;
memset(&engine, 0, sizeof(engine));
//设置采样参数
engine.fastPathSampleRate_ = static_cast<SLmilliHertz>(sampleRate) * 1000;
engine.fastPathFramesPerBuf_ = static_cast<uint32_t>(framesPerBuf