Android-irrLang or sound solution

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
zhengxianfu
Posts: 16
Joined: Thu Apr 05, 2012 9:33 am

Android-irrLang or sound solution

Post by zhengxianfu »

We are using irrlicht-android port project.It does integrate irrlang into this project.
Doesn't anyone who know how to play sound under irrlicht-android-port project ,for the format ogg or wav?

Thanks in advance.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Android-irrLang or sound solution

Post by hybrid »

Please ask in the irrklang forum at ambiera.com. Maybe there are already ports available for this platform
zhengxianfu
Posts: 16
Joined: Thu Apr 05, 2012 9:33 am

Re: Android-irrLang or sound solution

Post by zhengxianfu »

Thanks.
I will check at the irrlang website.RIght now,I have already found NDK native-sound example ,and use it as my sound solution.
digijohnny
Posts: 63
Joined: Sat Sep 12, 2009 6:08 pm
Contact:

Re: Android-irrLang or sound solution

Post by digijohnny »

here is a straight c++ implementation of OPENSLES
im using this on android, its the only opensl system i have, but i guess it with work on any opensl supporting
SL_IID_SEEK, SL_IID_PLAYBACKRATE,SL_IID_VOLUME
it only uses irrlicht stringc to load soundbites            
dont forget to links with -lOpenSLES

NAOpenSL.h

Code: Select all

 
/* JKROMERO - digijohnny.com  derived from Java JNI examples for native audio
// Pure c++   implementation of OpenSLES  native sound for android 
USAGE:
 
initialize...............
OSLESMediaPlayer  ESPlayer;    --sound engine and outputmix:  ONLY ONE PLAYER ALLOWED PER APP
SoundBite Sound1;                         --- up to 32 'active' per engine/outputmix
.....
 
ESPlayer.createEngine();
Sound1.createAudioPlayer('sdcard/media/soundbite.wav");
Sound1.setNoLoop(); - dont loop, loops by default.
Sound1.setVolume(0.5); - set volume @ halfway
Sound1.setPitch(500);   --- 500- half speed playback , 1000- normal 2000- double speed
Sound1.play();          --play soundbite
....
....
....
cleaning up...........
Sound1.releaseAudioPlayer();
ESPlayer.releaseEngine();
 
 
*/
 
 
#include<android/log.h>
#include "irrSetup.h"  // set up irrlicht environment - includes and namespaces only needed for stringc passed to CreateAudioPlayer(stringc)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG  , "NAOpenSLES", __VA_ARGS__)
class OSLESMediaPlayer {
public:
    void createEngine();
    void releaseEngine();
 
};
class SoundBite{
private:
     SLObjectItf uriPlayerObject;
     SLPlayItf uriPlayerPlay;
     SLSeekItf uriPlayerSeek;
     SLVolumeItf uriPlaybackVol;
     SLPlaybackRateItf uriPlaybackRate;
     SLVolumeItf  uriPlayerVolume;
     SLpermille playbackMinRate ;
     SLpermille playbackMaxRate ;
     SLpermille playbackRateStepSize;
public:
     char cstr[64]; // string to hold misc debug info messages
     int Rate; //current playback rate;  min 500 to max 2000 default 1000
     float Volume; // current volume setting 0.0 silent to 1.0 normal
    bool createAudioPlayer(stringc uri);
    void releaseAudioPlayer();
        void play();
        void stop();
        void pause();
        bool isPlaying();
        void setPlayState(SLuint32 state) ;
        SLuint32 getPlayState();
        void seekTo(int position);
        int getDuration();
        int getPosition();
        void setRate(int rate);
        void setVolume(float v);
        int getRate();
        bool setLoop( int startPos, int endPos );
        bool setNoLoop();
};
 
NAOpenSL.cpp

Code: Select all

 
// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "NAOpenSL.h"
#include <assert.h>
#include <sys/types.h>
 
