完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Android NDK r5给出了native-audio的例子,这个例子结合java代码,讲解了如何使用OpenSL播放声音。
我把此例子进行了精简,完全使用c,可以让我们更好的体会到OpenSL的用法,不多说,上代码 main.c:
Android.mk文件内容:
Application.mk文件里面需要指定android平台为9
保存这3个文件,然后ndk-build就可以生成一个名为audio-test的可执行文件,拷贝这个文件到android 2.3的模拟器或者手机,我们这里将audio-test拷贝到/data/目录下面, 然后任意拷贝一首歌曲到模拟器或者手机,比如我们拷贝一手歌曲到/data/test.mp3,然后就可以使用audio-test来播放这个音乐了 使用adb shell登录手机或者模拟器,在终端里面执行如下命令(路径如果不同,你需要做相应修改):
然后就可以听到音乐了,过20秒会暂停20秒,然后一直播放,直到sleep的1000秒结束。 作者: Aries @ 米狗族 地址: http://www.meegozu.com/thread-2107-1-1.html |
|
相关推荐
5 个讨论
|
|
/*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"); } |
|
|
|
|
|
/*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"); } |
|
|
|
|
|
/*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"); } |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
11828 浏览 2 评论
4265 浏览 3 评论
3448 浏览 5 评论
8453 浏览 47 评论
4014 浏览 9 评论
432浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-3-29 23:21 , Processed in 0.587541 second(s), Total 55, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 深圳华秋电子有限公司
电子发烧友 (电路图) 粤公网安备 44030402000349 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号