Skip to content

⬅️ Back to Table of Contents

📄 Audio.js

📊 Analysis Summary

Metric Count
🔧 Functions 27
🧱 Classes 1
📦 Imports 1

📚 Table of Contents

🛠️ File Location:

📂 src/audio/Audio.js

📦 Imports

Name Source
Object3D ../core/Object3D.js

Functions

Audio.getOutput(): GainNode

JSDoc:

/**
     * Returns the output audio node.
     *
     * @return {GainNode} The output node.
     */

Returns: GainNode

Code
getOutput() {

        return this.gain;

    }

Audio.setNodeSource(audioNode: AudioNode): Audio

JSDoc:

/**
     * Sets the given audio node as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `audioNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {AudioNode} audioNode - The audio node like an instance of `OscillatorNode`.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • audioNode AudioNode

Returns: Audio

Calls:

  • this.connect
Code
setNodeSource( audioNode ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'audioNode';
        this.source = audioNode;
        this.connect();

        return this;

    }

Audio.setMediaElementSource(mediaElement: HTMLMediaElement): Audio

JSDoc:

/**
     * Sets the given media element as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `mediaNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {HTMLMediaElement} mediaElement - The media element.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • mediaElement HTMLMediaElement

Returns: Audio

Calls:

  • this.context.createMediaElementSource
  • this.connect
Code
setMediaElementSource( mediaElement ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaNode';
        this.source = this.context.createMediaElementSource( mediaElement );
        this.connect();

        return this;

    }

Audio.setMediaStreamSource(mediaStream: MediaStream): Audio

JSDoc:

/**
     * Sets the given media stream as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `mediaStreamNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {MediaStream} mediaStream - The media stream.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • mediaStream MediaStream

Returns: Audio

Calls:

  • this.context.createMediaStreamSource
  • this.connect
Code
setMediaStreamSource( mediaStream ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaStreamNode';
        this.source = this.context.createMediaStreamSource( mediaStream );
        this.connect();

        return this;

    }

Audio.setBuffer(audioBuffer: AudioBuffer): Audio

JSDoc:

/**
     * Sets the given audio buffer as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `buffer` and {@link Audio#hasPlaybackControl} to `true`.
     *
     * @param {AudioBuffer} audioBuffer - The audio buffer.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • audioBuffer AudioBuffer

Returns: Audio

Calls:

  • this.play
Code
setBuffer( audioBuffer ) {

        this.buffer = audioBuffer;
        this.sourceType = 'buffer';

        if ( this.autoplay ) this.play();

        return this;

    }

Audio.play(delay: number): Audio

JSDoc:

/**
     * Starts the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [delay=0] - The delay, in seconds, at which the audio should start playing.
     * @return {Audio|undefined} A reference to this instance.
     */

Parameters:

  • delay number

Returns: Audio

Calls:

  • console.warn
  • this.context.createBufferSource
  • this.onEnded.bind
  • source.start
  • this.setDetune
  • this.setPlaybackRate
  • this.connect
Code
play( delay = 0 ) {

        if ( this.isPlaying === true ) {

            console.warn( 'THREE.Audio: Audio is already playing.' );
            return;

        }

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._startedAt = this.context.currentTime + delay;

        const source = this.context.createBufferSource();
        source.buffer = this.buffer;
        source.loop = this.loop;
        source.loopStart = this.loopStart;
        source.loopEnd = this.loopEnd;
        source.onended = this.onEnded.bind( this );
        source.start( this._startedAt, this._progress + this.offset, this.duration );

        this.isPlaying = true;

        this.source = source;

        this.setDetune( this.detune );
        this.setPlaybackRate( this.playbackRate );

        return this.connect();

    }

Audio.pause(): Audio

JSDoc:

/**
     * Pauses the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @return {Audio|undefined} A reference to this instance.
     */

Returns: Audio

Calls:

  • console.warn
  • Math.max
  • this.source.stop

