SFXPlayer.js

/* global platypus */
import {arrayCache, greenSplice} from './utils/array.js';
import TweenJS from '@tweenjs/tween.js';

const
    {Tween} = TweenJS;

/**
 * This class plays sfx audio and manages Springroll volume changes.
 *
 * @memberof platypus
 * @class SFXPlayer
 */
 export default class SFXPlayer {
    constructor () {
        this.masterVolume = 1;
        this.volume = 1;
        this.playingAudio = arrayCache.setUp();
    }

    /**
     * Plays a sound.
     *
     * @method platypus.SFXPlayer#play
     * @param {String} sound Sound Id to play.
     * @param {Object} data PixiSound data to inform sound playback.
     * @return {pixiSound.MediaInstance} The media instance of the playing sound.
     * @public
     */
    play (sound, data) {
        const
            sfx = typeof sound === 'string' ? platypus.assetCache.get(platypus.assetCache.getFileId(sound)) : sound,
            audio = sfx.play(data);

        audio.initialVolume = (typeof data.initialVolume === 'number' ? data.initialVolume : audio.volume);
        audio.set('volume', audio.volume * this.volume * this.masterVolume);
        this.playingAudio.push(audio);
        audio.on('end', () => {
            const index = this.playingAudio.indexOf(audio);

            greenSplice(this.playingAudio, index);
        });

        return audio;
    }

    /**
     * Plays a sound.
     *
     * @method platypus.SFXPlayer#stop
     * @param {pixiSound.MediaInstance} audio Audio to stop.
     * @public
     */
    stop (audio) {
        const index = this.playingAudio.indexOf(audio);

        audio.stop();
        if (index >= 0) {
            greenSplice(this.playingAudio, index);
        } else {
            platypus.debug.warn('SFXPlayer: Did not find "' + audio.soundId + '"');
        }
    }

    fade (audio, volume, time, onComplete = () => {}) {
        const
            tween = new Tween(audio);

        tween.to({
            initialVolume: volume
        }, time);
        tween.onUpdate(() => {
            audio.set('volume', audio.initialVolume * this.volume * this.masterVolume);
        });
        tween.onComplete(onComplete);
        tween.start();
    }

    /**
     * Sets volume on all playing sound effects.
     *
     * @method platypus.SFXPlayer#setVolume
     * @param {Number} volume A value between 0-1 to set volume on all playing sound effects.
     * @public
     */
    setVolume (volume) {
        const
            playingAudio = this.playingAudio;

        this.volume = volume;
        for (let i = 0; i < playingAudio.length; i++) {
            const
                audio = playingAudio[i];

            audio.set('volume', audio.initialVolume * this.volume * this.masterVolume);
        }
    }

    /**
     * Sets master volume on all playing sound effects.
     *
     * @method platypus.SFXPlayer#setMasterVolume
     * @param {Number} volume A value between 0-1 to set volume on all playing sound effects.
     * @public
     */
    setMasterVolume (volume) {
        this.masterVolume = volume;
        this.setVolume(this.volume);
    }

    /**
     * Cleans up this SFXPlayer.
     * @method platypus.SFXPlayer#destroy
     * @public
     */
    destroy () {
        arrayCache.recycle(this.playingAudio);
        this.playingAudio = null;
    }
};