调用OpenSL ES NDK播放声音
Android NDK 给出了native-audio的例子,这个例子结合java代码,讲解了如何使用OpenSL播放声音。 我把此例子进行了精简,完全使用c,可以让我们更好的体会到OpenSL的用法,不多说,上代码 main.c: 01.#include <stdio.h> 02.#include <SLES/OpenSLES.h> 03.#include <android/log.h> 04.#include <assert.h> 05.enum _bool { 06. false = 0, 07. true 08.}; 09.typedef enum _bool bool; 10./* engine interface */ 11.static SLObjectItf engineObject = NULL; 12.static SLEngineItf engineEngine; 13./* output mix interfaces */ 14.static SLObjectItf outputMixObject = NULL; 15.static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL; 16./* aux effect on the output mix */ 17.static const SLEnvironmentalReverbSettings reverbSettings = 18. SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR; 19./* uri player interfaces */ 20.static SLObjectItf uriPlayerObject = NULL; 21.static SLPlayItf uriPlayerPlay; 22.static SLSeekItf uriPlayerSeek; 23.void createEngine() 24.{ 25. SLresult result; 26. // create engine 27. result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 28. assert(SL_RESULT_SUCCESS == result); 29. // realize the engine 30. result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 31. assert(SL_RESULT_SUCCESS == result); 32. // get the engine interface 33. result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 34. assert(SL_RESULT_SUCCESS === result); 35. // create output mix 36. const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB}; 37. const SLboolean req[1] = {SL_BOOLEAN_FALSE}; 38. result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req); 39. assert(SL_RESULT_SUCCESS == result); 40. // realize the output mix 41. result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 42. assert(SL_RESULT_SUCCESS == result); 43.#if 0 44. // get the environmental reverb interface 45. result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB, 46. &outputMixEnvironmentalReverb); 47. if (SL_RESULT_SUCCESS == result) { 48. result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(outputMixEnvironmentalReverb, &reverbSettings); 49. } 50.#endif 51. // ignore unsuccessful result codes for env reverb 52.} 53.bool createUriAudioPlayer(char* uri) 54.{ 55. SLresult result; 56. // config audio source 57. SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, (SLchar *) uri}; 58. SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 59. SLDataSource audioSrc = {&loc_uri, &format_mime}; 60. // config audio sink 61. SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; 62. SLDataSink audioSnk = {&loc_outmix, NULL}; 63. // create audio player 64. const SLInterfaceID ids[1] = {SL_IID_SEEK}; 65. const SLboolean req[1] = {SL_BOOLEAN_TRUE}; 66. result = (*engineEngine)->CreateAudioPlayer(engineEngine, &uriPlayerObject, &audioSrc, &audioSnk, 1, ids, req); 67. assert(SL_RESULT_SUCCESS == result); 68. // realize the player 69. result = (*uriPlayerObject)->Realize(uriPlayerObject, SL_BOOLEAN_FALSE); 70. if (SL_RESULT_SUCCESS != result) { 71. (*uriPlayerObject)->Destroy(uriPlayerObject); 72. uriPlayerObject = NULL; 73. return false; 74. } 75. // get the play interface 76. result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAY, &uriPlayerPlay); 77. assert(SL_RESULT_SUCCESS == result); 78. // get the seek interface 79. result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_SEEK, &uriPlayerSeek); 80. assert(SL_RESULT_SUCCESS == result); 81. // enable whole file looping 82. result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN); 83. assert(SL_RESULT_SUCCESS == result); 84. return true; 85.} 86.setPlayingUriAudioPlayer(bool played) 87.{ 88. SLresult result; 89. if (uriPlayerPlay != NULL) { 90. result = (*uriPlayerPlay)->SetPlayState(uriPlayerPlay, played ? 91. SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED); 92. assert(SL_RESULT_SUCCESS == result); 93. } 94.} 95.int main(int argc, char** argv) 96.{ 97. // Create the OpenSL engine 98. createEngine(); 99. // Create the audio player with everything ready. 100. createUriAudioPlayer(argv[1]); 101. printf("Playing..."); 102. setPlayingUriAudioPlayer(true); // play the music 103. sleep(20); 104. printf("Pause..."); 105. setPlayingUriAudioPlayer(false); // pause the player 106. sleep(20); 107. 108. printf("Playing..."); 109. setPlayingUriAudioPlayer(true); 110. 111. sleep(1000); // Just wait for the playing threads 112.} 复制代码 Android.mk文件内容: 01.LOCAL_PATH := $(call my-dir) 02.include $(CLEAR_VARS) 03.LOCAL_MODULE := audio-test 04.LOCAL_SRC_FILES := main.c 05.LOCAL_LDLIBS += -lOpenSLES -llog 06.include $(BUILD_EXECUTABLE) 复制代码 Application.mk文件里面需要指定android平台为9 01.APP_PLATFORM := android-9 复制代码 保存这3个文件,然后ndk-build就可以生成一个名为audio-test的可执行文件,拷贝这个文件到android 2.3的模拟器或者手机,我们这里将audio-test拷贝到/data/目录下面, 然后任意拷贝一首歌曲到模拟器或者手机,比如我们拷贝一手歌曲到/data/test.mp3,然后就可以使用audio-test来播放这个音乐了 使用adb shell登录手机或者模拟器,在终端里面执行如下命令(路径如果不同,你需要做相应修改): 01./data/audio-test /data/test.mp3 复制代码 然后就可以听到音乐了,过20秒会暂停20秒,然后一直播放,直到sleep的1000秒结束。
================================
http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=3631163