Internal Comments:

// update current progress (x4)
// ensure _progress does not exceed duration with looped audios (x4)

Code
pause() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        if ( this.isPlaying === true ) {

            // update current progress

            this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;

            if ( this.loop === true ) {

                // ensure _progress does not exceed duration with looped audios

                this._progress = this._progress % ( this.duration || this.buffer.duration );

            }

            this.source.stop();
            this.source.onended = null;

            this.isPlaying = false;

        }

        return this;

    }

Audio.stop(delay: number): Audio

JSDoc:

/**
     * Stops the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [delay=0] - The delay, in seconds, at which the audio should stop playing.
     * @return {Audio|undefined} A reference to this instance.
     */

Parameters:

  • delay number

Returns: Audio

Calls:

  • console.warn
  • this.source.stop
Code
stop( delay = 0 ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._progress = 0;

        if ( this.source !== null ) {

            this.source.stop( this.context.currentTime + delay );
            this.source.onended = null;

        }

        this.isPlaying = false;

        return this;

    }

Audio.connect(): Audio

JSDoc:

/**
     * Connects to the audio source. This is used internally on
     * initialisation and when setting / removing filters.
     *
     * @return {Audio} A reference to this instance.
     */

Returns: Audio

Calls:

  • this.source.connect
  • this.filters[ i - 1 ].connect
  • this.filters[ this.filters.length - 1 ].connect
  • this.getOutput
Code
connect() {

        if ( this.filters.length > 0 ) {

            this.source.connect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].connect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].connect( this.getOutput() );

        } else {

            this.source.connect( this.getOutput() );

        }

        this._connected = true;

        return this;

    }

Audio.disconnect(): Audio

JSDoc:

/**
     * Disconnects to the audio source. This is used internally on
     * initialisation and when setting / removing filters.
     *
     * @return {Audio|undefined} A reference to this instance.
     */

Returns: Audio

Calls:

  • this.source.disconnect
  • this.filters[ i - 1 ].disconnect
  • this.filters[ this.filters.length - 1 ].disconnect
  • this.getOutput
Code
disconnect() {

        if ( this._connected === false ) {

            return;

        }

        if ( this.filters.length > 0 ) {

            this.source.disconnect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].disconnect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );

        } else {

            this.source.disconnect( this.getOutput() );

        }

        this._connected = false;

        return this;

    }

Audio.getFilters(): AudioNode[]

JSDoc:

/**
     * Returns the current set filters.
     *
     * @return {Array<AudioNode>} The list of filters.
     */

Returns: AudioNode[]

Code
getFilters() {

        return this.filters;

    }

Audio.setFilters(value: AudioNode[]): Audio

JSDoc:

/**
     * Sets an array of filters and connects them with the audio source.
     *
     * @param {Array<AudioNode>} [value] - A list of filters.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • value AudioNode[]

Returns: Audio

Calls:

  • this.disconnect
  • value.slice
  • this.connect
Code
setFilters( value ) {

        if ( ! value ) value = [];

        if ( this._connected === true ) {

            this.disconnect();
            this.filters = value.slice();
            this.connect();

        } else {

            this.filters = value.slice();

        }

        return this;

    }

Audio.setDetune(value: number): Audio

JSDoc:

/**
     * Defines the detuning of oscillation in cents.
     *
     * @param {number} value - The detuning of oscillation in cents.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • value number

Returns: Audio

Calls:

  • this.source.detune.setTargetAtTime
Code
setDetune( value ) {

        this.detune = value;

        if ( this.isPlaying === true && this.source.detune !== undefined ) {

            this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );

        }

        return this;

    }

Audio.getDetune(): number

JSDoc:

/**
     * Returns the detuning of oscillation in cents.
     *
     * @return {number} The detuning of oscillation in cents.
     */

Returns: number

Code
getDetune() {

        return this.detune;

    }

Audio.getFilter(): AudioNode

