Android Audio and Video learning 7th: decoding with OpenSL es

Source: Internet
Author: User


/*
*
* The WAV file is decoded using transcode-1.1.7 and then played using OpenSL ES
*
*/

Variables and structures used

WAV wav;//wav file PointerSLOBJECTITF Engineobject;//Engine ObjectSLENGINEITF Engineinterface;//Engine interfaceSLOBJECTITF Outputmixobject;//MixerSLOBJECTITF Audioplayerobject;//Player ObjectSLANDROIDSIMPLEBUFFERQUEUEITF ANDIOPLAYERBUFFERQUEUEITF;//Buffer Queue InterfaceSLPLAYITF Audioplayinterface;//Play InterfaceUnsignedChar*buffer;//Buffersize_t buffersize;//Buffer size//Contextstructplayercontext{wav wav; UnsignedChar*buffer;    size_t buffersize; Playercontext (WAV wav, unsignedChar*buffer, size_t buffersize) { This->wav = wav; This->buffer = buffer; This->buffersize = buffersize; }};//Implementation ObjectvoidRealizeobject (SLOBJECTITFObject){//non-asynchronous (blocking)(*Object)->realize (Object, sl_boolean_false);}
Specific implementation process: 1. Open file
WAV wav = OpenWaveFile(env,jFileName);
*env,jstring jFileName){    *cFileName = env->GetStringUTFChars(jFileName,JNI_FALSE);    WAVError err;    WAV wav = wav_open(cFileName,WAV_READ,&err);    LOGI("%d",wav_get_bitrate(wav));    env->ReleaseStringUTFChars(jFileName,cFileName);    if0){        LOGE("%s",wav_strerror(err));    }    return wav;}
2. Create the OpenSL es engine
//OpenSL ES在Android平台下默认是线程安全的,这样设置是为了为了兼容其他平台    SLEngineOption options[] = {        {(SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE}    };    slCreateEngine(&engineObject,ARRAY_LEN(engineObject),options,0,0,0//没有接口//实例化对象    //对象创建之后,处于未实例化状态,对象虽然存在但未分配任何资源,使用前先实例化(使用完之后destroy)    RealizeObject(engineObject);
3. Get the Engine interface
(*engineObject)->GetInterface(engineObject,SL_IID_ENGINE,&engineInterface);
4. Create an output mixer
(*engineInterface)->CreateOutputMix(engineInterface,&outputMixObject,0,0,0)//没有接口    //实例化混音器    RealizeObject(outputMixObject);
5. Create a buffer to save the read to the audio database
//缓冲区的大小    bufferSize = wav_get_channels(wav) * wav_get_rate(wav) * wav_get_bits(wav);    newunsignedchar[bufferSize];
6. Create an audio player with a buffer queue
CreateBufferQueueAudioPlayer(wav,engineInterface,outputMixObject,audioPlayerObject);    //实例化音频播放器    RealizeObject(audioPlayerObject);

CreateBufferQueueAudioPlayer.cpp

