Android万能音频播放器04--OpenSL ES实现音频播放

在OPenSL ES的回调函数中获取音频的PCM数据和大小,并播放。

int buffersize = wlAudio->resampleAudio();
if(buffersize > 0)
{
      (* wlAudio-> pcmBufferQueue)->Enqueue(
    wlAudio-> pcmBufferQueue, 
    (char *) wlAudio-> buffer, 
    buffersize);
}

在CmakeLists.txt中添加OpenSL ES的库,然后初始化OpenSL ES,

void JfAudio::initOpenSLES() {
    // 1、创建一个引擎:三部曲 slCreateEngine->Realize->GetInterface
    slCreateEngine(&engineObject,0,0,0,0,0);
    (*engineObject)->Realize(engineObject,SL_BOOLEAN_FALSE);
    (*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineEngine);


    // 2、设置混音器:创建混音器引擎->设置混音器属性
    const SLInterfaceID mids[1] = {SL_IID_ENVIRONMENTALREVERB};
    const SLboolean mrep[1] = {SL_BOOLEAN_FALSE};

    (*engineEngine)->CreateOutputMix(engineEngine,&outputMixObject,1,mids,mrep);
    (*outputMixObject)->Realize(outputMixObject,SL_BOOLEAN_FALSE);
    (*outputMixObject)->GetInterface(outputMixObject,SL_IID_ENVIRONMENTALREVERB,&outputMixEnvReb);

    (*outputMixEnvReb)->SetEnvironmentalReverbProperties(outputMixEnvReb,&reverbSettings);


    // 3、创建播放器
    SLDataLocator_AndroidSimpleBufferQueue android_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,2};//一个队列
    SLDataFormat_PCM format_pcm = {//设置PCM播放时的属性
            SL_DATAFORMAT_PCM,
            2,
            SL_SAMPLINGRATE_44_1,
            SL_PCMSAMPLEFORMAT_FIXED_16,
            SL_PCMSAMPLEFORMAT_FIXED_16,
            SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
            SL_BYTEORDER_LITTLEENDIAN
    };
    SLDataSource slDataSource ={&android_queue,&format_pcm};

    SLDataLocator_OutputMix outputMix = {SL_DATALOCATOR_OUTPUTMIX,outputMixObject};
    SLDataSink audioSink = {&outputMix,NULL};

    const SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE};
    const SLboolean req[1] = {SL_BOOLEAN_TRUE};
    (*engineEngine)->CreateAudioPlayer(engineEngine,&pcmPlayerObject,&slDataSource,&audioSink,1,ids,req);
    (*pcmPlayerObject)->Realize(pcmPlayerObject,SL_BOOLEAN_FALSE);
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject,SL_IID_PLAY,&pcmPlayerPlay);


    //4、设置缓冲队列和回调函数
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject,SL_IID_BUFFERQUEUE,&pcmBufferQueue);
    (*pcmBufferQueue)->RegisterCallback(pcmBufferQueue,pcmBufferCallback,this);


    //5、设置播放状态
    (*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay,SL_PLAYSTATE_PLAYING);

    pcmBufferCallback(pcmBufferQueue,this);
}

在回调方法中取出pcm数据播放

void pcmBufferCallback(SLAndroidSimpleBufferQueueItf bf,void *context){
    //获取pcm数据
    JfAudio *jfAudio = (JfAudio *)context;
    if (jfAudio != NULL){
        int buffer_size = jfAudio->resampleAudio();
        if (buffer_size > 0){
            (*jfAudio->pcmBufferQueue)->Enqueue(jfAudio->pcmBufferQueue,jfAudio->buffer,buffer_size);
        }
    } else {
        if (LOG_DEBUG){
            LOGE("jfAudio == NULL");
        }
    }
}

源码地址:openSLESPlayPcm分支

你可能感兴趣的:(Android万能音频播放器04--OpenSL ES实现音频播放)