JSDoc:

/**
     * Returns the first filter in the list of filters.
     *
     * @return {AudioNode|undefined} The first filter in the list of filters.
     */

Returns: AudioNode

Calls:

  • this.getFilters
Code
getFilter() {

        return this.getFilters()[ 0 ];

    }

Audio.setFilter(filter: AudioNode): Audio

JSDoc:

/**
     * Applies a single filter node to the audio.
     *
     * @param {AudioNode} [filter] - The filter to set.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • filter AudioNode

Returns: Audio

Calls:

  • this.setFilters
Code
setFilter( filter ) {

        return this.setFilters( filter ? [ filter ] : [] );

    }

Audio.setPlaybackRate(value: number): Audio

JSDoc:

/**
     * Sets the playback rate.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [value] - The playback rate to set.
     * @return {Audio|undefined} A reference to this instance.
     */

Parameters:

  • value number

Returns: Audio

Calls:

  • console.warn
  • this.source.playbackRate.setTargetAtTime
Code
setPlaybackRate( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.playbackRate = value;

        if ( this.isPlaying === true ) {

            this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );

        }

        return this;

    }

Audio.getPlaybackRate(): number

JSDoc:

/**
     * Returns the current playback rate.

     * @return {number} The playback rate.
     */

Returns: number

Code
getPlaybackRate() {

        return this.playbackRate;

    }

Audio.onEnded(): void

JSDoc:

/**
     * Automatically called when playback finished.
     */

Returns: void

Code
onEnded() {

        this.isPlaying = false;
        this._progress = 0;

    }

Audio.getLoop(): boolean

JSDoc:

/**
     * Returns the loop flag.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @return {boolean} Whether the audio should loop or not.
     */

Returns: boolean

Calls:

  • console.warn
Code
getLoop() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return false;

        }

        return this.loop;

    }

Audio.setLoop(value: boolean): Audio

JSDoc:

/**
     * Sets the loop flag.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {boolean} value - Whether the audio should loop or not.
     * @return {Audio|undefined} A reference to this instance.
     */

Parameters:

  • value boolean

Returns: Audio

Calls:

  • console.warn
Code
setLoop( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.loop = value;

        if ( this.isPlaying === true ) {

            this.source.loop = this.loop;

        }

        return this;

    }

Audio.setLoopStart(value: number): Audio

JSDoc:

/**
     * Sets the loop start value which defines where in the audio buffer the replay should
     * start, in seconds.
     *
     * @param {number} value - The loop start value.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • value number

Returns: Audio

Code
setLoopStart( value ) {

        this.loopStart = value;

        return this;

    }

Audio.setLoopEnd(value: number): Audio

JSDoc:

/**
     * Sets the loop end value which defines where in the audio buffer the replay should
     * stop, in seconds.
     *
     * @param {number} value - The loop end value.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • value number

Returns: Audio

Code
setLoopEnd( value ) {

        this.loopEnd = value;

        return this;

    }

Audio.getVolume(): number

JSDoc:

/**
     * Returns the volume.
     *
     * @return {number} The volume.
     */

Returns: number

Code
getVolume() {

        return this.gain.gain.value;

    }

Audio.setVolume(value: number): Audio

JSDoc:

/**
     * Sets the volume.
     *
     * @param {number} value - The volume to set.
     * @return {Audio} A reference to this instance.
     */

Parameters:

  • value number

Returns: Audio

Calls:

  • this.gain.gain.setTargetAtTime
Code
setVolume( value ) {

        this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );

        return this;

    }

Audio.copy(source: any, recursive: any): this

Parameters:

  • source any
  • recursive any

Returns: this

Calls:

  • super.copy
  • console.warn
  • source.filters.slice
