{"version":3,"file":"soundtouch.min.js","sources":["../src/soundtouch.js"],"sourcesContent":["/*\n * SoundTouch JS audio processing library\n * Copyright (c) Olli Parviainen\n * Copyright (c) Ryan Berdeen\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n */\n\n/**\n * root is our root object context, ie. window if we are in a browser\n * factory is a method that builds and returns our module\n */\n(function(root, factory) {\n    // If AMD is available, use the define() method to load our dependencies\n    //and declare our module\n    if (typeof define === 'function' && define.amd) {\n        define([], function() {\n            return factory(root);\n        });\n    }\n    // Otherwise we will attach our module to root, and pass references to our\n    // dependencies into the factory. We're assuming that our dependencies are\n    // also attached to root here, but they could come from anywhere\n    else\n    {\n        root.CloudPoodll = factory(root);\n    }\n})(this, function() {\n    /**\n     * Giving this value for the sequence length sets automatic parameter value\n     * according to tempo setting (recommended)\n     */\n    var USE_AUTO_SEQUENCE_LEN = 0;\n\n    /**\n     * Default length of a single processing sequence, in milliseconds. This determines to how\n     * long sequences the original sound is chopped in the time-stretch algorithm.\n     *\n     * The larger this value is, the lesser sequences are used in processing. In principle\n     * a bigger value sounds better when slowing down tempo, but worse when increasing tempo\n     * and vice versa.\n     *\n     * Increasing this value reduces computational burden and vice versa.\n     */\n        //var DEFAULT_SEQUENCE_MS = 130\n    var DEFAULT_SEQUENCE_MS = USE_AUTO_SEQUENCE_LEN;\n\n    /**\n     * Giving this value for the seek window length sets automatic parameter value\n     * according to tempo setting (recommended)\n     */\n    var USE_AUTO_SEEKWINDOW_LEN = 0;\n\n    /**\n     * Seeking window default length in milliseconds for algorithm that finds the best possible\n     * overlapping location. This determines from how wide window the algorithm may look for an\n     * optimal joining location when mixing the sound sequences back together.\n     *\n     * The bigger this window setting is, the higher the possibility to find a better mixing\n     * position will become, but at the same time large values may cause a \"drifting\" artifact\n     * because consequent sequences will be taken at more uneven intervals.\n     *\n     * If there's a disturbing artifact that sounds as if a constant frequency was drifting\n     * around, try reducing this setting.\n     *\n     * Increasing this value increases computational burden and vice versa.\n     */\n        //var DEFAULT_SEEKWINDOW_MS = 25;\n    var DEFAULT_SEEKWINDOW_MS = USE_AUTO_SEEKWINDOW_LEN;\n\n    /**\n     * Overlap length in milliseconds. When the chopped sound sequences are mixed back together,\n     * to form a continuous sound stream, this parameter defines over how long period the two\n     * consecutive sequences are let to overlap each other.\n     *\n     * This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting\n     * by a large amount, you might wish to try a smaller value on this.\n     *\n     * Increasing this value increases computational burden and vice versa.\n     */\n    var DEFAULT_OVERLAP_MS = 8;\n\n    // Table for the hierarchical mixing position seeking algorithm\n    var _SCAN_OFFSETS = [\n        [\n            124,\n            186,\n            248,\n            310,\n            372,\n            434,\n            496,\n            558,\n            620,\n            682,\n            744,\n            806,\n            868,\n            930,\n            992,\n            1054,\n            1116,\n            1178,\n            1240,\n            1302,\n            1364,\n            1426,\n            1488,\n            0\n        ],\n        [\n            -100,\n            -75,\n            -50,\n            -25,\n            25,\n            50,\n            75,\n            100,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0\n        ],\n        [\n            -20,\n            -15,\n            -10,\n            -5,\n            5,\n            10,\n            15,\n            20,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0\n        ],\n        [\n            -4,\n            -3,\n            -2,\n            -1,\n            1,\n            2,\n            3,\n            4,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0,\n            0\n        ]\n    ];\n\n    // Adjust tempo param according to tempo, so that variating processing sequence length is used\n    // at varius tempo settings, between the given low...top limits\n    var AUTOSEQ_TEMPO_LOW = 0.5; // auto setting low tempo range (-50%)\n    var AUTOSEQ_TEMPO_TOP = 2.0; // auto setting top tempo range (+100%)\n\n    // sequence-ms setting values at above low & top tempo\n    var AUTOSEQ_AT_MIN = 125.0;\n    var AUTOSEQ_AT_MAX = 50.0;\n    var AUTOSEQ_K =\n        (AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) /\n        (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW);\n    var AUTOSEQ_C = AUTOSEQ_AT_MIN - AUTOSEQ_K * AUTOSEQ_TEMPO_LOW;\n\n    // seek-window-ms setting values at above low & top tempo\n    var AUTOSEEK_AT_MIN = 25.0;\n    var AUTOSEEK_AT_MAX = 15.0;\n    var AUTOSEEK_K =\n        (AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) /\n        (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW);\n    var AUTOSEEK_C = AUTOSEEK_AT_MIN - AUTOSEEK_K * AUTOSEQ_TEMPO_LOW;\n\n    function extend(a, b) {\n        for (var i in b) {\n            var g = b.__lookupGetter__(i),\n                s = b.__lookupSetter__(i);\n            if (g || s) {\n                if (g) {\n                    a.__defineGetter__(i, g);\n                }\n                if (s) {\n                    a.__defineSetter__(i, s);\n                }\n            } else {\n                a[i] = b[i];\n            }\n        }\n        return a;\n    }\n\n    function testFloatEqual(a, b) {\n        return (a > b ? a - b : b - a) > 1e-10;\n    }\n\n    function AbstractFifoSamplePipe(createBuffers) {\n        if (createBuffers) {\n            this.inputBuffer = new FifoSampleBuffer();\n            this.outputBuffer = new FifoSampleBuffer();\n        } else {\n            this.inputBuffer = this.outputBuffer = null;\n        }\n    }\n    AbstractFifoSamplePipe.prototype = {\n        get inputBuffer() {\n            return this._inputBuffer;\n        },\n        set inputBuffer(inputBuffer) {\n            this._inputBuffer = inputBuffer;\n        },\n        get outputBuffer() {\n            return this._outputBuffer;\n        },\n        set outputBuffer(outputBuffer) {\n            this._outputBuffer = outputBuffer;\n        },\n        clear: function() {\n            this._inputBuffer.clear();\n            this._outputBuffer.clear();\n        }\n    };\n\n    function RateTransposer(createBuffers) {\n        AbstractFifoSamplePipe.call(this, createBuffers);\n        this._reset();\n        this.rate = 1;\n    }\n    extend(RateTransposer.prototype, AbstractFifoSamplePipe.prototype);\n    extend(RateTransposer.prototype, {\n        set rate(rate) {\n            this._rate = rate;\n            // TODO aa filter\n        },\n        _reset: function() {\n            this.slopeCount = 0;\n            this.prevSampleL = 0;\n            this.prevSampleR = 0;\n        },\n        process: function() {\n            // TODO aa filter\n            var numFrames = this._inputBuffer.frameCount;\n            this._outputBuffer.ensureAdditionalCapacity(\n                numFrames / this._rate + 1\n            );\n            var numFramesOutput = this._transpose(numFrames);\n            this._inputBuffer.receive();\n            this._outputBuffer.put(numFramesOutput);\n        },\n        _transpose: function(numFrames) {\n            if (numFrames === 0) {\n                return 0; // No work.\n            }\n\n            var src = this._inputBuffer.vector;\n            var srcOffset = this._inputBuffer.startIndex;\n\n            var dest = this._outputBuffer.vector;\n            var destOffset = this._outputBuffer.endIndex;\n\n            var used = 0;\n            var i = 0;\n\n            while (this.slopeCount < 1.0) {\n                dest[destOffset + 2 * i] =\n                    (1.0 - this.slopeCount) * this.prevSampleL +\n                    this.slopeCount * src[srcOffset];\n                dest[destOffset + 2 * i + 1] =\n                    (1.0 - this.slopeCount) * this.prevSampleR +\n                    this.slopeCount * src[srcOffset + 1];\n                i++;\n                this.slopeCount += this._rate;\n            }\n\n            this.slopeCount -= 1.0;\n\n            if (numFrames != 1) {\n                // eslint-disable-next-line no-constant-condition\n                out: while (true) {\n                    while (this.slopeCount > 1.0) {\n                        this.slopeCount -= 1.0;\n                        used++;\n                        if (used >= numFrames - 1) {\n                            break out;\n                        }\n                    }\n\n                    var srcIndex = srcOffset + 2 * used;\n                    dest[destOffset + 2 * i] =\n                        (1.0 - this.slopeCount) * src[srcIndex] +\n                        this.slopeCount * src[srcIndex + 2];\n                    dest[destOffset + 2 * i + 1] =\n                        (1.0 - this.slopeCount) * src[srcIndex + 1] +\n                        this.slopeCount * src[srcIndex + 3];\n\n                    i++;\n                    this.slopeCount += this._rate;\n                }\n            }\n\n            this.prevSampleL = src[srcOffset + 2 * numFrames - 2];\n            this.prevSampleR = src[srcOffset + 2 * numFrames - 1];\n\n            return i;\n        }\n    });\n\n    function FifoSampleBuffer() {\n        this._vector = new Float32Array();\n        this._position = 0;\n        this._frameCount = 0;\n    }\n    FifoSampleBuffer.prototype = {\n        get vector() {\n            return this._vector;\n        },\n        get position() {\n            return this._position;\n        },\n        get startIndex() {\n            return this._position * 2;\n        },\n        get frameCount() {\n            return this._frameCount;\n        },\n        get endIndex() {\n            return (this._position + this._frameCount) * 2;\n        },\n        clear: function(frameCount) {\n            this.receive(frameCount);\n            this.rewind();\n        },\n        put: function(numFrames) {\n            this._frameCount += numFrames;\n        },\n        putSamples: function(samples, position, numFrames) {\n            position = position || 0;\n            var sourceOffset = position * 2;\n            if (!(numFrames >= 0)) {\n                numFrames = (samples.length - sourceOffset) / 2;\n            }\n            var numSamples = numFrames * 2;\n\n            this.ensureCapacity(numFrames + this._frameCount);\n\n            var destOffset = this.endIndex;\n            this._vector.set(\n                samples.subarray(sourceOffset, sourceOffset + numSamples),\n                destOffset\n            );\n\n            this._frameCount += numFrames;\n        },\n        putBuffer: function(buffer, position, numFrames) {\n            position = position || 0;\n            if (!(numFrames >= 0)) {\n                numFrames = buffer.frameCount - position;\n            }\n            this.putSamples(\n                buffer.vector,\n                buffer.position + position,\n                numFrames\n            );\n        },\n        receive: function(numFrames) {\n            if (!(numFrames >= 0) || numFrames > this._frameCount) {\n                numFrames = this._frameCount;\n            }\n            this._frameCount -= numFrames;\n            this._position += numFrames;\n        },\n        receiveSamples: function(output, numFrames) {\n            var numSamples = numFrames * 2;\n            var sourceOffset = this.startIndex;\n            output.set(\n                this._vector.subarray(sourceOffset, sourceOffset + numSamples)\n            );\n            this.receive(numFrames);\n        },\n        extract: function(output, position, numFrames) {\n            var sourceOffset = this.startIndex + position * 2;\n            var numSamples = numFrames * 2;\n            output.set(\n                this._vector.subarray(sourceOffset, sourceOffset + numSamples)\n            );\n        },\n        ensureCapacity: function(numFrames) {\n            var minLength = numFrames * 2;\n            if (this._vector.length < minLength) {\n                var newVector = new Float32Array(minLength);\n                newVector.set(\n                    this._vector.subarray(this.startIndex, this.endIndex)\n                );\n                this._vector = newVector;\n                this._position = 0;\n            } else {\n                this.rewind();\n            }\n        },\n        ensureAdditionalCapacity: function(numFrames) {\n            this.ensureCapacity(this.frameCount + numFrames);\n        },\n        rewind: function() {\n            if (this._position > 0) {\n                this._vector.set(\n                    this._vector.subarray(this.startIndex, this.endIndex)\n                );\n                this._position = 0;\n            }\n        }\n    };\n\n    function SimpleFilter(sourceSound, pipe) {\n        this._pipe = pipe;\n        this.sourceSound = sourceSound;\n        this.historyBufferSize = 22050;\n        this._sourcePosition = 0;\n        this.outputBufferPosition = 0;\n        this._position = 0;\n    }\n    SimpleFilter.prototype = {\n        get pipe() {\n            return this._pipe;\n        },\n        get position() {\n            return this._position;\n        },\n        set position(position) {\n            if (position > this._position) {\n                throw new RangeError(\n                    'New position may not be greater than current position'\n                );\n            }\n            var newOutputBufferPosition =\n                this.outputBufferPosition - (this._position - position);\n            if (newOutputBufferPosition < 0) {\n                throw new RangeError(\n                    'New position falls outside of history buffer'\n                );\n            }\n            this.outputBufferPosition = newOutputBufferPosition;\n            this._position = position;\n        },\n        get sourcePosition() {\n            return this._sourcePosition;\n        },\n        set sourcePosition(sourcePosition) {\n            this.clear();\n            this._sourcePosition = sourcePosition;\n        },\n        get inputBuffer() {\n            return this._pipe.inputBuffer;\n        },\n        get outputBuffer() {\n            return this._pipe.outputBuffer;\n        },\n        fillInputBuffer: function(numFrames) {\n            var samples = new Float32Array(numFrames * 2);\n            var numFramesExtracted = this.sourceSound.extract(\n                samples,\n                numFrames,\n                this._sourcePosition\n            );\n            this._sourcePosition += numFramesExtracted;\n            this.inputBuffer.putSamples(samples, 0, numFramesExtracted);\n        },\n        fillOutputBuffer: function(numFrames) {\n            while (this.outputBuffer.frameCount < numFrames) {\n                // TODO hardcoded buffer size\n                var numInputFrames = 8192 * 2 - this.inputBuffer.frameCount;\n\n                this.fillInputBuffer(numInputFrames);\n\n                if (this.inputBuffer.frameCount < 8192 * 2) {\n                    break;\n                    // TODO flush pipe\n                }\n                this._pipe.process();\n            }\n        },\n        extract: function(target, numFrames) {\n            this.fillOutputBuffer(this.outputBufferPosition + numFrames);\n\n            var numFramesExtracted = Math.min(\n                numFrames,\n                this.outputBuffer.frameCount - this.outputBufferPosition\n            );\n            this.outputBuffer.extract(\n                target,\n                this.outputBufferPosition,\n                numFramesExtracted\n            );\n\n            var currentFrames = this.outputBufferPosition + numFramesExtracted;\n            this.outputBufferPosition = Math.min(\n                this.historyBufferSize,\n                currentFrames\n            );\n            this.outputBuffer.receive(\n                Math.max(currentFrames - this.historyBufferSize, 0)\n            );\n\n            this._position += numFramesExtracted;\n            return numFramesExtracted;\n        },\n        handleSampleData: function(e) {\n            this.extract(e.data, 4096);\n        },\n        clear: function() {\n            // TODO yuck\n            this._pipe.clear();\n            this.outputBufferPosition = 0;\n        }\n    };\n\n    function Stretch(createBuffers, sampleRate) {\n        AbstractFifoSamplePipe.call(this, createBuffers);\n        this.bQuickSeek = true;\n        this.bMidBufferDirty = false;\n\n        this.pMidBuffer = null;\n        this.overlapLength = 0;\n\n        this.bAutoSeqSetting = true;\n        this.bAutoSeekSetting = true;\n\n        this._tempo = 1;\n        this.setParameters(\n            sampleRate,\n            DEFAULT_SEQUENCE_MS,\n            DEFAULT_SEEKWINDOW_MS,\n            DEFAULT_OVERLAP_MS\n        );\n    }\n    extend(Stretch.prototype, AbstractFifoSamplePipe.prototype);\n    extend(Stretch.prototype, {\n        clear: function() {\n            AbstractFifoSamplePipe.prototype.clear.call(this);\n            this._clearMidBuffer();\n        },\n        _clearMidBuffer: function() {\n            if (this.bMidBufferDirty) {\n                this.bMidBufferDirty = false;\n                this.pMidBuffer = null;\n            }\n        },\n\n        /**\n         * Sets routine control parameters. These control are certain time constants\n         * defining how the sound is stretched to the desired duration.\n         *\n         * 'sampleRate' = sample rate of the sound\n         * 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)\n         * 'seekwindowMS' = seeking window length for scanning the best overlapping\n         *      position (default = 28 ms)\n         * 'overlapMS' = overlapping length (default = 12 ms)\n         */\n        setParameters: function(\n            aSampleRate,\n            aSequenceMS,\n            aSeekWindowMS,\n            aOverlapMS\n        ) {\n            // accept only positive parameter values - if zero or negative, use old values instead\n            if (aSampleRate > 0) {\n                this.sampleRate = aSampleRate;\n            }\n            if (aOverlapMS > 0) {\n                this.overlapMs = aOverlapMS;\n            }\n\n            if (aSequenceMS > 0) {\n                this.sequenceMs = aSequenceMS;\n                this.bAutoSeqSetting = false;\n            } else {\n                // zero or below, use automatic setting\n                this.bAutoSeqSetting = true;\n            }\n\n            if (aSeekWindowMS > 0) {\n                this.seekWindowMs = aSeekWindowMS;\n                this.bAutoSeekSetting = false;\n            } else {\n                // zero or below, use automatic setting\n                this.bAutoSeekSetting = true;\n            }\n\n            this.calcSeqParameters();\n\n            this.calculateOverlapLength(this.overlapMs);\n\n            // set tempo to recalculate 'sampleReq'\n            this.tempo = this._tempo;\n        },\n\n        /**\n         * Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower\n         * tempo, larger faster tempo.\n         */\n        set tempo(newTempo) {\n            var intskip;\n\n            this._tempo = newTempo;\n\n            // Calculate new sequence duration\n            this.calcSeqParameters();\n\n            // Calculate ideal skip length (according to tempo value)\n            this.nominalSkip =\n                this._tempo * (this.seekWindowLength - this.overlapLength);\n            this.skipFract = 0;\n            intskip = Math.floor(this.nominalSkip + 0.5);\n\n            // Calculate how many samples are needed in the 'inputBuffer' to\n            // process another batch of samples\n            this.sampleReq =\n                Math.max(intskip + this.overlapLength, this.seekWindowLength) +\n                this.seekLength;\n        },\n        get inputChunkSize() {\n            return this.sampleReq;\n        },\n        get outputChunkSize() {\n            return (\n                this.overlapLength +\n                Math.max(0, this.seekWindowLength - 2 * this.overlapLength)\n            );\n        },\n\n        /**\n         * Calculates overlapInMsec period length in samples.\n         */\n        calculateOverlapLength: function(overlapInMsec) {\n            var newOvl;\n\n            // TODO assert(overlapInMsec >= 0);\n            newOvl = (this.sampleRate * overlapInMsec) / 1000;\n            if (newOvl < 16) newOvl = 16;\n\n            // must be divisible by 8\n            newOvl -= newOvl % 8;\n\n            this.overlapLength = newOvl;\n\n            this.pRefMidBuffer = new Float32Array(this.overlapLength * 2);\n            this.pMidBuffer = new Float32Array(this.overlapLength * 2);\n        },\n        checkLimits: function(x, mi, ma) {\n            return x < mi ? mi : x > ma ? ma : x;\n        },\n\n        /**\n         * Calculates processing sequence length according to tempo setting\n         */\n        calcSeqParameters: function() {\n            var seq;\n            var seek;\n\n            if (this.bAutoSeqSetting) {\n                seq = AUTOSEQ_C + AUTOSEQ_K * this._tempo;\n                seq = this.checkLimits(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN);\n                this.sequenceMs = Math.floor(seq + 0.5);\n            }\n\n            if (this.bAutoSeekSetting) {\n                seek = AUTOSEEK_C + AUTOSEEK_K * this._tempo;\n                seek = this.checkLimits(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN);\n                this.seekWindowMs = Math.floor(seek + 0.5);\n            }\n\n            // Update seek window lengths\n            this.seekWindowLength = Math.floor(\n                (this.sampleRate * this.sequenceMs) / 1000\n            );\n            this.seekLength = Math.floor(\n                (this.sampleRate * this.seekWindowMs) / 1000\n            );\n        },\n\n        /**\n         * Enables/disables the quick position seeking algorithm.\n         */\n        set quickSeek(enable) {\n            this.bQuickSeek = enable;\n        },\n\n        /**\n         * Seeks for the optimal overlap-mixing position.\n         */\n        seekBestOverlapPosition: function() {\n            if (this.bQuickSeek) {\n                return this.seekBestOverlapPositionStereoQuick();\n            } else {\n                return this.seekBestOverlapPositionStereo();\n            }\n        },\n\n        /**\n         * Seeks for the optimal overlap-mixing position. The 'stereo' version of the\n         * routine\n         *\n         * The best position is determined as the position where the two overlapped\n         * sample sequences are 'most alike', in terms of the highest cross-correlation\n         * value over the overlapping period\n         */\n        seekBestOverlapPositionStereo: function() {\n            var bestOffs, bestCorr, corr, i;\n\n            // Slopes the amplitudes of the 'midBuffer' samples.\n            this.precalcCorrReferenceStereo();\n\n            bestCorr = Number.MIN_VALUE;\n            bestOffs = 0;\n\n            // Scans for the best correlation value by testing each possible position\n            // over the permitted range.\n            for (i = 0; i < this.seekLength; i++) {\n                // Calculates correlation value for the mixing position corresponding\n                // to 'i'\n                corr = this.calcCrossCorrStereo(2 * i, this.pRefMidBuffer);\n\n                // Checks for the highest correlation value.\n                if (corr > bestCorr) {\n                    bestCorr = corr;\n                    bestOffs = i;\n                }\n            }\n            return bestOffs;\n        },\n\n        /**\n         * Seeks for the optimal overlap-mixing position. The 'stereo' version of the\n         * routine\n         *\n         * The best position is determined as the position where the two overlapped\n         * sample sequences are 'most alike', in terms of the highest cross-correlation\n         * value over the overlapping period\n         */\n        seekBestOverlapPositionStereoQuick: function() {\n            var j, bestOffs, bestCorr, corr, scanCount, corrOffset, tempOffset;\n\n            // Slopes the amplitude of the 'midBuffer' samples\n            this.precalcCorrReferenceStereo();\n\n            bestCorr = Number.MIN_VALUE;\n            bestOffs = 0;\n            corrOffset = 0;\n            tempOffset = 0;\n\n            // Scans for the best correlation value using four-pass hierarchical search.\n            //\n            // The look-up table 'scans' has hierarchical position adjusting steps.\n            // In first pass the routine searhes for the highest correlation with\n            // relatively coarse steps, then rescans the neighbourhood of the highest\n            // correlation with better resolution and so on.\n            for (scanCount = 0; scanCount < 4; scanCount++) {\n                j = 0;\n                while (_SCAN_OFFSETS[scanCount][j]) {\n                    tempOffset = corrOffset + _SCAN_OFFSETS[scanCount][j];\n                    if (tempOffset >= this.seekLength) {\n                        break;\n                    }\n\n                    // Calculates correlation value for the mixing position corresponding\n                    // to 'tempOffset'\n                    corr = this.calcCrossCorrStereo(\n                        2 * tempOffset,\n                        this.pRefMidBuffer\n                    );\n\n                    // Checks for the highest correlation value\n                    if (corr > bestCorr) {\n                        bestCorr = corr;\n                        bestOffs = tempOffset;\n                    }\n                    j++;\n                }\n                corrOffset = bestOffs;\n            }\n            return bestOffs;\n        },\n\n        /**\n         * Slopes the amplitude of the 'midBuffer' samples so that cross correlation\n         * is faster to calculate\n         */\n        precalcCorrReferenceStereo: function() {\n            var i, cnt2, temp;\n\n            for (i = 0; i < this.overlapLength; i++) {\n                temp = i * (this.overlapLength - i);\n                cnt2 = i * 2;\n                this.pRefMidBuffer[cnt2] = this.pMidBuffer[cnt2] * temp;\n                this.pRefMidBuffer[cnt2 + 1] = this.pMidBuffer[cnt2 + 1] * temp;\n            }\n        },\n\n        calcCrossCorrStereo: function(mixingPos, compare) {\n            var mixing = this._inputBuffer.vector;\n            mixingPos += this._inputBuffer.startIndex;\n\n            var corr, i, mixingOffset;\n            corr = 0;\n            for (i = 2; i < 2 * this.overlapLength; i += 2) {\n                mixingOffset = i + mixingPos;\n                corr +=\n                    mixing[mixingOffset] * compare[i] +\n                    mixing[mixingOffset + 1] * compare[i + 1];\n            }\n            return corr;\n        },\n\n        // TODO inline\n        /**\n         * Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position\n         * of 'ovlPos'.\n         */\n        overlap: function(ovlPos) {\n            this.overlapStereo(2 * ovlPos);\n        },\n\n        /**\n         * Overlaps samples in 'midBuffer' with the samples in 'pInput'\n         */\n        overlapStereo: function(pInputPos) {\n            var pInput = this._inputBuffer.vector;\n            pInputPos += this._inputBuffer.startIndex;\n\n            var pOutput = this._outputBuffer.vector,\n                pOutputPos = this._outputBuffer.endIndex,\n                i,\n                cnt2,\n                fTemp,\n                fScale,\n                fi,\n                pInputOffset,\n                pOutputOffset;\n\n            fScale = 1 / this.overlapLength;\n            for (i = 0; i < this.overlapLength; i++) {\n                fTemp = (this.overlapLength - i) * fScale;\n                fi = i * fScale;\n                cnt2 = 2 * i;\n                pInputOffset = cnt2 + pInputPos;\n                pOutputOffset = cnt2 + pOutputPos;\n                pOutput[pOutputOffset + 0] =\n                    pInput[pInputOffset + 0] * fi +\n                    this.pMidBuffer[cnt2 + 0] * fTemp;\n                pOutput[pOutputOffset + 1] =\n                    pInput[pInputOffset + 1] * fi +\n                    this.pMidBuffer[cnt2 + 1] * fTemp;\n            }\n        },\n        process: function() {\n            var ovlSkip, offset, temp, i;\n            if (this.pMidBuffer === null) {\n                // if midBuffer is empty, move the first samples of the input stream\n                // into it\n                if (this._inputBuffer.frameCount < this.overlapLength) {\n                    // wait until we've got overlapLength samples\n                    return;\n                }\n                this.pMidBuffer = new Float32Array(this.overlapLength * 2);\n                this._inputBuffer.receiveSamples(\n                    this.pMidBuffer,\n                    this.overlapLength\n                );\n            }\n\n            var output;\n            // Process samples as long as there are enough samples in 'inputBuffer'\n            // to form a processing frame.\n            while (this._inputBuffer.frameCount >= this.sampleReq) {\n                // If tempo differs from the normal ('SCALE'), scan for the best overlapping\n                // position\n                offset = this.seekBestOverlapPosition();\n\n                // Mix the samples in the 'inputBuffer' at position of 'offset' with the\n                // samples in 'midBuffer' using sliding overlapping\n                // ... first partially overlap with the end of the previous sequence\n                // (that's in 'midBuffer')\n                this._outputBuffer.ensureAdditionalCapacity(this.overlapLength);\n                // FIXME unit?\n                //overlap(uint(offset));\n                this.overlap(Math.floor(offset));\n                this._outputBuffer.put(this.overlapLength);\n\n                // ... then copy sequence samples from 'inputBuffer' to output\n                temp = this.seekWindowLength - 2 * this.overlapLength; // & 0xfffffffe;\n                if (temp > 0) {\n                    this._outputBuffer.putBuffer(\n                        this._inputBuffer,\n                        offset + this.overlapLength,\n                        temp\n                    );\n                }\n\n                // Copies the end of the current sequence from 'inputBuffer' to\n                // 'midBuffer' for being mixed with the beginning of the next\n                // processing sequence and so on\n                //assert(offset + seekWindowLength <= (int)inputBuffer.numSamples());\n                var start =\n                    this.inputBuffer.startIndex +\n                    2 * (offset + this.seekWindowLength - this.overlapLength);\n                this.pMidBuffer.set(\n                    this._inputBuffer.vector.subarray(\n                        start,\n                        start + 2 * this.overlapLength\n                    )\n                );\n\n                // Remove the processed samples from the input buffer. Update\n                // the difference between integer & nominal skip step to 'skipFract'\n                // in order to prevent the error from accumulating over time.\n                this.skipFract += this.nominalSkip; // real skip size\n                ovlSkip = Math.floor(this.skipFract); // rounded to integer skip\n                this.skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip\n                this._inputBuffer.receive(ovlSkip);\n            }\n        }\n    });\n\n    // https://bugs.webkit.org/show_bug.cgi?id=57295\n    extend(Stretch.prototype, {\n        get tempo() {\n            return this._tempo;\n        }\n    });\n\n    function SoundTouch(sampleRate) {\n        this.rateTransposer = new RateTransposer(false);\n        this.tdStretch = new Stretch(false, sampleRate);\n\n        this._inputBuffer = new FifoSampleBuffer();\n        this._intermediateBuffer = new FifoSampleBuffer();\n        this._outputBuffer = new FifoSampleBuffer();\n\n        this._rate = 0;\n        this._tempo = 0;\n\n        this.virtualPitch = 1.0;\n        this.virtualRate = 1.0;\n        this.virtualTempo = 1.0;\n\n        this._calculateEffectiveRateAndTempo();\n    }\n    SoundTouch.prototype = {\n        clear: function() {\n            this.rateTransposer.clear();\n            this.tdStretch.clear();\n        },\n        get rate() {\n            return this._rate;\n        },\n        set rate(rate) {\n            this.virtualRate = rate;\n            this._calculateEffectiveRateAndTempo();\n        },\n        set rateChange(rateChange) {\n            this.rate = 1.0 + 0.01 * rateChange;\n        },\n        get tempo() {\n            return this._tempo;\n        },\n        set tempo(tempo) {\n            this.virtualTempo = tempo;\n            this._calculateEffectiveRateAndTempo();\n        },\n        set tempoChange(tempoChange) {\n            this.tempo = 1.0 + 0.01 * tempoChange;\n        },\n        set pitch(pitch) {\n            this.virtualPitch = pitch;\n            this._calculateEffectiveRateAndTempo();\n        },\n        set pitchOctaves(pitchOctaves) {\n            this.pitch = Math.exp(0.69314718056 * pitchOctaves);\n            this._calculateEffectiveRateAndTempo();\n        },\n        set pitchSemitones(pitchSemitones) {\n            this.pitchOctaves = pitchSemitones / 12.0;\n        },\n        get inputBuffer() {\n            return this._inputBuffer;\n        },\n        get outputBuffer() {\n            return this._outputBuffer;\n        },\n        _calculateEffectiveRateAndTempo: function() {\n            var previousTempo = this._tempo;\n            var previousRate = this._rate;\n\n            this._tempo = this.virtualTempo / this.virtualPitch;\n            this._rate = this.virtualRate * this.virtualPitch;\n\n            if (testFloatEqual(this._tempo, previousTempo)) {\n                this.tdStretch.tempo = this._tempo;\n            }\n            if (testFloatEqual(this._rate, previousRate)) {\n                this.rateTransposer.rate = this._rate;\n            }\n\n            if (this._rate > 1.0) {\n                if (this._outputBuffer != this.rateTransposer.outputBuffer) {\n                    this.tdStretch.inputBuffer = this._inputBuffer;\n                    this.tdStretch.outputBuffer = this._intermediateBuffer;\n\n                    this.rateTransposer.inputBuffer = this._intermediateBuffer;\n                    this.rateTransposer.outputBuffer = this._outputBuffer;\n                }\n            } else {\n                if (this._outputBuffer != this.tdStretch.outputBuffer) {\n                    this.rateTransposer.inputBuffer = this._inputBuffer;\n                    this.rateTransposer.outputBuffer = this._intermediateBuffer;\n\n                    this.tdStretch.inputBuffer = this._intermediateBuffer;\n                    this.tdStretch.outputBuffer = this._outputBuffer;\n                }\n            }\n        },\n        process: function() {\n            if (this._rate > 1.0) {\n                this.tdStretch.process();\n                this.rateTransposer.process();\n            } else {\n                this.rateTransposer.process();\n                this.tdStretch.process();\n            }\n        }\n    };\n\n    function WebAudioBufferSource(buffer) {\n        this.buffer = buffer;\n    }\n    WebAudioBufferSource.prototype = {\n        extract: function(target, numFrames, position) {\n            var l = this.buffer.getChannelData(0),\n                r = this.buffer.getChannelData(1);\n            for (var i = 0; i < numFrames; i++) {\n                target[i * 2] = l[i + position];\n                target[i * 2 + 1] = r[i + position];\n            }\n            return Math.min(numFrames, l.length - position);\n        }\n    };\n\n    function getWebAudioNode(context, filter) {\n        var BUFFER_SIZE = 4096;\n        var node = context.createScriptProcessor(BUFFER_SIZE, 2, 2),\n            samples = new Float32Array(BUFFER_SIZE * 2);\n        node.onaudioprocess = function(e) {\n            var l = e.outputBuffer.getChannelData(0),\n                r = e.outputBuffer.getChannelData(1);\n            var framesExtracted = filter.extract(samples, BUFFER_SIZE);\n            if (framesExtracted === 0) {\n                node.disconnect(); // Pause.\n            }\n            for (var i = 0; i < framesExtracted; i++) {\n                l[i] = samples[i * 2];\n                r[i] = samples[i * 2 + 1];\n            }\n        };\n        return node;\n    }\n\n    return soundtouch = {\n        RateTransposer: RateTransposer,\n        Stretch: Stretch,\n        SimpleFilter: SimpleFilter,\n        SoundTouch: SoundTouch,\n        WebAudioBufferSource: WebAudioBufferSource,\n        getWebAudioNode: getWebAudioNode\n    };\n});//end of factory method container"],"names":["root","factory","this","_SCAN_OFFSETS","extend","a","b","i","g","__lookupGetter__","s","__lookupSetter__","__defineGetter__","__defineSetter__","testFloatEqual","AbstractFifoSamplePipe","createBuffers","inputBuffer","FifoSampleBuffer","outputBuffer","RateTransposer","call","_reset","rate","_vector","Float32Array","_position","_frameCount","SimpleFilter","sourceSound","pipe","_pipe","historyBufferSize","_sourcePosition","outputBufferPosition","Stretch","sampleRate","bQuickSeek","bMidBufferDirty","pMidBuffer","overlapLength","bAutoSeqSetting","bAutoSeekSetting","_tempo","setParameters","SoundTouch","rateTransposer","tdStretch","_inputBuffer","_intermediateBuffer","_outputBuffer","_rate","virtualPitch","virtualRate","virtualTempo","_calculateEffectiveRateAndTempo","WebAudioBufferSource","buffer","prototype","clear","slopeCount","prevSampleL","prevSampleR","process","numFrames","frameCount","ensureAdditionalCapacity","numFramesOutput","_transpose","receive","put","src","vector","srcOffset","startIndex","dest","destOffset","endIndex","used","out","srcIndex","position","rewind","putSamples","samples","sourceOffset","length","numSamples","ensureCapacity","set","subarray","putBuffer","receiveSamples","output","extract","minLength","newVector","RangeError","newOutputBufferPosition","sourcePosition","fillInputBuffer","numFramesExtracted","fillOutputBuffer","numInputFrames","target","Math","min","currentFrames","max","handleSampleData","e","data","_clearMidBuffer","aSampleRate","aSequenceMS","aSeekWindowMS","aOverlapMS","overlapMs","sequenceMs","seekWindowMs","calcSeqParameters","calculateOverlapLength","tempo","newTempo","intskip","nominalSkip","seekWindowLength","skipFract","floor","sampleReq","seekLength","inputChunkSize","outputChunkSize","overlapInMsec","newOvl","pRefMidBuffer","checkLimits","x","mi","ma","seq","seek","AUTOSEQ_AT_MIN","AUTOSEEK_AT_MIN","quickSeek","enable","seekBestOverlapPosition","seekBestOverlapPositionStereoQuick","seekBestOverlapPositionStereo","bestOffs","bestCorr","corr","precalcCorrReferenceStereo","Number","MIN_VALUE","calcCrossCorrStereo","j","scanCount","corrOffset","tempOffset","cnt2","temp","mixingPos","compare","mixingOffset","mixing","overlap","ovlPos","overlapStereo","pInputPos","pInput","fTemp","fScale","fi","pInputOffset","pOutputOffset","pOutput","pOutputPos","ovlSkip","offset","start","rateChange","tempoChange","pitch","pitchOctaves","exp","pitchSemitones","previousTempo","previousRate","l","getChannelData","r","soundtouch","getWebAudioNode","context","filter","node","createScriptProcessor","BUFFER_SIZE","onaudioprocess","framesExtracted","disconnect","define","amd","CloudPoodll"],"mappings":"AAwBA,IAAUA,KAAMC,QAAND,KAePE,OAfaD,QAeP,eAwDDE,cAAgB,CAChB,CACI,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,GAEJ,EACK,KACA,IACA,IACA,GACD,GACA,GACA,GACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GAEJ,EACK,IACA,IACA,IACA,EACD,EACA,GACA,GACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GAEJ,EACK,GACA,GACA,GACA,EACD,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,aAyBCC,OAAOC,EAAGC,OACV,IAAIC,KAAKD,EAAG,KACTE,EAAIF,EAAEG,iBAAiBF,GACvBG,EAAIJ,EAAEK,iBAAiBJ,GACvBC,GAAKE,GACDF,GACAH,EAAEO,iBAAiBL,EAAGC,GAEtBE,GACAL,EAAEQ,iBAAiBN,EAAGG,IAG1BL,EAAEE,GAAKD,EAAEC,UAGVF,WAGFS,eAAeT,EAAGC,UACfD,EAAIC,EAAID,EAAIC,EAAIA,EAAID,GAAK,eAG5BU,uBAAuBC,eACxBA,oBACKC,YAAc,IAAIC,sBAClBC,aAAe,IAAID,uBAEnBD,YAAcf,KAAKiB,aAAe,cAsBtCC,eAAeJ,eACpBD,uBAAuBM,KAAKnB,KAAMc,oBAC7BM,cACAC,KAAO,WAiFPL,wBACAM,QAAU,IAAIC,kBACdC,UAAY,OACZC,YAAc,WAsGdC,aAAaC,YAAaC,WAC1BC,MAAQD,UACRD,YAAcA,iBACdG,kBAAoB,WACpBC,gBAAkB,OAClBC,qBAAuB,OACvBR,UAAY,WAiGZS,QAAQnB,cAAeoB,YAC5BrB,uBAAuBM,KAAKnB,KAAMc,oBAC7BqB,YAAa,OACbC,iBAAkB,OAElBC,WAAa,UA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"}