您的位置:

OpenSL ES在多媒体应用开发中的应用

一、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被广泛地应用于音频的播放、录制、处理等多个方面,为移动设备的多媒体应用开发提供了很大的便利。