Code
copy( source, recursive ) {

        super.copy( source, recursive );

        if ( source.sourceType !== 'buffer' ) {

            console.warn( 'THREE.Audio: Audio source type cannot be copied.' );

            return this;

        }

        this.autoplay = source.autoplay;

        this.buffer = source.buffer;
        this.detune = source.detune;
        this.loop = source.loop;
        this.loopStart = source.loopStart;
        this.loopEnd = source.loopEnd;
        this.offset = source.offset;
        this.duration = source.duration;
        this.playbackRate = source.playbackRate;
        this.hasPlaybackControl = source.hasPlaybackControl;
        this.sourceType = source.sourceType;

        this.filters = source.filters.slice();

        return this;

    }

Audio.clone(recursive: any): any

Parameters:

  • recursive any

Returns: any

Calls:

  • new this.constructor( this.listener ).copy
Code
clone( recursive ) {

        return new this.constructor( this.listener ).copy( this, recursive );

    }

Classes

Audio

Class Code
class Audio extends Object3D {

    /**
     * Constructs a new audio.
     *
     * @param {AudioListener} listener - The global audio listener.
     */
    constructor( listener ) {

        super();

        this.type = 'Audio';

        /**
         * The global audio listener.
         *
         * @type {AudioListener}
         * @readonly
         */
        this.listener = listener;

        /**
         * The audio context.
         *
         * @type {AudioContext}
         * @readonly
         */
        this.context = listener.context;

        /**
         * The gain node used for volume control.
         *
         * @type {GainNode}
         * @readonly
         */
        this.gain = this.context.createGain();
        this.gain.connect( listener.getInput() );

        /**
         * Whether to start playback automatically or not.
         *
         * @type {boolean}
         * @default false
         */
        this.autoplay = false;

        /**
         * A reference to an audio buffer.
         *
         * Defined via {@link Audio#setBuffer}.
         *
         * @type {?AudioBuffer}
         * @default null
         * @readonly
         */
        this.buffer = null;

        /**
         * Modify pitch, measured in cents. +/- 100 is a semitone.
         * +/- 1200 is an octave.
         *
         * Defined via {@link Audio#setDetune}.
         *
         * @type {number}
         * @default 0
         * @readonly
         */
        this.detune = 0;

        /**
         * Whether the audio should loop or not.
         *
         * Defined via {@link Audio#setLoop}.
         *
         * @type {boolean}
         * @default false
         * @readonly
         */
        this.loop = false;

        /**
         * Defines where in the audio buffer the replay should
         * start, in seconds.
         *
         * @type {number}
         * @default 0
         */
        this.loopStart = 0;

        /**
         * Defines where in the audio buffer the replay should
         * stop, in seconds.
         *
         * @type {number}
         * @default 0
         */
        this.loopEnd = 0;

        /**
         * An offset to the time within the audio buffer the playback
         * should begin, in seconds.
         *
         * @type {number}
         * @default 0
         */
        this.offset = 0;

        /**
         * Overrides the default duration of the audio.
         *
         * @type {undefined|number}
         * @default undefined
         */
        this.duration = undefined;

        /**
         * The playback speed.
         *
         * Defined via {@link Audio#setPlaybackRate}.
         *
         * @type {number}
         * @readonly
         * @default 1
         */
        this.playbackRate = 1;

        /**
         * Indicates whether the audio is playing or not.
         *
         * This flag will be automatically set when using {@link Audio#play},
         * {@link Audio#pause}, {@link Audio#stop}.
         *
         * @type {boolean}
         * @readonly
         * @default false
         */
        this.isPlaying = false;

        /**
         * Indicates whether the audio playback can be controlled
         * with method like {@link Audio#play} or {@link Audio#pause}.
         *
         * This flag will be automatically set when audio sources are
         * defined.
         *
         * @type {boolean}
         * @readonly
         * @default true
         */
        this.hasPlaybackControl = true;

        /**
         * Holds a reference to the current audio source.
         *
         * The property is automatically by one of the `set*()` methods.
         *
         * @type {?AudioNode}
         * @readonly
         * @default null
         */
        this.source = null;

        /**
         * Defines the source type.
         *
         * The property is automatically by one of the `set*()` methods.
         *
         * @type {('empty'|'audioNode'|'mediaNode'|'mediaStreamNode'|'buffer')}
         * @readonly
         * @default 'empty'
         */
        this.sourceType = 'empty';

        this._startedAt = 0;
        this._progress = 0;
        this._connected = false;

        /**
         * Can be used to apply a variety of low-order filters to create
         * more complex sound effects e.g. via `BiquadFilterNode`.
         *
         * The property is automatically set by {@link Audio#setFilters}.
         *
         * @type {Array<AudioNode>}
         * @readonly
         */
        this.filters = [];

    }

