zoukankan      html  css  js  c++  java
  • 使用opensl 的BufferQueueAudioPlayer对wav文件的播放

    创建音频引擎之后,读取wav文件到内存,然后使用BufferQueueAudioPlayer进行播放。

    这里在读取wav文件的时候需要对wav文件的前44个类似头信息进行解析,然后在进行播放的时候,在创建BufferQueueAudioPlayer的时候需要配置音源的时候需要用到,要不然是不能正常播放wav文件的。

     SLDataFormat_PCM format_pcm = {
         SL_DATAFORMAT_PCM,                    //数据格式定义
         1, 
         SL_SAMPLINGRATE_8,                    //采样率(hz)
            SL_PCMSAMPLEFORMAT_FIXED_16,    //采样格式
            SL_PCMSAMPLEFORMAT_FIXED_16,    //
            SL_SPEAKER_FRONT_CENTER,        //声道相关
            SL_BYTEORDER_LITTLEENDIAN        //块的字节顺序 从16--32位
     };

    其中数据格式定义可选:

    #define SL_DATAFORMAT_MIME        ((SLuint32) 0x00000001)
    #define SL_DATAFORMAT_PCM        ((SLuint32) 0x00000002)
    #define SL_DATAFORMAT_RESERVED3    ((SLuint32) 0x00000003)
    #define SL_DATAFORMAT_PCM_EX    ((SLuint32) 0x00000004)

    这里重点是采样率,如果设置的采用率与读取的wav文件内的采用率不同的话,声音是不能正常播放的,下面是sl提供的采用率:

    #define SL_SAMPLINGRATE_8          ((SLuint32) 8000000)
    #define SL_SAMPLINGRATE_11_025     ((SLuint32) 11025000)
    #define SL_SAMPLINGRATE_12         ((SLuint32) 12000000)
    #define SL_SAMPLINGRATE_16         ((SLuint32) 16000000)
    #define SL_SAMPLINGRATE_22_05      ((SLuint32) 22050000)
    #define SL_SAMPLINGRATE_24         ((SLuint32) 24000000)
    #define SL_SAMPLINGRATE_32         ((SLuint32) 32000000)
    #define SL_SAMPLINGRATE_44_1       ((SLuint32) 44100000)
    #define SL_SAMPLINGRATE_48         ((SLuint32) 48000000)
    #define SL_SAMPLINGRATE_64         ((SLuint32) 64000000)
    #define SL_SAMPLINGRATE_88_2       ((SLuint32) 88200000)
    #define SL_SAMPLINGRATE_96         ((SLuint32) 96000000)
    #define SL_SAMPLINGRATE_192        ((SLuint32) 192000000)

    虽然sl支持的采样率很多,但通常用到的也就是 8000000 和 44100000 这两个。

    第四个参数是采样格式,sl列举下面几个:

    #define SL_PCMSAMPLEFORMAT_FIXED_8     ((SLuint16) 0x0008)
    #define SL_PCMSAMPLEFORMAT_FIXED_16    ((SLuint16) 0x0010)
    #define SL_PCMSAMPLEFORMAT_FIXED_20    ((SLuint16) 0x0014)
    #define SL_PCMSAMPLEFORMAT_FIXED_24    ((SLuint16) 0x0018)
    #define SL_PCMSAMPLEFORMAT_FIXED_28    ((SLuint16) 0x001C)
    #define SL_PCMSAMPLEFORMAT_FIXED_32    ((SLuint16) 0x0020)
    #define SL_PCMSAMPLEFORMAT_FIXED_64    ((SLuint16) 0x0040)

    第五个参数同上。

    第六个参数,应该属于声道相关的,研究的很浅,sl给列举的也不少:

    #define SL_SPEAKER_FRONT_LEFT                  ((SLuint32) 0x00000001)
    #define SL_SPEAKER_FRONT_RIGHT                 ((SLuint32) 0x00000002)
    #define SL_SPEAKER_FRONT_CENTER                ((SLuint32) 0x00000004)
    #define SL_SPEAKER_LOW_FREQUENCY               ((SLuint32) 0x00000008)
    #define SL_SPEAKER_BACK_LEFT                   ((SLuint32) 0x00000010)
    #define SL_SPEAKER_BACK_RIGHT                  ((SLuint32) 0x00000020)
    #define SL_SPEAKER_FRONT_LEFT_OF_CENTER        ((SLuint32) 0x00000040)
    #define SL_SPEAKER_FRONT_RIGHT_OF_CENTER       ((SLuint32) 0x00000080)
    #define SL_SPEAKER_BACK_CENTER                 ((SLuint32) 0x00000100)
    #define SL_SPEAKER_SIDE_LEFT                   ((SLuint32) 0x00000200)
    #define SL_SPEAKER_SIDE_RIGHT                  ((SLuint32) 0x00000400)
    #define SL_SPEAKER_TOP_CENTER                  ((SLuint32) 0x00000800)
    #define SL_SPEAKER_TOP_FRONT_LEFT              ((SLuint32) 0x00001000)
    #define SL_SPEAKER_TOP_FRONT_CENTER            ((SLuint32) 0x00002000)
    #define SL_SPEAKER_TOP_FRONT_RIGHT             ((SLuint32) 0x00004000)
    #define SL_SPEAKER_TOP_BACK_LEFT               ((SLuint32) 0x00008000)
    #define SL_SPEAKER_TOP_BACK_CENTER             ((SLuint32) 0x00010000)
    #define SL_SPEAKER_TOP_BACK_RIGHT              ((SLuint32) 0x00020000)

    第七个参数:

    #define SL_BYTEORDER_BIGENDIAN                ((SLuint32) 0x00000001)
    #define SL_BYTEORDER_LITTLEENDIAN            ((SLuint32) 0x00000002)

    音源配置成功后设置播放状态,使用内存进行播放。

    sl提供的接口是

    SLresult (*Enqueue) (
    SLBufferQueueItf self,  //创建的BufferQueueAudioPlayer
    const void *pBuffer,    //读取wave文件的buffer  
    SLuint32 size,      //buffer大小
    SLboolean isLastBuffer  //是否最后(暂时没用过)
    );

    实际用法:

    SLresult result;
            result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
            if (SL_RESULT_SUCCESS != result) {
                return JNI_FALSE;
            }

    在使用BufferQueueAudioPlayer进行播放的时候,我试图去频繁的获取播放的状态

    SLresult (*GetPlayState) (
    SLPlayItf self,
    SLuint32 *pState
    );

    的时候,貌似获取的都是playing 而在一个wav文件播放结束的时候,还是没有出现我所期待的stopped,暂时还不知道什么原因。

  • 相关阅读:
    2019-8-22学习笔记---文件上传与读取
    JS字符串的操作
    JS控制台打印星星,总有你要的那一款~呐~给你小心心哦~~~❤
    DOM的操作(增删改查)
    js上传视频(jquery.form.js)
    vue单页面模板说明文档(3)
    vue单页面模板说明文档(2)
    vue单页面模板说明文档(1)
    js 通过url获取里面的参数值
    ios点击输入框,界面放大解决方案
  • 原文地址:https://www.cnblogs.com/wainiwann/p/3064992.html
Copyright © 2011-2022 走看看