extern"C"{#include "wavlib.h"}#include <SLES/OpenSLES.h>#include <SLES/OpenSLES_Android.h>#include <android/log.h>#define Array_len (a) (sizeof (a)/sizeof (a[0))//Create an audio playback objectvoidCreatebufferqueueaudioplayer (WAVWAV, SLENGINEITF engineengine, SLOBJECTITF outputmixobject, SLOBJECTITF &audioplayerobject) {//Android Simple buffer queue locator for data sourcesSldatalocator_androidsimplebufferqueue Datasourcelocator = {Sl_datalocator_androidsimplebufferqueue,//Locator type        1                                        //Number of buffers};//PCM data source formatSLDATAFORMAT_PCM Datasourceformat = {SL_DATAFORMAT_PCM,//format typeWav_get_channels (WAV),//Number of channelsWav_get_rate (WAV) * +,number of samples per//Hz/secWav_get_bits (WAV),//Number of bits per sampleWav_get_bits (WAV),//Container sizeSl_speaker_front_center,//Channel Shield       Sl_byteorder_littleendian//byte order};//Data source is a simple buffer queue that contains the PCM formatSldatasource DataSource = {&datasourcelocator,//Data Locator&datasourceformat//Data format};//output hybrid locator for data receiversSldatalocator_outputmix Datasinklocator = {Sl_datalocator_outputmix,//Locator typeOutputmixobject//Output Mix};//Data locator is an output mixSldatasink Datasink = {&datasinklocator,//Locator        0                 //Format};//Required InterfaceSlinterfaceid interfaceids[] = {Sl_iid_bufferqueue};//Required interface, if the required interface is not used, the request will failSlboolean requiredinterfaces[] = {sl_boolean_true//For Sl_iid_bufferqueue};//Create an audio player objectSlresult result = (*engineengine)->createaudioplayer (Engineengine, &audioplayerobject, &datasource, &datasink, Array_len (interfaceids), Interfaceids, R equiredinterfaces);}
7. Get the buffer queue interface buffer Interface
//通过缓冲区队列接口对缓冲区进行排序播放    (*audioPlayerObject)->GetInterface(audioPlayerObject,SL_IID_BUFFERQUEUE,&andioPlayerBufferQueueItf);
8. Register the audio player callback function
//当播放器完成对前一个缓冲区队列的播放时,回调函数会被调用,然后我们又继续读取音频数据,直到结束    //上下文,包裹参数方便再回调函数中使用    new PlayerContext(wav,buffer,bufferSize);    (*andioPlayerBufferQueueItf)->RegisterCallback(andioPlayerBufferQueueItf,PlayerCallBack,ctx);
//callback functionvoidPlayercallback (SLANDROIDSIMPLEBUFFERQUEUEITF Andioplayerbufferqueue,void *Context) {Playercontext*CTx=(Playercontext*) context;//Read Datassize_t readsize=Wav_read_data (CTX -Wav,ctx -Buffer,ctx -buffersize);if(0 <ReadSize) {(*Andioplayerbufferqueue) -Enqueue (Andioplayerbufferqueue,ctx -Buffer,readsize); }Else{//destroy ContextClosewavefile (CTX -WAV);//Close fileDelete CTX -Buffer//Release cache}}
9. Get play interface to start playing music by using the Setplaystate function
//一旦播放器被设置为播放状态,该音频播放器开始等待缓冲区排队就绪    (*audioPlayerObject)->GetInterface(audioPlayerObject,SL_IID_PLAY,&audioPlayInterface);    //设置播放状态    (*audioPlayInterface)->SetPlayState(audioPlayInterface,SL_PLAYSTATE_PLAYING);
10. Start by making the first buffer queue

PlayerCallBack(andioPlayerBufferQueueItf,ctx);
Full code
#include "com_dongnaoedu_jasonaudioplayer_audioplayer.h"extern "C"{#include "wavlib.h"}#include <SLES/OpenSLES.h>#include <SLES/OpenSLES_Android.h>#include <android/log.h>#include "CreateBufferQueueAudioPlayer.cpp"#define Logi (FORMAT,...) __android_log_print (Android_log_info, "Jason", format,# #__VA_ARGS__);#define LOGE (FORMAT,...) __android_log_print (Android_log_error, "Jason", format,# #__VA_ARGS__);#define Array_len (a) (sizeof (a)/sizeof (a[0))WAV wav;//wav file PointerSLOBJECTITF Engineobject;//Engine ObjectSLENGINEITF Engineinterface;//Engine interfaceSLOBJECTITF Outputmixobject;//MixerSLOBJECTITF Audioplayerobject;//Player ObjectSLANDROIDSIMPLEBUFFERQUEUEITF ANDIOPLAYERBUFFERQUEUEITF;//Buffer Queue InterfaceSLPLAYITF Audioplayinterface;//Play Interfaceunsigned Char*buffer;//Buffersize_t buffersize;//Buffer size//Contextstructplayercontext{wav wav;unsigned Char*buffer;    size_t buffersize; Playercontext (WAV wav,unsigned Char*buffer, size_t buffersize) { This->wav = wav; This->buffer = buffer; This->buffersize = buffersize; }};//Open FileWAV openwavefile (jnienv *env,jstring jfilename) {Const Char*cfilename = Env->getstringutfchars (Jfilename,jni_false);    Waverror err;    WAV wav = Wav_open (CFILENAME,WAV_READ,&AMP;ERR); Logi ("%d", Wav_get_bitrate (WAV)); Env->releasestringutfchars (Jfilename,cfilename);if(wav = =0) {LOGE ('%s ', Wav_strerror (err)); }returnWAV;}//Close filevoidClosewavefile (WAV wav) {wav_close (WAV);}//Implementation ObjectvoidRealizeobject (Slobjectitf object) {//non-asynchronous (blocking)(*object)->realize (object,sl_boolean_false);}//callback functionvoidPlayercallback (SLANDROIDSIMPLEBUFFERQUEUEITF Andioplayerbufferqueue,void*context) {playercontext* CTX = (playercontext*) context;//Read Datassize_t readsize = Wav_read_data (ctx->wav,ctx->buffer,ctx->buffersize);if(0< ReadSize) {(*andioplayerbufferqueue)->enqueue (andioplayerbufferqueue,ctx->buffer,readsize); }Else{//destroy ContextClosewavefile (ctx->wav);//Close file        Deletectx->buffer;//Release cache}}jniexportvoidJnicall Java_com_dongnaoedu_jasonaudioplayer_audioplayer_play (jnienv *env, Jclass jthiz, jstring jFileName) {//1. Opening a fileWAV wav = openwavefile (env,jfilename);//2. Creating the OpenSL es engine    //opensl es is thread-safe by default on Android, so it is set up to be compatible with other platformsSlengineoption options[] = {{(SLuint32) Sl_engineoption_threadsafe, (SLuint32) sl_boolean_true}}; Slcreateengine (&engineobject,array_len (engineobject), Options,0,0,0);//No interface    //instanced objects    after the object is created, it is in an destroy state, the object exists but no resources are assigned, and is instantiated before use (after use)Realizeobject (Engineobject);//3. Getting the engine interface(*engineobject)->getinterface (engineobject,sl_iid_engine,&engineinterface);//4. Creating an output mixer(*engineinterface)->createoutputmix (Engineinterface,&outputmixobject,0,0,0);//No interface    //instancing mixerRealizeobject (Outputmixobject);//5. Creating a buffer to save the read to the audio database    //size of bufferbuffersize = wav_get_channels (WAV) * WAV_GET_RATE (WAV) * wav_get_bits (WAV); Buffer =New unsigned Char[BufferSize];//6. Creating an audio player with a buffer queueCreatebufferqueueaudioplayer (Wav,engineinterface,outputmixobject,audioplayerobject);//Instantiate an audio playerRealizeobject (Audioplayerobject);//7. Getting the buffer queue interface buffer queues Interface    //Sort buffers by Buffer queue interface to play(*audioplayerobject)->getinterface (AUDIOPLAYEROBJECT,SL_IID_BUFFERQUEUE,&AMP;ANDIOPLAYERBUFFERQUEUEITF);//8. Registering the audio player callback function    //When the player finishes playing against the previous buffer queue, the callback function is called, and then we continue to read the audio data until the end    //context, wrap parameters easy to use in callback functionPlayercontext *ctx =NewPlayercontext (wav,buffer,buffersize); (*ANDIOPLAYERBUFFERQUEUEITF)->registercallback (ANDIOPLAYERBUFFERQUEUEITF,PLAYERCALLBACK,CTX);//9. Get play interface to start playing music by setplaystate function    //Once the player is set to play, the audio player begins to wait for the buffer to queue ready(*audioplayerobject)->getinterface (audioplayerobject,sl_iid_play,&audioplayinterface);//Set playback status(*audioplayinterface)->setplaystate (audioplayinterface,sl_playstate_playing);//10. Start by getting the first buffer enqueuedPlayercallback (ANDIOPLAYERBUFFERQUEUEITF,CTX);//Close file    //closewavefile (WAV);}

Android Audio and Video learning 7th: decoding with OpenSL es

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.