    /**
     * Returns the output audio node.
     *
     * @return {GainNode} The output node.
     */
    getOutput() {

        return this.gain;

    }

    /**
     * Sets the given audio node as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `audioNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {AudioNode} audioNode - The audio node like an instance of `OscillatorNode`.
     * @return {Audio} A reference to this instance.
     */
    setNodeSource( audioNode ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'audioNode';
        this.source = audioNode;
        this.connect();

        return this;

    }

    /**
     * Sets the given media element as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `mediaNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {HTMLMediaElement} mediaElement - The media element.
     * @return {Audio} A reference to this instance.
     */
    setMediaElementSource( mediaElement ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaNode';
        this.source = this.context.createMediaElementSource( mediaElement );
        this.connect();

        return this;

    }

    /**
     * Sets the given media stream as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `mediaStreamNode` and {@link Audio#hasPlaybackControl} to `false`.
     *
     * @param {MediaStream} mediaStream - The media stream.
     * @return {Audio} A reference to this instance.
     */
    setMediaStreamSource( mediaStream ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaStreamNode';
        this.source = this.context.createMediaStreamSource( mediaStream );
        this.connect();

        return this;

    }

    /**
     * Sets the given audio buffer as the source of this instance.
     *
     * {@link Audio#sourceType} is set to `buffer` and {@link Audio#hasPlaybackControl} to `true`.
     *
     * @param {AudioBuffer} audioBuffer - The audio buffer.
     * @return {Audio} A reference to this instance.
     */
    setBuffer( audioBuffer ) {

        this.buffer = audioBuffer;
        this.sourceType = 'buffer';

        if ( this.autoplay ) this.play();

        return this;

    }

    /**
     * Starts the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [delay=0] - The delay, in seconds, at which the audio should start playing.
     * @return {Audio|undefined} A reference to this instance.
     */
    play( delay = 0 ) {

        if ( this.isPlaying === true ) {

            console.warn( 'THREE.Audio: Audio is already playing.' );
            return;

        }

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._startedAt = this.context.currentTime + delay;

        const source = this.context.createBufferSource();
        source.buffer = this.buffer;
        source.loop = this.loop;
        source.loopStart = this.loopStart;
        source.loopEnd = this.loopEnd;
        source.onended = this.onEnded.bind( this );
        source.start( this._startedAt, this._progress + this.offset, this.duration );

        this.isPlaying = true;

        this.source = source;

        this.setDetune( this.detune );
        this.setPlaybackRate( this.playbackRate );

        return this.connect();

    }

    /**
     * Pauses the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @return {Audio|undefined} A reference to this instance.
     */
    pause() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        if ( this.isPlaying === true ) {

            // update current progress

            this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;

            if ( this.loop === true ) {

                // ensure _progress does not exceed duration with looped audios

                this._progress = this._progress % ( this.duration || this.buffer.duration );

            }

            this.source.stop();
            this.source.onended = null;

            this.isPlaying = false;

        }

