Impact

» Edit Game Info

1 year 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.

1 year 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...

1 year 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.

1 year ago by kapolab

Thank you lTyl, I will try this!

1 year 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.