• 调用OpenSL ES NDK播放声音


    调用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

    http://blog.csdn.net/hgl868/article/details/7534841

    http://www.dssz.com/603896.html

  • 相关阅读:
    Quartz快速入门 (转自 http://www.blogjava.net/baoyaer/articles/155645.html)
    C#HTML 转文本及HTML内容提取
    创建连接字符串方法
    源生js _AJax
    .NET里面附件上传大小限制的控制
    错误记录 COM
    Quartz的cron表达式
    Quartz 多任务调用
    Myeclipse的web工程和Eclipse互相转换
    Myeclipse8.0序列号生成程序
  • 原文地址:https://www.cnblogs.com/wainiwann/p/2984307.html
Copyright © 2020-2023  润新知