        return this;

    }

    /**
     * Stops the playback of the audio.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [delay=0] - The delay, in seconds, at which the audio should stop playing.
     * @return {Audio|undefined} A reference to this instance.
     */
    stop( delay = 0 ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._progress = 0;

        if ( this.source !== null ) {

            this.source.stop( this.context.currentTime + delay );
            this.source.onended = null;

        }

        this.isPlaying = false;

        return this;

    }

    /**
     * Connects to the audio source. This is used internally on
     * initialisation and when setting / removing filters.
     *
     * @return {Audio} A reference to this instance.
     */
    connect() {

        if ( this.filters.length > 0 ) {

            this.source.connect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].connect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].connect( this.getOutput() );

        } else {

            this.source.connect( this.getOutput() );

        }

        this._connected = true;

        return this;

    }

    /**
     * Disconnects to the audio source. This is used internally on
     * initialisation and when setting / removing filters.
     *
     * @return {Audio|undefined} A reference to this instance.
     */
    disconnect() {

        if ( this._connected === false ) {

            return;

        }

        if ( this.filters.length > 0 ) {

            this.source.disconnect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].disconnect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );

        } else {

            this.source.disconnect( this.getOutput() );

        }

        this._connected = false;

        return this;

    }

    /**
     * Returns the current set filters.
     *
     * @return {Array<AudioNode>} The list of filters.
     */
    getFilters() {

        return this.filters;

    }

    /**
     * Sets an array of filters and connects them with the audio source.
     *
     * @param {Array<AudioNode>} [value] - A list of filters.
     * @return {Audio} A reference to this instance.
     */
    setFilters( value ) {

        if ( ! value ) value = [];

        if ( this._connected === true ) {

            this.disconnect();
            this.filters = value.slice();
            this.connect();

        } else {

            this.filters = value.slice();

        }

        return this;

    }

    /**
     * Defines the detuning of oscillation in cents.
     *
     * @param {number} value - The detuning of oscillation in cents.
     * @return {Audio} A reference to this instance.
     */
    setDetune( value ) {

        this.detune = value;

        if ( this.isPlaying === true && this.source.detune !== undefined ) {

            this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );

        }

        return this;

    }

    /**
     * Returns the detuning of oscillation in cents.
     *
     * @return {number} The detuning of oscillation in cents.
     */
    getDetune() {

        return this.detune;

    }

    /**
     * Returns the first filter in the list of filters.
     *
     * @return {AudioNode|undefined} The first filter in the list of filters.
     */
    getFilter() {

        return this.getFilters()[ 0 ];

    }

    /**
     * Applies a single filter node to the audio.
     *
     * @param {AudioNode} [filter] - The filter to set.
     * @return {Audio} A reference to this instance.
     */
    setFilter( filter ) {

        return this.setFilters( filter ? [ filter ] : [] );

    }

    /**
     * Sets the playback rate.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {number} [value] - The playback rate to set.
     * @return {Audio|undefined} A reference to this instance.
     */
    setPlaybackRate( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.playbackRate = value;

        if ( this.isPlaying === true ) {

            this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );

        }

        return this;

    }

    /**
     * Returns the current playback rate.

     * @return {number} The playback rate.
     */
    getPlaybackRate() {

        return this.playbackRate;

    }

    /**
     * Automatically called when playback finished.
     */
    onEnded() {

        this.isPlaying = false;
        this._progress = 0;

    }

    /**
     * Returns the loop flag.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @return {boolean} Whether the audio should loop or not.
     */
    getLoop() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return false;

        }

        return this.loop;

    }

    /**
     * Sets the loop flag.
     *
     * Can only be used with compatible audio sources that allow playback control.
     *
     * @param {boolean} value - Whether the audio should loop or not.
     * @return {Audio|undefined} A reference to this instance.
     */
    setLoop( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.loop = value;

        if ( this.isPlaying === true ) {

            this.source.loop = this.loop;

        }

        return this;

    }

    /**
     * Sets the loop start value which defines where in the audio buffer the replay should
     * start, in seconds.
     *
     * @param {number} value - The loop start value.
     * @return {Audio} A reference to this instance.
     */
    setLoopStart( value ) {

        this.loopStart = value;

        return this;

    }

    /**
     * Sets the loop end value which defines where in the audio buffer the replay should
     * stop, in seconds.
     *
     * @param {number} value - The loop end value.
     * @return {Audio} A reference to this instance.
     */
    setLoopEnd( value ) {

        this.loopEnd = value;

        return this;

    }

    /**
     * Returns the volume.
     *
     * @return {number} The volume.
     */
    getVolume() {

        return this.gain.gain.value;

    }

    /**
     * Sets the volume.
     *
     * @param {number} value - The volume to set.
     * @return {Audio} A reference to this instance.
     */
    setVolume( value ) {

        this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );

        return this;

    }

    copy( source, recursive ) {

        super.copy( source, recursive );

        if ( source.sourceType !== 'buffer' ) {

            console.warn( 'THREE.Audio: Audio source type cannot be copied.' );

            return this;

        }

        this.autoplay = source.autoplay;

        this.buffer = source.buffer;
        this.detune = source.detune;
        this.loop = source.loop;
        this.loopStart = source.loopStart;
        this.loopEnd = source.loopEnd;
        this.offset = source.offset;
        this.duration = source.duration;
        this.playbackRate = source.playbackRate;
        this.hasPlaybackControl = source.hasPlaybackControl;
        this.sourceType = source.sourceType;

        this.filters = source.filters.slice();

        return this;

    }

    clone( recursive ) {

        return new this.constructor( this.listener ).copy( this, recursive );

    }

}

