Android音频开发之OpenSL ES

7 篇文章 0 订阅
4 篇文章 0 订阅
关于OpenSL ES

OpenSL ES 全称是Open Sound Library for Embedded Systems , 即嵌入式音频加速标准。OpenSL ES 是开源免费、跨平台、针对嵌入式系统优化的硬件音频加速API。它为开发者提供了标准化、高性能、低响应时间的音频功能实现方法。

在使用OpenSL ES前,需要对OpenSL ES中的对象和接口的概念有一定的了解。
  1. 对象:对象是对一组资源及其状态的抽象,每个对象都有一个在其创建时指定的类型,类型决定了对象可以执行的任务集,对象有点类似于C++中类的概念。
  2. 接口:接口是对象提供的一组特征的抽象,这些抽象会为开发者提供一组方法以及每个接口的类型功能,在代码中,接口的类型由接口ID来标识。

简单来说就是,对象在代码中是没有实际的表示形式的,对象的创建也是通过接口来完成的。通过获取对象的方法来获取对象,进而可以使用对象的方法和属性,使用步骤如下:
以创建引擎为例,分为三步create -> realize -> get

  1. 创建一个引擎对象接口slCreateEngine(&engineObject,0,NULL,0,NULL,NULL);
  2. 实例化引擎对象(*engineObject)->Realize(engineObject,SL_BOOLEAN_FALSE);
  3. 获取这个引擎对象的方法接口(*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineEngine);
下面使用OpenSL ES来播放PCM数据

使用流程如下图:
在这里插入图片描述

代码实现

1.创建接口对象,即引擎对象

    //创建接口对象,即引擎对象
    //Create engine
    slCreateEngine(&engineObject,0,NULL,0,NULL,NULL);

    //realize the engine
    (*engineObject)->Realize(engineObject,SL_BOOLEAN_FALSE);

    //get the engine interface ,which is needed in order to create other objects
    (*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineEngine);

2.设置混音器

    //c创建混音器
    //create output mix, with environmental reverb specified as a non-required interface
    const SLInterfaceID  ids[1] = {SL_IID_ENVIRONMENTALREVERB};
    const SLboolean req[1] = {SL_BOOLEAN_FALSE};
    (*engineEngine)->CreateOutputMix(engineEngine,&outputMixObject,1,ids,req);

    //realize the output mix
    (*outputMixObject)->Realize(outputMixObject,SL_BOOLEAN_FALSE);
    //get the environmental reverb interface
    // this could fail if the environmental reverb effect is not available,
    // either because the feature is not present, excessive CPU load, or
    // the required MODIFY_AUDIO_SETTINGS permission was not requested and granted
    SLresult lresult =(*outputMixObject)->GetInterface(outputMixObject,SL_IID_ENVIRONMENTALREVERB,&outputMixEnvironmentalReverb);
    if(SL_RESULT_SUCCESS == lresult) {
        (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
                outputMixEnvironmentalReverb,&reverbSettings);
    }

3.创建播放器或录音器

     //创建播放器(录音器)
    //create buffer queue audio player

    //configure audio source
    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,2};
    SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2,
                                   (SLuint32) getCurSampleRateForOpenSLES(pCodecParam != NULL ? pCodecParam->sample_rate : 0),
                                   SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
                                   SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN};

    SLDataSource audioSrc = {&loc_bufq,&format_pcm};
    //configure audio sink
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX,outputMixObject};
    SLDataSink audioSnk = {&loc_outmix,NULL};

    const SLInterfaceID ids1[4] = {SL_IID_BUFFERQUEUE,SL_IID_VOLUME,SL_IID_PLAYBACKRATE,SL_IID_MUTESOLO};
    const SLboolean  req1[4] = {SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE};
    (*engineEngine)->CreateAudioPlayer(engineEngine,&bqPlayerObject,&audioSrc,&audioSnk,
                                       4,ids1,req1);

    //realize the player
    (*bqPlayerObject)->Realize(bqPlayerObject,SL_BOOLEAN_FALSE);

    //get the play interface
    (*bqPlayerObject)->GetInterface(bqPlayerObject,SL_IID_PLAY,&bqPlayerPlay);

4.设置缓冲队列和回调函数

    //创建缓冲队列和回调函数
    //get the buffer queque interface
    (*bqPlayerObject)->GetInterface(bqPlayerObject,SL_IID_BUFFERQUEUE,&bqPlayerBufferQueue);

    //register callback on the buffer queue
    (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue,bqPlayerCallback,this);

回调函数

//this callback handler is called every time a buffer finishes playing
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context) {
    int size = getPcmData(&buffer);
    SLresult result;
    // enqueue another buffer
    result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, 44100 * 2 * 2);
}

5.设置播放状态

    //设置播放状态
    //set the player's state to playing
    (*bqPlayerPlay)->SetPlayState(bqPlayerPlay,SL_PLAYSTATE_PLAYING);

6.调用回调函数,开始播放

    //StartPlay
    bqPlayerCallback(bqPlayerBufferQueue,NULL);
完整代码如下:

https://github.com/Huzhuwei1/MusicPlayer.git
https://download.csdn.net/download/memory_of_the_wind/10803709

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值