function FileLoader( URL, context, onloadCallback, onProgressCallback ) {
    if ( !( this instanceof FileLoader ) ) {
        throw new TypeError( "FileLoader constructor cannot be called as a function." );
    }
    var rawBuffer_;
    var loopStart_ = 0;
    var loopEnd_ = 0;

    var isSoundLoaded_ = false;

    // Private functions

    /**
     * Check if a value is an integer.
     * @method isInt_
     * @private
     * @param {Object} value
     * @return {Boolean} Result of test.
     */
    var isInt_ = function ( value ) {
        var er = /^[0-9]+$/;
        if ( er.test( value ) ) {
            return true;
        }
        return false;
    };

    /**
     * Get a buffer based on the start and end markers.
     * @private
     * @method sliceBuffer
     * @param {Number} start The start of the buffer to load.
     * @param {Number} end The end of the buffer to load.
     * @return {AudioBuffer} The requested sliced buffer.
     */
    var sliceBuffer_ = function ( start, end ) {

        // Set end if it is missing
        if ( typeof end == 'undefined' ) {
            end = rawBuffer_.length;
        }
        // Verify parameters
        if ( !isInt_( start ) ) {
            start = Number.isNan( start ) ? 0 : Math.round( Number( start ) );
            log.debug( "Incorrect parameter Type - FileLoader getBuffer start parameter is not an integer. Coercing it to an Integer - start" );
        } else if ( !isInt_( end ) ) {
            log.debug( "Incorrect parameter Type - FileLoader getBuffer end parameter is not an integer" );
            end = Number.isNan( end ) ? 0 : Math.round( Number( end ) );
        }
        // Check if start is smaller than end
        if ( start > end ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter " + start + " should be smaller than end parameter " + end + " . Setting them to the same value " + start );
            end = start;
        }
        // Check if start is within the buffer size
        if ( start > loopEnd_ || start < loopStart_ ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_.length + " . Setting start to " + loopStart_ );
            start = loopStart_;
        }

        // Check if end is within the buffer size
        if ( end > loopEnd_ || end < loopStart_ ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_.length + " . Setting start to " + loopEnd_ );
            end = loopEnd_;
        }

        var length = end - start;

        if ( !rawBuffer_ ) {
            log.error( "No Buffer Found - Buffer loading has not completed or has failed." );
            return null;
        }

        // Create the new buffer
        var newBuffer = context.createBuffer( rawBuffer_.numberOfChannels, length, rawBuffer_.sampleRate );

        // Start trimming
        for ( var i = 0; i < rawBuffer_.numberOfChannels; i++ ) {
            var aData = new Float32Array( rawBuffer_.getChannelData( i ) );
            newBuffer.getChannelData( i )
                .set( aData.subarray( start, end ) );
        }

        return newBuffer;
    };

    function init() {
        var parameterType = Object.prototype.toString.call( URL );
        var fileExtension = /[^.]+$/.exec( URL );
        if ( parameterType === '[object String]' ) {
            var request = new XMLHttpRequest();
            request.open( 'GET', URL, true );
            request.responseType = 'arraybuffer';
            request.addEventListener( 'progress', onProgressCallback, false );
            request.onload = function () {
                decodeAudio( request.response, fileExtension );
            };
            request.send();
        } else if ( parameterType === '[object File]' || parameterType === '[object Blob]' ) {
            var reader = new FileReader();
            reader.addEventListener( 'progress', onProgressCallback, false );
            reader.onload = function () {
                decodeAudio( reader.result, fileExtension );
            };
            reader.readAsArrayBuffer( URL );
        }

    }

    function decodeAudio( result, fileExt ) {
        context.decodeAudioData( result, function ( buffer ) {
            isSoundLoaded_ = true;
            rawBuffer_ = buffer;
            // Do trimming if it is not a wave file
            loopStart_ = 0;
            loopEnd_ = rawBuffer_.length;
            if ( fileExt[ 0 ] !== 'wav' ) {
                // Trim Buffer based on Markers
                var markers = detectLoopMarkers( rawBuffer_ );
                if ( markers ) {
                    loopStart_ = markers.start;
                    loopEnd_ = markers.end;
                }
            }
            if ( onloadCallback && typeof onloadCallback === 'function' ) {
                onloadCallback( true );
            }
        }, function () {
            log.error( "Error Decoding " + URL );
            if ( onloadCallback && typeof onloadCallback === 'function' ) {
                onloadCallback( false );
            }
        } );
    }

    // Public functions
    /**
     * Get the current buffer.
     * @method getBuffer
     * @param {Number} start The start index
     * @param {Number} end The end index
     * @return {AudioBuffer} The AudioBuffer that was marked then trimmed if it is not a wav file.
     */
    this.getBuffer = function ( start, end ) {
        // Set start if it is missing
        if ( typeof start == 'undefined' ) {
            start = 0;
        }
        // Set end if it is missing
        if ( typeof end == 'undefined' ) {
            end = loopEnd_ - loopStart_;
        }

        return sliceBuffer_( loopStart_ + start, loopStart_ + end );
    };

    /**
     * Get the original buffer.
     * @method getRawBuffer
     * @return {AudioBuffer} The original AudioBuffer.
     */
    this.getRawBuffer = function () {
        if ( !isSoundLoaded_ ) {
            log.error( "No Buffer Found - Buffer loading has not completed or has failed." );
            return null;
        }
        return rawBuffer_;
    };

    /**
     * Check if sound is already loaded.
     * @method isLoaded
     * @return {Boolean} True if file is loaded. Flase if file is not yeat loaded.
     */
    this.isLoaded = function () {
        return isSoundLoaded_;
    };

    // Make a request
    init();
}
/**
 * Load a single file from a URL or a File object.
 *
 * @class FileLoader
 * @constructor
 * @param {String/File} URL URL of the file to be Loaded
 * @param {String} context AudioContext to be used in decoding the file
 * @param {Function} [onloadCallback] Callback function to be called when the file loading is
 * @param {Function} [onProgressCallback] Callback function to access the progress of the file loading.
 */