// engine interfaces
 SLObjectItf engineObject = NULL;
 SLEngineItf engineEngine;
 SLObjectItf outputMixObject = NULL;
 
 
 void SLAPIENTRY play_callback( SLPlayItf player, void *context, SLuint32 event )
    {
     LOGD("CallBack");
        if( event & SL_PLAYEVENT_HEADATEND )
        {
            (*player)->SetPlayState(player, SL_PLAYSTATE_STOPPED);
            LOGD("CallBack.......stopped");
        }
    }
 
float gain_to_attenuation( float gain )
{
    return gain < 0.01F ? -96.0F : 20 * log10( gain );
}
 
     bool SoundBite::createAudioPlayer( stringc uri) {
         SLresult result;
 
             // configure audio source
         // (requires the INTERNET permission depending on the uri parameter)
         SLDataLocator_URI loc_uri = { SL_DATALOCATOR_URI, (SLchar*)uri.c_str()};
         SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL,
         SL_CONTAINERTYPE_UNSPECIFIED };
         SLDataSource audioSrc = { &loc_uri, &format_mime };
             SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX,
                     outputMixObject };
             SLDataSink audioSnk = { &loc_outmix, NULL };
 
             // create audio player
             const SLInterfaceID ids[3] = { SL_IID_SEEK, SL_IID_PLAYBACKRATE,SL_IID_VOLUME };
             const SLboolean req[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE ,SL_BOOLEAN_TRUE};
             result = (*engineEngine)->CreateAudioPlayer(engineEngine, &uriPlayerObject,
                     &audioSrc, &audioSnk, 3, ids, req);
                     assert(SL_RESULT_SUCCESS == result);
 
                     result = (*uriPlayerObject)->Realize(uriPlayerObject, SL_BOOLEAN_FALSE);
                     if (SL_RESULT_SUCCESS != result) {
                             (*uriPlayerObject)->Destroy(uriPlayerObject);
                             uriPlayerObject = NULL;
                             return false;
             }
 
             // get the play interface
             result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAY,
                     &uriPlayerPlay);
             assert(SL_RESULT_SUCCESS == result);
 
             // get the seek interface
                 result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_SEEK,
                         &uriPlayerSeek);
                 assert(SL_RESULT_SUCCESS == result);
 
               // get the Volume interface
                     result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_VOLUME,
                             &uriPlayerVolume);
                     assert(SL_RESULT_SUCCESS == result);
 
             // get playback rate interface
             result = (*uriPlayerObject)->GetInterface(uriPlayerObject,
                     SL_IID_PLAYBACKRATE, &uriPlaybackRate);
             assert(SL_RESULT_SUCCESS == result);
 
                 // register callback function
 
             result = (*uriPlayerPlay)->RegisterCallback(uriPlayerPlay,
                        play_callback, 0);
                assert(SL_RESULT_SUCCESS == result);
                result = (*uriPlayerPlay)->SetCallbackEventsMask(uriPlayerPlay,
                        SL_PLAYEVENT_HEADATEND); // head at end
                assert(SL_RESULT_SUCCESS == result);
 
 
             SLmillisecond msec;
             result = (*uriPlayerPlay)->GetDuration(uriPlayerPlay, &msec);
             assert(SL_RESULT_SUCCESS == result);
 
             // no loop
             result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, SL_BOOLEAN_TRUE, 0, msec);
            assert(SL_RESULT_SUCCESS == result);
 
 
             SLuint32 capa;
                 result = (*uriPlaybackRate)->GetRateRange(uriPlaybackRate, 0,
                         &playbackMinRate, &playbackMaxRate, &playbackRateStepSize, &capa);
                 assert(SL_RESULT_SUCCESS == result);
          sprintf(cstr,"Min:%i Max:%i Step:%i Curr:%i",playbackMinRate,playbackMaxRate,playbackRateStepSize,getRate());
 
                 //  (*uriPlaybackRate)->SetRate(uriPlaybackRate, playbackMinRate);
 
 
             result = (*uriPlaybackRate)->SetPropertyConstraints(uriPlaybackRate,
                                         SL_RATEPROP_NOPITCHCORAUDIO);
 
                             if (SL_RESULT_PARAMETER_INVALID == result) {
                                 LOGD("Parameter Invalid");
                             }
                             if (SL_RESULT_FEATURE_UNSUPPORTED == result) {
                                     LOGD("Feature Unsupported");
                                 }
                             if (SL_RESULT_SUCCESS == result) {
                                 assert(SL_RESULT_SUCCESS == result);
                                     LOGD("Success");
                                 }
             return true;
     }
 
     void SoundBite::releaseAudioPlayer(
             ) {
         // destroy URI audio player object, and invalidate all associated interfaces
         if (uriPlayerObject != NULL) {
             (*uriPlayerObject)->Destroy(uriPlayerObject);
             uriPlayerObject = NULL;
             uriPlayerPlay = NULL;
             uriPlayerSeek = NULL;
             uriPlaybackRate = NULL;
         }
    }
 
      void SoundBite::setPlayState(SLuint32 state) {
            SLresult result;
            if (NULL != uriPlayerPlay) {
                result = (*uriPlayerPlay)->SetPlayState(uriPlayerPlay, state);
                assert(SL_RESULT_SUCCESS == result);
            }
 
        }
 
        SLuint32 SoundBite::getPlayState() {
        SLresult result;
 
        // make sure the URI audio player was created
        if (NULL != uriPlayerPlay) {
            SLuint32 state;
            result = (*uriPlayerPlay)->GetPlayState(uriPlayerPlay, &state);
            assert(SL_RESULT_SUCCESS == result);
            return state;
        }
 
        return 0;
 
    }
 
    // play
     void SoundBite::play() {
        setPlayState(SL_PLAYSTATE_PLAYING);
    }
 
    // stop
     void SoundBite::stop() {
        setPlayState(SL_PLAYSTATE_STOPPED);
    }
 
    // pause
     void SoundBite::pause() {
        setPlayState(SL_PLAYSTATE_PAUSED);
    }
 
    // pause
     bool SoundBite::isPlaying() {
        return (getPlayState() == SL_PLAYSTATE_PLAYING);
    }
     //set Volume
    void SoundBite::setVolume(float v){
     (*uriPlayerVolume)->SetVolumeLevel( uriPlayerVolume,
         (SLmillibel)(gain_to_attenuation( v ) * 100) );
     Volume=v;
    }
 
    // set position
     void SoundBite::seekTo(int position) {
        if (NULL != uriPlayerPlay) {
            SLresult result;
            result = (*uriPlayerSeek)->SetPosition(uriPlayerSeek, position,
                    SL_SEEKMODE_FAST);
            assert(SL_RESULT_SUCCESS == result);
            //LOGD("  SeekTo");
        }    else
            LOGD("Unsuported  SeekTo");
    }
 
    // get duration in milisecs
     int SoundBite::getDuration() {
        if (NULL != uriPlayerPlay) {
            SLresult result;
            SLmillisecond msec;
            result = (*uriPlayerPlay)->GetDuration(uriPlayerPlay, &msec);
        assert(SL_RESULT_SUCCESS == result);
 
            return msec;
        }    else
            LOGD("Unsuported getDuration");
 
 
        return 0.0f;
    }
 
    // get current position in millisecs
     int SoundBite::getPosition() {
        if (NULL != uriPlayerPlay) {
            SLresult result;
            SLmillisecond msec;
            result = (*uriPlayerPlay)->GetPosition(uriPlayerPlay, &msec);
        assert(SL_RESULT_SUCCESS == result);
 
            return msec;
        }    else
            LOGD("Unsuported getPosition");
        return 0.0f;
    }
     void SoundBite::setRate(int rate) {
        if (NULL != uriPlaybackRate) {
            SLresult result;
 
            result = (*uriPlaybackRate)->SetRate(uriPlaybackRate, rate);
          assert(SL_RESULT_SUCCESS == result);
          Rate=rate;
 
        }    else
            LOGD("Unsuported setRate");
 
    }
 
     int SoundBite::getRate(
            ) {
      if (NULL != uriPlaybackRate) {
            SLresult result;
 
            SLpermille rate;
            result = (*uriPlaybackRate)->GetRate(uriPlaybackRate, &rate);
            assert(SL_RESULT_SUCCESS == result);
 
            return rate;
        }    else
            LOGD("Unsuported getRate");
 
 
        return 0;
    }
 
    // create URI audio player
     bool SoundBite::setLoop( int startPos, int endPos) {
        SLresult result;
        if (NULL != uriPlayerSeek) {
 
        result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, SL_BOOLEAN_TRUE, startPos,
                endPos);
     assert(SL_RESULT_SUCCESS == result);
        return true;
        }
        else
            LOGD("Unsupported  setLoop ");
    }
 
    // create URI audio player
    bool SoundBite::setNoLoop() {
        SLresult result;
        if (NULL != uriPlayerSeek) {
                // enable whole file looping
            result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, SL_BOOLEAN_FALSE, 0,
                    SL_TIME_UNKNOWN);
            assert(SL_RESULT_SUCCESS == result);
 
        }    else
            LOGD("Unsuported setNoLoop");
        return true;
    }
 
    // create the engine and output mix objects
 void OSLESMediaPlayer::createEngine(
        ) {
    SLresult result;
 
    // create engine
    LOGD("create engine");
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
   // assert(SL_RESULT_SUCCESS == result);
 
    // realize the engine
    LOGD("realize the engine");
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);
 
    // get the engine interface, which is needed in order to create other objects
    LOGD("get the engine interface");
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE,
            &engineEngine);
    assert(SL_RESULT_SUCCESS == result);
 
    // create output mix, with environmental reverb specified as a non-required interface
    LOGD("create output mix");
 
    const SLInterfaceID ids[1] = {SL_IID_VOLUME};
       const SLboolean req[1] = {SL_BOOLEAN_TRUE};
 
       /// NOTE: CRAETING OutputMix with no requested features , 0 for ids/req count
       // not much available for android implementation of outputmix, more available in player object
       result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0,
               ids, req);
   assert(SL_RESULT_SUCCESS == result);
 
    // realize the output mix
    LOGD("realize the output mix");
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);
 
}
 
 void OSLESMediaPlayer::releaseEngine(
        ) {
    // destroy URI audio player object, and invalidate all associated interfaces
 
 
    // destroy output mix object, and invalidate all associated interfaces
    if (outputMixObject != NULL) {
        (*outputMixObject)->Destroy(outputMixObject);
        outputMixObject = NULL;
    }
 
    // destroy engine object, and invalidate all associated interfaces
    if (engineObject != NULL) {
        (*engineObject)->Destroy(engineObject);
        engineObject = NULL;
        engineEngine = NULL;
    }
 
}
 
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Android-irrLang or sound solution

Post by Nadro »

I use OpenAL + Ogg Vorbis for my Android projects and it works without problems.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
huan'er
Posts: 2
Joined: Wed Mar 14, 2007 9:27 am

Re: Android-irrLang or sound solution

Post by huan'er »

i use opensles and ogg;it's play no problem. but, the api of "GetPlayState" is no use. i didn't find any problem. Someone has the same problem?
huan'er
Posts: 2
Joined: Wed Mar 14, 2007 9:27 am

Re: Android-irrLang or sound solution

Post by huan'er »

Nadro wrote:I use OpenAL + Ogg Vorbis for my Android projects and it works without problems.
hi, there is no source code of openal. How do you compile a lib on android?
Post Reply