OpenSL 播放声音

在Android中,使用OpenSL播放声音,在Andriod 2.3或以上版本中使用,需要添加-lOpenSLES 动态库

#include "jni.h"

#include <SLES/OpenSLES.h>
#include "SLES/OpenSLES_Android.h"
#include <sys/types.h>
#include <assert.h>

typedef void (*AudioCallBackAT)(int event, void* user, void *info);
typedef void (*AudioCallBackSL)(SLAndroidSimpleBufferQueueItf bq, void *soundMix);

// engine interfaces
static SLObjectItf gEngineObject = NULL;
static SLEngineItf gEngineEngine;

// output mix interfaces
static SLObjectItf gOutputMixObject = NULL;
static SLEnvironmentalReverbItf gOutputMixEnvironmentalReverb = NULL;

// buffer queue player interfaces
static SLObjectItf        gBQObject = NULL;
static SLPlayItf        gBQPlay = NULL;
static SLVolumeItf        gVolume;
static SLAndroidSimpleBufferQueueItf gBQBufferQueue;
static SLEffectSendItf    gBQEffectSend;

// aux effect on the output mix, used by the buffer queue player
static const SLEnvironmentalReverbSettings gReverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;

// create the engine and output mix objects
extern "C"
void SlesCreateEngine( )
{
    SLresult result;
    // create engine
    result = slCreateEngine(&gEngineObject, 0, NULL, 0, NULL, NULL);
    //assert(SL_RESULT_SUCCESS == result);

    // realize the engine
    result = (*gEngineObject)->Realize(gEngineObject, SL_BOOLEAN_FALSE);
    //assert(SL_RESULT_SUCCESS == result);

    // get the engine interface, which is needed in order to create other objects
    result = (*gEngineObject)->GetInterface(gEngineObject, SL_IID_ENGINE, &gEngineEngine);
    //assert(SL_RESULT_SUCCESS == result);

    // create output mix, with environmental reverb specified as a non-required interface
    const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
    const SLboolean req[1] = {SL_BOOLEAN_FALSE};
    result = (*gEngineEngine)->CreateOutputMix(gEngineEngine, &gOutputMixObject, 1, ids, req);
    //assert(SL_RESULT_SUCCESS == result);

    // realize the output mix
    result = (*gOutputMixObject)->Realize(gOutputMixObject, SL_BOOLEAN_FALSE);
    //assert(SL_RESULT_SUCCESS == 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
    result = (*gOutputMixObject)->GetInterface(gOutputMixObject, SL_IID_ENVIRONMENTALREVERB,
            &gOutputMixEnvironmentalReverb);
    if (SL_RESULT_SUCCESS == result) {
        result = (*gOutputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
                gOutputMixEnvironmentalReverb, &gReverbSettings);
    }
    // ignore unsuccessful result codes for environmental reverb, as it is optional for this example
}

// create buffer queue audio player
extern "C"
void SlesCreateBQPlayer(AudioCallBackSL funCallback, void *soundMix, int rate, int nChannel, int bitsPerSample )
{
    SLresult result;
    // configure audio source
    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
    SLDataFormat_PCM format_pcm;
    format_pcm.formatType = SL_DATAFORMAT_PCM;
    format_pcm.numChannels = nChannel;
    format_pcm.samplesPerSec = rate * 1000; //SL_SAMPLINGRATE_22_05;
    format_pcm.bitsPerSample = bitsPerSample;
    format_pcm.containerSize = 16;
    if( nChannel == 2 )
        format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
    else
        format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
    format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;

    SLDataSource audioSrc = {&loc_bufq, &format_pcm};

    // configure audio sink
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, gOutputMixObject};
    SLDataSink audioSnk = {&loc_outmix, NULL};

    // create audio player
    const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME};
    const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
    result = (*gEngineEngine)->CreateAudioPlayer(gEngineEngine, &gBQObject, &audioSrc, &audioSnk,
            3, ids, req);
    //assert(SL_RESULT_SUCCESS == result);

    // realize the player
    result = (*gBQObject)->Realize(gBQObject, SL_BOOLEAN_FALSE);
    //assert(SL_RESULT_SUCCESS == result);

    // get the play interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_PLAY, &gBQPlay);
    //assert(SL_RESULT_SUCCESS == result);

    // get the buffer queue interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_BUFFERQUEUE,
            &gBQBufferQueue);
    //assert(SL_RESULT_SUCCESS == result);

    // register callback on the buffer queue
    result = (*gBQBufferQueue)->RegisterCallback(gBQBufferQueue, funCallback, soundMix );
    //assert(SL_RESULT_SUCCESS == result);

    // get the effect send interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_EFFECTSEND,
            &gBQEffectSend);
    //assert(SL_RESULT_SUCCESS == result);

    // set the player's state to playing
    result = (*gBQPlay)->SetPlayState(gBQPlay, SL_PLAYSTATE_PLAYING );
    //assert(SL_RESULT_SUCCESS == result);

//    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_VOLUME,  &gVolume);
//    assert(SL_RESULT_SUCCESS == result);
//    result = (*gVolume)->SetMute( gVolume, SL_BOOLEAN_FALSE );
//    assert(SL_RESULT_SUCCESS == result);
}


// shut down the native audio system
extern "C" void SlesShutdown( )
{
    // destroy buffer queue audio player object, and invalidate all associated interfaces
    if (gBQObject != NULL)
    {
        (*gBQObject)->Destroy(gBQObject);
        gBQObject = NULL;
        gBQPlay = NULL;
        gBQBufferQueue = NULL;
        gBQEffectSend = NULL;
    }

    // destroy output mix object, and invalidate all associated interfaces
    if (gOutputMixObject != NULL)
    {
        (*gOutputMixObject)->Destroy(gOutputMixObject);
        gOutputMixObject = NULL;
        gOutputMixEnvironmentalReverb = NULL;
    }

    // destroy engine object, and invalidate all associated interfaces
    if (gEngineObject != NULL)
    {
        (*gEngineObject)->Destroy(gEngineObject);
        gEngineObject = NULL;
        gEngineEngine = NULL;
    }
}

extern "C" void BwAudioCreate(int rate)
{
    SlesCreateEngine( );
}

void BwAudioCreateAT(AudioCallBackAT funCallback, void *soundMix, int rate )
{
}

extern "C"
void BwAudioCreateSL(AudioCallBackSL funCallback, void *soundMix, int rate, int nChannel, int bitsPerSample)
{
    SlesCreateEngine( );
    SlesCreateBQPlayer(funCallback, soundMix, rate, nChannel, bitsPerSample);
    return;
}

extern "C" void BwAudioStart()
{
    (*gBQPlay)->SetPlayState(gBQPlay, SL_PLAYSTATE_PLAYING );
}

extern "C" void BwAudioStop()
{
    (*gBQPlay)->SetPlayState(gBQPlay, SL_PLAYSTATE_PAUSED );
}

extern "C" int BwAudioWrite( const void* buffer, int size)
{
    (*gBQBufferQueue)->Enqueue(gBQBufferQueue, buffer, size );
    return 0;
}

extern "C" void BwAudioDestroy()
{
    SlesShutdown( );
}

extern "C" void BwAudioGetVolume( float* left, float* right)
{
    //SLmillibel level = 0;
    //(*gVolume)->GetVolumeLevel( gVolume, &level );
    //*left = *right = level;
}

extern "C" void BwAudioSetVolume( float left, float right)
{
     //(*gVolume)->SetVolumeLevel( gVolume, right );
}


你可能感兴趣的:(null,buffer,float,interface,audio,output)