Impact

» Edit Game Info

12 months ago by kapolab

I am using ig.game.music to play bgm, and there is one problem that I want to solve.

When the music loops, there is a little interval occurs.

Is there any way to avoid this?

I am making short looping musics and this interval is quite annoying when it is looping.

11 months ago by Joncom

I'm not aware of any way to avoid this issue. However I'm interested in the solution if anybody knows of one...

11 months ago by lTyl

I wrote a simple wrapper around Howler 2.0 I am using for Shadows of Adam that seems to fix this issue:

ig.module(
    'impact.audioManager'
)


.defines(function(){
        AudioManager = function(){
            // List of loaded music
            this._audio = {};

            this._musicID = null;
            this._currentTrack = null;

            this._musicIDFade = null;

            this._s = ig.global.Config.Audio;

        };

        AudioManager.prototype.addMusic = function( name, id, data ){
            if ( !data ) data = {};

            this._audio[id] = new Howl({
                src: [ this._s.MUSIC_ROOT_PATH + name + ".mp3", this._s.MUSIC_ROOT_PATH + name + ".ogg" ],
                sprite: data.sprite,
                loop: data.loop || false,
                autoplay: data.autoPlay || false,
                preload: data.preLoad || this._s.PRE_LOAD_AUDIO,
                html5: data.html5 || true,
                mute: data.mute || false,
                rate: data.rate || this._s.MASTER_PLAYBACK_RATE,
                pool: data.pool || this._s.MAX_MUSIC_CHANNEL_POOL,
                volume: data.volume || this._s.MUSIC_VOLUME,
                name: name,
                onend: function( soundID ) {
                    this.playMusic( this.getCurrentTrackID(), 'loop');
                    if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                        ig.log("The following sound ID has reached the end", soundID );
                }.bind( this ),
                onstop: function(){

                }.bind( this )
            })

        };

        AudioManager.prototype.addSound = function( name, id, data ){
            if ( !data ) data = {};

            this._audio[id] = new Howl({
                src: [ this._s.SOUND_ROOT_PATH + name + ".mp3", this._s.MUSIC_ROOT_PATH + name + ".ogg" ],
                sprite: data.sprite,
                loop: data.loop || false,
                autoplay: data.autoPlay || false,
                preload: data.preLoad || this._s.PRE_LOAD_AUDIO,
                html5: data.html5 || true,
                mute: data.mute || false,
                rate: data.rate || this._s.MASTER_PLAYBACK_RATE,
                pool: data.pool || this._s.MAX_SOUND_CHANNEL_POOL,
                volume: data.volume || this._s.MUSIC_VOLUME,
                name: name
            })

        };

        AudioManager.prototype.getID = function( id ) {
            return this._audio[ id ];
        };

        AudioManager.prototype.playMusic = function( id, sprite ){
            if ( ig.global.gamePaused ) {
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log( "Attempted to play music. Action blocked because game is paused");
                return;
            }
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                ig.log( "Attempting to play ", id, " Sprite is", sprite );
            // Handle music pausing and resuming. If no id is present and we have a musicID value, play the paused track
            if ( this.getMusicID() && !id ) {
                id = this.getCurrentTrackID();
                sprite = this.getMusicID();
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    console.log("Resume track: ", id, "At sprite:", sprite );
            }

            // Currently do not have a playing track nor do we have a sprite. Set sprite to intro
            if ( !this.getMusicID() && !sprite ) {
                sprite = "intro";
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log("Playing new track:", id );
            }

            // We currently have a track playing. However the ID is not the same as the track playing. So play the new track
            if ( this.getCurrentTrackID() !== id  && this.getCurrentTrackID() != null  ) {
                sprite = ( !sprite ) ? "intro" : sprite;
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log("Replacing track", this.getCurrentTrackID(), "with track", id );
                this.stop();
            }

            // Track is playing the same ID but a different sprite.
            if ( this.getCurrentTrackID() == id && sprite ) {
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log("Playing new sprite", sprite );
                this.stop();
            }

            // Track is playing the same ID but with an undefined sprite. Terminate
            if ( this.getCurrentTrackID() == id && !sprite ) {
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log("Tried playing the same song that was already playing. Action was blocked because music was already playing");
                return;
            }

            // This track is a fadeOut track because the sprite is a loop and the current music ID is the same as the fade out music id
            if ( sprite == 'loop' && this._musicIDFade == this.getMusicID() ){
                if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                    ig.log("Attempted to play a loop sprite. Action was blocked because music was faded.");
                return;
            }

            this._musicID = this.getID( id ).play( sprite );
            this._currentTrack = id;
        };

        AudioManager.prototype.getCurrentTrackID = function(){
            return this._currentTrack;
        };

        AudioManager.prototype.getMusicID = function(){
            return this._musicID;
        };

        AudioManager.prototype.playSound = function( id ){
            if ( !this.getID(id) ) return;
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                console.log("Playing sound", id );

            this.getID(id).play();

        };

        AudioManager.prototype.stopSound = function( id ){
            if ( !this.getID(id) ) return;
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                console.log("Stopping sound", id );

            this.getID(id).stop();

        };

        AudioManager.prototype.pause = function( id ){
            if ( !id ) id = this.getCurrentTrackID();
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                console.log("Track paused", id );
            return this.getID( id ).pause( this.getMusicID() );
        };

        AudioManager.prototype.stop = function( id ){
            if ( !id ) id = this.getCurrentTrackID();
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                console.log("Track stopped", this.getCurrentTrackID() );
            return this.getID( id ).stop( this.getMusicID() );
        };

        AudioManager.prototype.mute = function( bool, id ){
            if ( !id ) id = this.getCurrentTrackID();
            return this.getID( id ).mute( bool );
        };

        AudioManager.prototype.volume = function( volume, id ){
            if ( !id ) id = this.getCurrentTrackID();
            return this.getID( id ).volume( volume );
        };

        AudioManager.prototype.fade = function( from, to, duration, id ){
            if ( !id ) id = this.getCurrentTrackID();
            if ( to == 0.0 ) {
                this._musicIDFade = this.getMusicID();
            } else {
                this._musicIDFade = null;
            }
            if ( ig.global.Config.Settings.AUDIO_MANAGER_DEBUG_MODE )
                ig.log(this.getMusicID() + " is starting to fade to volume " + to + " in " + duration + "ms");
            return this.getID( id ).fade( from, to, duration );
        };

        AudioManager.prototype.rate = function( rate, id ){
            if ( !id ) id = this.getCurrentTrackID();
            return this.getID( id ).rate( rate, this.getMusicID() );
        };

    });

Example of addMusic:

            // DEFINE MUSIC HERE
            // Format: "fileName", "internalID", [ data ]
            // Title music
            ig.global.audioManager.addMusic('title', 'title',
                {
                    sprite: {
                        intro: [0, 69999],
                        loop: [70000, 80000]}
                }
            );

Music is in two parts. Intro part plays from 0 milliseconds to 69,999 milliseconds. At the end of that part, it loops from 70,000 milliseconds to 80,000 milliseconds forever.

11 months ago by kapolab

Thank you lTyl, I will try this!

11 months ago by lTyl

Good luck! This is a straight copy+paste from my project, so make sure you remove all the debug code and config file references before using it. You also need Howler 2.0 (1.0 will not work)
Page 1 of 1
« first « previous next › last »

Post Reply

Please login or register to reply.