http://tieba.baidu.com/p/2661564 ... p;cid=0#81086592640*/
#include
//#include
#include
#include
static SLObjectItf _aud=NULL;/* 声音引擎对象 */
static SLEngineItf _aud_eng;/* 声音引擎 */
static SLObjectItf _aud_mix=NULL;/* 输出混音器对象 */
static SLObjectItf _aud_plyobj=NULL; /*播放器对象 */
static SLPlayItf _aud_ply; /* 播放介面(播放,暂停...) */
//static SLAndroidSimpleBufferQueueItf _aud_buf;/*缓冲区介面 */
static SLBufferQueueItf _aud_buf;
static SLEffectSendItf _aud_bufefx; /*音效介面,在本播放器中将用于缓冲区 */
static SLVolumeItf _aud_vol; /*音量介面 */
static short *snd; /* 16 bit, 8kHz单声道 pcm 声音采样 */
static unsigned sndlen; /*声音采样数据的大小*/
static int num_snd=5; /* 该采样的剩余播放的次数 */
#define M_PI 3.1415926536
#include "math.h"
static short snd_sin[8000]; /* 时长为1秒的 16bit 单声道 正弦波采样 */
void create_sine_wave(void)
{
unsigned i;
for (i = 0; i < 8000; ++i) /* 声音时长1秒,所以我们创建8000个单声道 采样 */
snd_sin= sinf(i*180/M_PI)*32767; /* 通过正弦函数创建单个采样值 */
}
/* _newsnd_cb: 我们自己创建的缓冲区队列播放回调函数,第一项填写目标缓冲区介面,第二项填NULL即可 */
void _newsnd_cb(SLBufferQueueItf bq, void *context)
{
assert(bq == _aud_buf);
assert(NULL == context);
if (--num_snd > 0 && NULL != snd && 0 != sndlen > 0) /* 如果采样的剩余播放的次数大于0,声音数据有效,而且 声音数据的长度大于0 */
{
SLresult result;
result = (*bq)->Enqueue(bq, snd, sndlen); /* 操作缓冲区队列介面,将长度为 sndlen的声音数据snd排进队列 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
}
}
/* audio_init: 初始化opensl es */
void audio_init ()
{
SLresult result;
result = slCreateEngine(&_aud, 0, NULL, 0, NULL, NULL);/* 创建声音引擎对象 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud)->Realize(_aud, SL_BOOLEAN_FALSE);/* 实现声音引擎对象 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud)->GetInterface(_aud, SL_IID_ENGINE, &_aud_eng);/* 从声音引擎对象中抓取声音引擎 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
const SLInterfaceID effect[1] = {SL_IID_ENVIRONMENTALREVERB}; /* 音效 */
const SLboolean effect_bool[1] = {SL_BOOLEAN_FALSE}; /*音效强制实现逻辑 */
result = (*_aud_eng)->CreateOutputMix(_aud_eng, &_aud_mix, 1, effect, effect_bool);/* 通过声音引擎创建输出混音器对象,并且非强制性的开启环境混响效果 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud_mix)->Realize(_aud_mix, SL_BOOLEAN_FALSE);/* 实现混音器对象 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
}
void createPlayer()
{
SLresult result;
// configure audio source
SLDataLocator_BufferQueue loc_bufq = {SL_DATALOCATOR_BUFFERQUEUE,2};
/* 缓冲区队列定位器 */ /* 必须填成这样,表示数据定位器将定位缓冲区队列 *//* 缓冲队列里的缓冲数目,这里我们填写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};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, _aud_mix};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND,
/*SL_IID_MUTESOLO,*/ SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
/*SL_BOOLEAN_TRUE,*/ SL_BOOLEAN_TRUE};
result = (*_aud_eng)->CreateAudioPlayer(_aud_eng, &_aud_plyobj, &audioSrc, &audioSnk,
3, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud_plyobj)->Realize(_aud_plyobj, SL_BOOLEAN_FALSE); /*实现声音播放器对象 */
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud_plyobj)->GetInterface(_aud_plyobj, SL_IID_PLAY, &_aud_ply); /*获得播放介面, 存至_aud_ply*/
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud_plyobj)->GetInterface(_aud_plyobj, SL_IID_BUFFERQUEUE, &_aud_buf); /*获得缓冲区介面,存至 _aud_buf */
assert(SL_RESULT_SUCCESS == result);
(void)result;
/*result = (*_aud_buf)->RegisterCallback(_aud_buf, _newsnd_cb, NULL);
assert(SL_RESULT_SUCCESS == result);
(void)result;*/
result = (*_aud_plyobj)->GetInterface(_aud_plyobj, SL_IID_EFFECTSEND, &_aud_bufefx); /*获得音效介面,存至 _aud_bufefx */
assert(SL_RESULT_SUCCESS == result);
(void)result;
result = (*_aud_plyobj)->GetInterface(_aud_plyobj, SL_IID_VOLUME, &_aud_vol); /*获得音量介面,存至 _aud_vol */
assert(SL_RESULT_SUCCESS == result);
(void)result;
/*result = (*_aud_ply)->SetPlayState(_aud_ply, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
(void)result;*/
}
int main()
{
create_sine_wave();
audio_init();
createPlayer();
snd=snd_sin;
sndlen=sizeof(snd_sin);
SLresult result;
result =(*_aud_buf)->Enqueue(_aud_buf, snd,sndlen);
_newsnd_cb( _aud_buf, NULL);
result =(*_aud_buf)->RegisterCallback(_aud_buf, _newsnd_cb, NULL);
result =(*_aud_ply)->SetPlayState(_aud_ply, SL_PLAYSTATE_PLAYING);
//printf("ok");
}