Methods

getOutput(): GainNode
Code
getOutput() {

        return this.gain;

    }
setNodeSource(audioNode: AudioNode): Audio
Code
setNodeSource( audioNode ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'audioNode';
        this.source = audioNode;
        this.connect();

        return this;

    }
setMediaElementSource(mediaElement: HTMLMediaElement): Audio
Code
setMediaElementSource( mediaElement ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaNode';
        this.source = this.context.createMediaElementSource( mediaElement );
        this.connect();

        return this;

    }
setMediaStreamSource(mediaStream: MediaStream): Audio
Code
setMediaStreamSource( mediaStream ) {

        this.hasPlaybackControl = false;
        this.sourceType = 'mediaStreamNode';
        this.source = this.context.createMediaStreamSource( mediaStream );
        this.connect();

        return this;

    }
setBuffer(audioBuffer: AudioBuffer): Audio
Code
setBuffer( audioBuffer ) {

        this.buffer = audioBuffer;
        this.sourceType = 'buffer';

        if ( this.autoplay ) this.play();

        return this;

    }
play(delay: number): Audio
Code
play( delay = 0 ) {

        if ( this.isPlaying === true ) {

            console.warn( 'THREE.Audio: Audio is already playing.' );
            return;

        }

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._startedAt = this.context.currentTime + delay;

        const source = this.context.createBufferSource();
        source.buffer = this.buffer;
        source.loop = this.loop;
        source.loopStart = this.loopStart;
        source.loopEnd = this.loopEnd;
        source.onended = this.onEnded.bind( this );
        source.start( this._startedAt, this._progress + this.offset, this.duration );

        this.isPlaying = true;

        this.source = source;

        this.setDetune( this.detune );
        this.setPlaybackRate( this.playbackRate );

        return this.connect();

    }
pause(): Audio
Code
pause() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        if ( this.isPlaying === true ) {

            // update current progress

            this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;

            if ( this.loop === true ) {

                // ensure _progress does not exceed duration with looped audios

                this._progress = this._progress % ( this.duration || this.buffer.duration );

            }

            this.source.stop();
            this.source.onended = null;

            this.isPlaying = false;

        }

        return this;

    }
stop(delay: number): Audio
Code
stop( delay = 0 ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this._progress = 0;

        if ( this.source !== null ) {

            this.source.stop( this.context.currentTime + delay );
            this.source.onended = null;

        }

        this.isPlaying = false;

        return this;

    }
