一、OpenSL ES介绍
OpenSL ES是指Open Sound System for Embedded Systems,是一种开放式、跨平台的、低延迟的音频编程接口,主要用于嵌入式音频应用,比如游戏、音频处理、多媒体等。Android系统中使用的就是OpenSL ES的API。
OpenSL ES与Java音频API(Java Sound API)结构不同。JavaAPI的机制运行在Java虚拟机上,可以帮助应用程序的开发者隐藏从不同硬件厂商所带来的差异。OpenSL ES提供较底层的音频编程接口,它使开发者能够直接访问移动设备上运行的硬件,并精确控制音频数据的流动,以便提供高质量、低延迟的音频输出。
在OpenSL ES中,所有音频需要在一个对应的Audio插槽(Audio Object)中进行处理,并且每个插槽都可以包含多个音频流。一个应用程序可以创建多个Audio插槽,通过控制音频流的流动,实现音频输出的控制。
二、OpenSL ES的特点
1、低延迟:OpenSL ES提供了一种精细控制音频数据流动的机制,使得音频处理的延迟得以控制,实现低延迟的音频输出。
2、高效性:OpenSL ES提供了多种良好的音频处理API,如音效处理、音量控制、均衡器等等,易于移植到设备上。
3、跨平台:OpenSL ES是一种开放式的音频编程接口,可以在嵌入式设备和移动设备上使用,具有很好的系统兼容性,易于移植到其他平台上。
三、OpenSL ES在Android平台上的应用
1、AudioPlayer播放音频文件
可以使用OpenSL ES播放WAV格式的音频文件,通过OpenSL ES可以更好地控制数据的流动,从而获得更低延迟的音频输出效果。下面是一个简单的AudioPlayer的代码示例:
//定义播放器 SLObjectItf pPlayerObj; //定义播放器接口 SLPlayItf pPlayer; //定义缓冲队列接口 SLAndroidSimpleBufferQueueItf pBuffQueue; //定义音频格式参数 SLDataFormat_PCM pcm; //定义音频源地址 SLDataLocator_AndroidFD android_fd; //创建Audio对象 slCreateEngine(&engineObj, 0, NULL, 0, NULL, NULL); //实例化Audio对象 (*engineObj)->Realize(engineObj, SL_BOOLEAN_FALSE); //获取Audio对象的接口 (*engineObj)->GetInterface(engineObj, SL_IID_ENGINE, &engine); //设置Audio源地址 android_fd.locatorType = SL_DATALOCATOR_ANDROIDFD; android_fd.fd = audioFD; android_fd.offset = startByte; android_fd.length = length; //设置音频格式参数 pcm.formatType = SL_DATAFORMAT_PCM; pcm.numChannels = numChannels; pcm.samplesPerSec = sampleRate; pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; pcm.channelMask = channelMask; pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; //创建播放器对象 const SLInterfaceID ids[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PLAY}; const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; (*engine)->CreateAudioPlayer(engine,pPlayerObj, &android_fd, &pcm, 2, ids, req); //realize播放器对象 (*pPlayerObj)->Realize(pPlayerObj,SL_BOOLEAN_FALSE); //获取播放器接口 (*pPlayerObj)->GetInterface(pPlayerObj,SL_IID_PLAY, &pPlayer); //获取缓冲队列接口对象 (*pPlayerObj)->GetInterface(pPlayerObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &pBuffQueue); //注册缓冲队列回调 (*pBuffQueue)->RegisterCallback(pBuffQueue, BufferCallback, NULL); (*pPlayer)->SetPlayState(pPlayer,SL_PLAYSTATE_PLAYING);
2、AudioRecorder录制音频文件
使用OpenSL ES还可以录制音频文件,通过设置输入源、音频格式等参数,可以方便地控制音频数据的采集。下面是一个简单的AudioRecorder的代码示例:
//创建Audio对象 slCreateEngine(&engineObj, 0, NULL, 0, NULL, NULL); //实例化Audio对象 (*engineObj)->Realize(engineObj, SL_BOOLEAN_FALSE); //获取Audio对象的接口 (*engineObj)->GetInterface(engineObj, SL_IID_ENGINE, &engine); //设置音频格式参数 SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; SLDataSource audioSrc = {&loc_dev, NULL}; SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2, 44100, 2, 16, SL_BYTEORDER_LITTLEENDIAN, SL_PCMSAMPLEFORMAT_FIXED_16}; SLDataSink audioSnk = {&loc_bq, &format_pcm}; //创建录音机对象 const SLInterfaceID id[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; const SLboolean req[1] = {SL_BOOLEAN_TRUE}; (*engine)->CreateAudioRecorder(engine, &recorderObj, &audioSrc, &audioSnk, 1, id, req); //Realize录音机对象 (*recorderObj)->Realize(recorderObj, SL_BOOLEAN_FALSE); //获取录音机接口 (*recorderObj)->GetInterface(recorderObj, SL_IID_RECORD, &recorder); //获取录音机BufferQueue接口 (*recorderObj)->GetInterface(recorderObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,&recorderBufferQueue); //设置回调函数 (*recorderBufferQueue)->RegisterCallback(recorderBufferQueue,RecorderCallback, NULL); (*recorder)->SetRecordState(recorder, SL_RECORDSTATE_RECORDING);
3、AudioEffect音效处理
OpenSL ES还提供了多种音效处理接口,如EQualizer、BassBoost、Virtualizer等等。可以使用这些API来对音频进行处理,提高音频的质量。下面是一个简单的音效处理的代码示例:
//创建Audio对象 slCreateEngine(&engineObj, 0, NULL, 0, NULL, NULL); //实例化Audio对象 (*engineObj)->Realize(engineObj, SL_BOOLEAN_FALSE); //获取Audio对象的接口 (*engineObj)->GetInterface(engineObj, SL_IID_ENGINE, &engine); //创建混音器 (*engine)->CreateOutputMix(engine, &outputMixObj, 2, ids, req); //realize混音器对象 (*outputMixObj)->Realize(outputMixObj, SL_BOOLEAN_FALSE); //定义均衡器接口 SLEqualizerItf pEqualizer; //定义均衡器对象 SLObjectItf pEqualizerObj; //定义混音器接口 SLAndroidEffectCapabilitiesItf pEffectDesc; //定义混音器接口 sLAndroidEffectItf pEffect; //定义音效源地址 SLDataLocator_AndroidSimpleBufferQueue loc_bufq; //定义音效格式参数 SLDataFormat_PCM format_pcm; //创建均衡器对象 const SLInterfaceID eq_ids[1] = {SL_IID_EQUALIZER}; const SLboolean eq_req[1] = {SL_BOOLEAN_TRUE}; (*engine)->CreateAudioPlayer(engine,&pEqualizerObj, &loc_bufq, &format_pcm, 1, eq_ids,eq_req); //realize均衡器对象 (*pEqualizerObj)->Realize(pEqualizerObj, SL_BOOLEAN_FALSE); //获取均衡器接口 (*pEqualizerObj)->GetInterface(pEqualizerObj,SL_IID_EQUALIZER,&pEqualizer); //通过均衡器接口进行初始化均衡器对象 (*pEqualizer)->SetEnabled(pEqualizer, SL_BOOLEAN_TRUE);
四、总结
OpenSL ES作为专为多媒体应用开发而设计的音频编程接口,具有低延迟、跨平台、高效性等诸多优点。在Android平台中,OpenSL ES被广泛地应用于音频的播放、录制、处理等多个方面,为移动设备的多媒体应用开发提供了很大的便利。