Load a single file from a URL or a File object.
Load a single file from a URL or a File object .
function FileLoader( URL, context, onloadCallback, onProgressCallback ) {
    if ( !( this instanceof FileLoader ) ) {
        throw new TypeError( "FileLoader constructor cannot be called as a function." );
    }
    var rawBuffer_;
    var loopStart_ = 0;
    var loopEnd_ = 0;
    var isSoundLoaded_ = false;
    var isInt_ = function ( value ) {
        var er = /^[0-9]+$/;
        if ( er.test( value ) ) {
            return true;
        }
        return false;
    };
    var sliceBuffer_ = function ( start, end ) {
        if ( typeof end == 'undefined' ) {
            end = rawBuffer_.length;
        }
        if ( !isInt_( start ) ) {
            start = Number.isNan( start ) ? 0 : Math.round( Number( start ) );
            log.debug( "Incorrect parameter Type - FileLoader getBuffer start parameter is not an integer. Coercing it to an Integer - start" );
        } else if ( !isInt_( end ) ) {
            log.debug( "Incorrect parameter Type - FileLoader getBuffer end parameter is not an integer" );
            end = Number.isNan( end ) ? 0 : Math.round( Number( end ) );
        }
        if ( start > end ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter " + start + " should be smaller than end parameter " + end + " . Setting them to the same value " + start );
            end = start;
        }
        if ( start > loopEnd_ || start < loopStart_ ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_.length + " . Setting start to " + loopStart_ );
            start = loopStart_;
        }
        if ( end > loopEnd_ || end < loopStart_ ) {
            log.warn( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_.length + " . Setting start to " + loopEnd_ );
            end = loopEnd_;
        }
        var length = end - start;
        if ( !rawBuffer_ ) {
            log.error( "No Buffer Found - Buffer loading has not completed or has failed." );
            return null;
        }
        var newBuffer = context.createBuffer( rawBuffer_.numberOfChannels, length, rawBuffer_.sampleRate );
        for ( var i = 0; i < rawBuffer_.numberOfChannels; i++ ) {
            var aData = new Float32Array( rawBuffer_.getChannelData( i ) );
            newBuffer.getChannelData( i )
                .set( aData.subarray( start, end ) );
        }
        return newBuffer;
    };
    function init() {
        var parameterType = Object.prototype.toString.call( URL );
        var fileExtension = /[^.]+$/.exec( URL );
        if ( parameterType === '[object String]' ) {
            var request = new XMLHttpRequest();
            request.open( 'GET', URL, true );
            request.responseType = 'arraybuffer';
            request.addEventListener( 'progress', onProgressCallback, false );
            request.onload = function () {
                decodeAudio( request.response, fileExtension );
            };
            request.send();
        } else if ( parameterType === '[object File]' || parameterType === '[object Blob]' ) {
            var reader = new FileReader();
            reader.addEventListener( 'progress', onProgressCallback, false );
            reader.onload = function () {
                decodeAudio( reader.result, fileExtension );
            };
            reader.readAsArrayBuffer( URL );
        }
    }
    function decodeAudio( result, fileExt ) {
        context.decodeAudioData( result, function ( buffer ) {
            isSoundLoaded_ = true;
            rawBuffer_ = buffer;
            loopStart_ = 0;
            loopEnd_ = rawBuffer_.length;
            if ( fileExt[ 0 ] !== 'wav' ) {
                var markers = detectLoopMarkers( rawBuffer_ );
                if ( markers ) {
                    loopStart_ = markers.start;
                    loopEnd_ = markers.end;
                }
            }
            if ( onloadCallback && typeof onloadCallback === 'function' ) {
                onloadCallback( true );
            }
        }, function () {
            log.error( "Error Decoding " + URL );
            if ( onloadCallback && typeof onloadCallback === 'function' ) {
                onloadCallback( false );
            }
        } );
    }
    this.getBuffer = function ( start, end ) {
        if ( typeof start == 'undefined' ) {
            start = 0;
        }
        if ( typeof end == 'undefined' ) {
            end = loopEnd_ - loopStart_;
        }
        return sliceBuffer_( loopStart_ + start, loopStart_ + end );
    };
    this.getRawBuffer = function () {
        if ( !isSoundLoaded_ ) {
            log.error( "No Buffer Found - Buffer loading has not completed or has failed." );
            return null;
        }
        return rawBuffer_;
    };
    this.isLoaded = function () {
        return isSoundLoaded_;
    };
    init();
}
function FileLoader ( URL , context , onloadCallback , onProgressCallback ) { if ( ! ( this instanceof FileLoader ) ) { throw new TypeError ( "FileLoader constructor cannot be called as a function." ) ; } var rawBuffer_ ; var loopStart_ = 0 ; var loopEnd_ = 0 ; var isSoundLoaded_ = false ; var isInt_ = function ( value ) { var er = / ^[0-9]+$ / ; if ( er . test ( value ) ) { return true ; } return false ; } ; var sliceBuffer_ = function ( start , end ) { if ( typeof end == 'undefined' ) { end = rawBuffer_ . length ; } if ( ! isInt_ ( start ) ) { start = Number . isNan ( start ) ? 0 : Math . round ( Number ( start ) ) ; log . debug ( "Incorrect parameter Type - FileLoader getBuffer start parameter is not an integer. Coercing it to an Integer - start" ) ; } else if ( ! isInt_ ( end ) ) { log . debug ( "Incorrect parameter Type - FileLoader getBuffer end parameter is not an integer" ) ; end = Number . isNan ( end ) ? 0 : Math . round ( Number ( end ) ) ; } if ( start > end ) { log . warn ( "Incorrect parameter Type - FileLoader getBuffer start parameter " + start + " should be smaller than end parameter " + end + " . Setting them to the same value " + start ) ; end = start ; } if ( start > loopEnd_ || start < loopStart_ ) { log . warn ( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_ . length + " . Setting start to " + loopStart_ ) ; start = loopStart_ ; } if ( end > loopEnd_ || end < loopStart_ ) { log . warn ( "Incorrect parameter Type - FileLoader getBuffer start parameter should be within the buffer size : 0-" + rawBuffer_ . length + " . Setting start to " + loopEnd_ ) ; end = loopEnd_ ; } var length = end - start ; if ( ! rawBuffer_ ) { log . error ( "No Buffer Found - Buffer loading has not completed or has failed." ) ; return null ; } var newBuffer = context . createBuffer ( rawBuffer_ . numberOfChannels , length , rawBuffer_ . sampleRate ) ; for ( var i = 0 ; i < rawBuffer_ . numberOfChannels ; i ++ ) { var aData = new Float32Array ( rawBuffer_ . getChannelData ( i ) ) ; newBuffer . getChannelData ( i ) . set ( aData . subarray ( start , end ) ) ; } return newBuffer ; } ; function init ( ) { var parameterType = Object . prototype . toString . call ( URL ) ; var fileExtension = / [^.]+$ / . exec ( URL ) ; if ( parameterType === '[object String]' ) { var request = new XMLHttpRequest ( ) ; request . open ( 'GET' , URL , true ) ; request . responseType = 'arraybuffer' ; request . addEventListener ( 'progress' , onProgressCallback , false ) ; request . onload = function ( ) { decodeAudio ( request . response , fileExtension ) ; } ; request . send ( ) ; } else if ( parameterType === '[object File]' || parameterType === '[object Blob]' ) { var reader = new FileReader ( ) ; reader . addEventListener ( 'progress' , onProgressCallback , false ) ; reader . onload = function ( ) { decodeAudio ( reader . result , fileExtension ) ; } ; reader . readAsArrayBuffer ( URL ) ; } } function decodeAudio ( result , fileExt ) { context . decodeAudioData ( result , function ( buffer ) { isSoundLoaded_ = true ; rawBuffer_ = buffer ; loopStart_ = 0 ; loopEnd_ = rawBuffer_ . length ; if ( fileExt [ 0 ] !== 'wav' ) { var markers = detectLoopMarkers ( rawBuffer_ ) ; if ( markers ) { loopStart_ = markers . start ; loopEnd_ = markers . end ; } } if ( onloadCallback && typeof onloadCallback === 'function' ) { onloadCallback ( true ) ; } } , function ( ) { log . error ( "Error Decoding " + URL ) ; if ( onloadCallback && typeof onloadCallback === 'function' ) { onloadCallback ( false ) ; } } ) ; } this . getBuffer = function ( start , end ) { if ( typeof start == 'undefined' ) { start = 0 ; } if ( typeof end == 'undefined' ) { end = loopEnd_ - loopStart_ ; } return sliceBuffer_ ( loopStart_ + start , loopStart_ + end ) ; } ; this . getRawBuffer = function ( ) { if ( ! isSoundLoaded_ ) { log . error ( "No Buffer Found - Buffer loading has not completed or has failed." ) ; return null ; } return rawBuffer_ ; } ; this . isLoaded = function ( ) { return isSoundLoaded_ ; } ; init ( ) ; }
Load a single file from a URL or a File object.
Load a single file from a URL or a File object .
// Private functions /**
     * Check if a value is an integer.
     * @method isInt_
     * @private
     * @param {Object} value
     * @return {Boolean} Result of test.
     */ /**
     * Get a buffer based on the start and end markers.
     * @private
     * @method sliceBuffer
     * @param {Number} start The start of the buffer to load.
     * @param {Number} end The end of the buffer to load.
     * @return {AudioBuffer} The requested sliced buffer.
     */ // Set end if it is missing // Verify parameters // Check if start is smaller than end // Check if start is within the buffer size // Check if end is within the buffer size // Create the new buffer // Start trimming // Do trimming if it is not a wave file // Trim Buffer based on Markers // Public functions /**
     * Get the current buffer.
     * @method getBuffer
     * @param {Number} start The start index
     * @param {Number} end The end index
     * @return {AudioBuffer} The AudioBuffer that was marked then trimmed if it is not a wav file.
     */ // Set start if it is missing // Set end if it is missing /**
     * Get the original buffer.
     * @method getRawBuffer
     * @return {AudioBuffer} The original AudioBuffer.
     */ /**
     * Check if sound is already loaded.
     * @method isLoaded
     * @return {Boolean} True if file is loaded. Flase if file is not yeat loaded.
     */ // Make a request