#include<jni.h>
#include<string>
#include<SLES/OpenSLES.h>
#include<SLES/OpenSLES_Android.h>
#include"AndroidLog.h"
SLObjectItf engineObject = NULL;
SLEngineItf engineEngin = NULL;
SLObjectItf outputMixObject =NULL;
SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
SLObjectItf pcmPlayObject = NULL;
SLPlayItf pclPlayerPlay = NULL;
SLAndroidSimpleBufferQueueItf pcmBufferQueue;
FILE *pcmFile;
void *buffer;
uint8_t *out_buffer;
int getPcmData(void **pcm){
int size=0;
while(!feof(pcmFile)){//是否讀到結尾
size=fread(out_buffer,1,44100*2*2,pcmFile);
if(out_buffer==NULL){
LOGD("%s","讀取結束");
break;//讀取完畢
}else{
LOGD("%s","讀取ing");
}
*pcm=out_buffer;
break;
}
return size;
}
void pcmBufferCallBack(SLAndroidSimpleBufferQueueItf bf,void *context){
int size = getPcmData(&buffer);
if(buffer!=NULL){
(*pcmBufferQueue)->Enqueue(pcmBufferQueue,buffer,size);
}
}
extern"C"
JNIEXPORT void JNICALL
Java_com_qy_ffmpeg_102_MainActivity_playpcm(JNIEnv *env,jobject instance,jstring url_){
const char *url = env->GetStringUTFChars(url_ , 0);
pcmFile=fopen(url,"r");//打開文件
if(pcmFile==NULL){
return;
}
//讀一秒鐘的數據
out_buffer=(uint8_t*)malloc(44100*2*2);
SLresult result;
//1創建引擎接口(參數:)
result=slCreateEngine(&engineObject,0,NULL,0,NULL,NULL);
//判斷是否成功
assert(SL_RESULT_SUCCESS==result);
(void)result;
//2實例化引擎
result=(*engineObject)->Realize(engineObject,SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//3獲取引擎接口(其他對象需要這個),
result=(*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineEngin);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//4創建混音器
const SLInterfaceID mids[1]={SL_IID_ENVIRONMENTALREVERB};
const SLboolean mreq[1]={SL_BOOLEAN_FALSE};
result=(*engineEngin)->CreateOutputMix(engineEngin,&outputMixObject,1,mids,mreq);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//實現輸出組合
result=(*outputMixObject)->Realize(outputMixObject,SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//獲得環境混響接口
result=(*outputMixObject)->GetInterface(outputMixObject,SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb);
////獲取環境混響界面
///如果環境混響效果不可用,則可能會失敗,
//原因是該功能不存在,CPU負載過大或未請求並授予所需的MODIFY_AUDIO_SETTINGS權限
if(SL_RESULT_SUCCESS==result){
result=(*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
outputMixEnvironmentalReverb,&reverbSettings);
(void)result;
}
//5創建緩衝隊列(配置音頻源)
SLDataLocator_AndroidBufferQueue android_queue={SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE , 2};
//設置要播放的pcm格式的內容
SLDataFormat_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//塊的字節順序從16--32位
};
//配置音頻接收器
SLDataLocator_OutputMix outputMix={SL_DATALOCATOR_OUTPUTMIX,outputMixObject};
SLDataSource slDataSource={&android_queue,&pcm};
SLDataSink audioSnk={&outputMix,NULL,};
//創建音頻播放器:
const SLInterfaceIDids[2]={SL_IID_BUFFERQUEUE};
const SLbooleanreq[2]={SL_BOOLEAN_TRUE};
result=(*engineEngin)->CreateAudioPlayer(engineEngin,&pcmPlayObject,&slDataSource,&audioSnk,1,ids,req);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//實例化播放器
result=(*pcmPlayObject)->Realize(pcmPlayObject,SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//得到播放接口
result=(*pcmPlayObject)->GetInterface(pcmPlayObject,SL_IID_PLAY,&pclPlayerPlay);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//設置緩衝
result=(*pcmPlayObject)->GetInterface(pcmPlayObject,SL_IID_BUFFERQUEUE,&pcmBufferQueue);
assert(SL_RESULT_SUCCESS==result);
(void)result;
//設置回調
(*pcmBufferQueue)->RegisterCallback(pcmBufferQueue,pcmBufferCallBack,NULL);
//設置播放狀態
(*pclPlayerPlay)->SetPlayState(pclPlayerPlay,SL_PLAYSTATE_PLAYING);
//
pcmBufferCallBack(pcmBufferQueue,NULL);
//========
env->ReleaseStringUTFChars(url_,url);
}
|