创建音频引擎之后,读取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,暂时还不知道什么原因。