connect(): Audio
Code
connect() {

        if ( this.filters.length > 0 ) {

            this.source.connect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].connect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].connect( this.getOutput() );

        } else {

            this.source.connect( this.getOutput() );

        }

        this._connected = true;

        return this;

    }
disconnect(): Audio
Code
disconnect() {

        if ( this._connected === false ) {

            return;

        }

        if ( this.filters.length > 0 ) {

            this.source.disconnect( this.filters[ 0 ] );

            for ( let i = 1, l = this.filters.length; i < l; i ++ ) {

                this.filters[ i - 1 ].disconnect( this.filters[ i ] );

            }

            this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );

        } else {

            this.source.disconnect( this.getOutput() );

        }

        this._connected = false;

        return this;

    }
getFilters(): AudioNode[]
Code
getFilters() {

        return this.filters;

    }
setFilters(value: AudioNode[]): Audio
Code
setFilters( value ) {

        if ( ! value ) value = [];

        if ( this._connected === true ) {

            this.disconnect();
            this.filters = value.slice();
            this.connect();

        } else {

            this.filters = value.slice();

        }

        return this;

    }
setDetune(value: number): Audio
Code
setDetune( value ) {

        this.detune = value;

        if ( this.isPlaying === true && this.source.detune !== undefined ) {

            this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );

        }

        return this;

    }
getDetune(): number
Code
getDetune() {

        return this.detune;

    }
getFilter(): AudioNode
Code
getFilter() {

        return this.getFilters()[ 0 ];

    }
setFilter(filter: AudioNode): Audio
Code
setFilter( filter ) {

        return this.setFilters( filter ? [ filter ] : [] );

    }
setPlaybackRate(value: number): Audio
Code
setPlaybackRate( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.playbackRate = value;

        if ( this.isPlaying === true ) {

            this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );

        }

        return this;

    }
getPlaybackRate(): number
Code
getPlaybackRate() {

        return this.playbackRate;

    }
onEnded(): void
Code
onEnded() {

        this.isPlaying = false;
        this._progress = 0;

    }
getLoop(): boolean
Code
getLoop() {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return false;

        }

        return this.loop;

    }
setLoop(value: boolean): Audio
Code
setLoop( value ) {

        if ( this.hasPlaybackControl === false ) {

            console.warn( 'THREE.Audio: this Audio has no playback control.' );
            return;

        }

        this.loop = value;

        if ( this.isPlaying === true ) {

            this.source.loop = this.loop;

        }

        return this;

    }
setLoopStart(value: number): Audio
Code
setLoopStart( value ) {

        this.loopStart = value;

        return this;

    }
setLoopEnd(value: number): Audio
Code
setLoopEnd( value ) {

        this.loopEnd = value;

        return this;

    }
getVolume(): number
Code
getVolume() {

        return this.gain.gain.value;

    }
setVolume(value: number): Audio
Code
setVolume( value ) {

        this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );

        return this;

    }
copy(source: any, recursive: any): this
Code
copy( source, recursive ) {

        super.copy( source, recursive );

        if ( source.sourceType !== 'buffer' ) {

            console.warn( 'THREE.Audio: Audio source type cannot be copied.' );

            return this;

        }

        this.autoplay = source.autoplay;

        this.buffer = source.buffer;
        this.detune = source.detune;
        this.loop = source.loop;
        this.loopStart = source.loopStart;
        this.loopEnd = source.loopEnd;
        this.offset = source.offset;
        this.duration = source.duration;
        this.playbackRate = source.playbackRate;
        this.hasPlaybackControl = source.hasPlaybackControl;
        this.sourceType = source.sourceType;

        this.filters = source.filters.slice();

        return this;

    }
clone(recursive: any): any
Code
clone( recursive ) {

        return new this.constructor( this.listener ).copy( this, recursive );

    }