OpenSL的代码编写

#include <jni.h>
#include <string>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>

static SLObjectItf engineItf = NULL;
SLEngineItf createSL()
{
SLresult lresult;
SLEngineItf en;
lresult = slCreateEngine(&engineItf, 0, 0, 0, 0, 0);
if(lresult != SL_RESULT_SUCCESS)return NULL;
lresult = (*engineItf)->Realize(engineItf , SL_BOOLEAN_FALSE);
if(lresult != SL_RESULT_SUCCESS)return NULL;
lresult = (*engineItf)->GetInterface(engineItf , SL_IID_ENGINE , &en);
if(lresult != SL_RESULT_SUCCESS)return NULL;
return en;
}

void PcmCall(SLAndroidSimpleBufferQueueItf bf , void *context)
{
static FILE *file = NULL;
static char *buf = NULL;
if(!buf)
{
buf = new char[1024 * 1024];
}
if(!file)
{
file = fopen("/sdcard/shape.pcm" , "rb");
}
if(!file) return;

if(feof(file) == 0)
{
int len = fread(buf , 1,1024 ,file);
if(len>0)
{
(*bf)->Enqueue(bf , buf , len);
}

}
}
extern "C" JNIEXPORT jstring

JNICALL
Java_com_example_shang_opensl_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";

//1.创建引擎
SLEngineItf eng = createSL();



//2.创建混音器
SLObjectItf mix = NULL;
(*eng)->CreateOutputMix(eng , &mix ,0 ,0 ,0);
//实例化mix
(*mix)->Realize(mix , SL_BOOLEAN_FALSE);

SLDataLocator_OutputMix outMix = {SL_DATALOCATOR_OUTPUTMIX , mix};
SLDataSink audioSink = {&outMix , 0};




//配置音频信息
//缓冲格式
SLDataLocator_AndroidSimpleBufferQueue queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
, 10};
//音频格式
SLDataFormat_PCM pcm = {
SL_DATAFORMAT_PCM,
2,
SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_BACK_LEFT , //SL_SPEAKER_BACK_RIGHT,
SL_BYTEORDER_LITTLEENDIAN //字节序,小断------还有大段

};

SLDataSource ds = {&queue , &pcm};



//创建播放器
SLObjectItf player = NULL;
SLPlayItf iplayer = NULL ;
const SLInterfaceID id[] = {SL_IID_BUFFERQUEUE};
const SLboolean req[] = {SL_BOOLEAN_TRUE};
(*eng)->CreateAudioPlayer(eng, &player, &ds, &audioSink, sizeof(id)/ sizeof(SLInterfaceID) , id , req); //如果只用player接口就不用传其他
//实例化播放器 //参数,因为调用到内部类的接口,
(*player)->Realize(player ,SL_BOOLEAN_FALSE); //所以必须传入其他参数
//获取接口
(*player)->GetInterface(player, SL_IID_PLAY, &iplayer);


//获取队列的接口
SLAndroidSimpleBufferQueueItf pcmQue = NULL;
(*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &pcmQue);

//设置回调函数
(*pcmQue)->RegisterCallback(pcmQue, PcmCall, 0);

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

//启动队列回调
(*pcmQue)->Enqueue(pcmQue , "",1);

return env->NewStringUTF(hello.c_str());
}

猜你喜欢

转载自www.cnblogs.com/liunx1109/p/9281766.html