//创建OpenSLES引擎extern"C"void createEngine() {
SLresult result;
//创建引擎
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//关联引擎
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//获取引擎接口, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//创建输出混音器, with environmental reverb specified as a non-required interfaceconst SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
const SLboolean req[1] = {SL_BOOLEAN_FALSE};
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//关联输出混音器
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// get the environmental reverb interface// this could fail if the environmental reverb effect is not available,// either because the feature is not present, excessive CPU load, or// the required MODIFY_AUDIO_SETTINGS permission was not requested and granted//获取reverb接口
result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb);
if (SL_RESULT_SUCCESS == result) {
result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
outputMixEnvironmentalReverb, &reverbSettings);
(void) result;
}
// ignore unsuccessful result codes for environmental reverb, as it is optional for this example
}
创建缓存队列和opensl播放器
// create buffer queue audio playerextern"C"void createBufferQueueAudioPlayer(int sampleRate, int channel) {
SLresult result;
if (sampleRate >= 0) {
bqPlayerSampleRate = sampleRate * 1000;
}
//配置音频源
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
if (bqPlayerSampleRate) {
format_pcm.samplesPerSec = bqPlayerSampleRate; //sample rate in mili second
}
format_pcm.numChannels = (SLuint32) channel;
if (channel == 2) {
format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
} else {
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
}
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
//配置音频池
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
/*
* create audio player:
* fast audio does not support when SL_IID_EFFECTSEND is required, skip it
* for fast audio case
*/const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME, SL_IID_EFFECTSEND,
/*SL_IID_MUTESOLO,*/};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
/*SL_BOOLEAN_TRUE,*/ };
//创建音频播放器
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
bqPlayerSampleRate ? 2 : 3, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 关联播放器
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 获取播放接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 获取缓冲队列接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 注册缓冲队列回调
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 获取音效接口
bqPlayerEffectSend = NULL;
if (0 == bqPlayerSampleRate) {
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,
&bqPlayerEffectSend);
assert(SL_RESULT_SUCCESS == result);
(void) result;
}
#if 0 // mute/solo is not supported for sources that are known to be mono, as this is// get the mute/solo interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
(void)result;
#endif// 获取音量接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//注册事件回调
result = (*bqPlayerPlay)->RegisterCallback(bqPlayerPlay, playOverEvent, NULL);
assert(SL_RESULT_SUCCESS == result);
(void) result;
//设置播放结束回调
result = (*bqPlayerPlay)->SetCallbackEventsMask(bqPlayerPlay, SL_PLAYEVENT_HEADATEND);
assert(SL_RESULT_SUCCESS == result);
(void) result;
// 开始播放音乐
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
assert(SL_RESULT_SUCCESS == result);
(void) result;
}
实现数据回调方法
void releaseResampleBuf(void) {
if (0 == bqPlayerSampleRate) {
/*
* we are not using fast path, so we were not creating buffers, nothing to do
*/return;
}
free(resampleBuf);
resampleBuf = NULL;
}
// this callback handler is called every time a buffer finishes playingextern"C"void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
assert(bq == bqPlayerBufferQueue);
assert(NULL == context);
// for streaming playback, replace this test by logic to find and fill the next bufferif (getPCM() < 0) {//解码音频文件
pthread_mutex_unlock(&audioEngineLock);
return;
}
if (NULL != nextBuffer && 0 != nextSize) {
SLresult result;
// enqueue another buffer
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,// which for this code example would indicate a programming errorif (SL_RESULT_SUCCESS != result) {
pthread_mutex_unlock(&audioEngineLock);
}
(void) result;
} else {
releaseResampleBuf();
pthread_mutex_unlock(&audioEngineLock);
}
}