Bug 1588233 - P3: Update soundtouch to version 2.1.2. r=padenot
authorChun-Min Chang <chun.m.chang@gmail.com>
Tue, 26 Nov 2019 00:42:19 +0000
changeset 503765 41cd531e5e837a1aee11aa7ae317c386dd5c166a
parent 503764 1d46f9bfcab5b4a9101be0d0163d0ca2eefa5c6a
child 503766 ffb0feac6752f3040710b5b38f1727358f4ead55
push id36847
push userncsoregi@mozilla.com
push dateTue, 26 Nov 2019 09:34:48 +0000
treeherdermozilla-central@7bc0df30a8a9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1588233
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1588233 - P3: Update soundtouch to version 2.1.2. r=padenot The changed-files are updated by running `sh update.sh <upstream-path>` with moz-libsoundtouch.patch applied. Differential Revision: https://phabricator.services.mozilla.com/D49029
media/libsoundtouch/LICENSE
media/libsoundtouch/src/AAFilter.cpp
media/libsoundtouch/src/AAFilter.h
media/libsoundtouch/src/FIFOSampleBuffer.cpp
media/libsoundtouch/src/FIFOSampleBuffer.h
media/libsoundtouch/src/FIFOSamplePipe.h
media/libsoundtouch/src/FIRFilter.cpp
media/libsoundtouch/src/FIRFilter.h
media/libsoundtouch/src/InterpolateCubic.cpp
media/libsoundtouch/src/InterpolateCubic.h
media/libsoundtouch/src/InterpolateLinear.cpp
media/libsoundtouch/src/InterpolateLinear.h
media/libsoundtouch/src/InterpolateShannon.cpp
media/libsoundtouch/src/InterpolateShannon.h
media/libsoundtouch/src/RateTransposer.cpp
media/libsoundtouch/src/RateTransposer.h
media/libsoundtouch/src/STTypes.h
media/libsoundtouch/src/SoundTouch.cpp
media/libsoundtouch/src/SoundTouch.h
media/libsoundtouch/src/TDStretch.cpp
media/libsoundtouch/src/TDStretch.h
media/libsoundtouch/src/cpu_detect.h
media/libsoundtouch/src/cpu_detect_x86.cpp
media/libsoundtouch/src/mmx_optimized.cpp
media/libsoundtouch/src/sse_optimized.cpp
--- a/media/libsoundtouch/LICENSE
+++ b/media/libsoundtouch/LICENSE
@@ -450,9 +450,9 @@ AND/OR REDISTRIBUTE THE LIBRARY AS PERMI
 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 DAMAGES.
 
-		     END OF TERMS AND CONDITIONS
+		     END OF TERMS AND CONDITIONS
\ No newline at end of file
--- a/media/libsoundtouch/src/AAFilter.cpp
+++ b/media/libsoundtouch/src/AAFilter.cpp
@@ -7,23 +7,16 @@
 /// transposing the sample rate with interpolation.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-05 21:40:22 +0000 (Sun, 05 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: AAFilter.cpp 177 2014-01-05 21:40:22Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -70,59 +63,54 @@ using namespace soundtouch;
         }
         fclose(fptr);
     }
 
 #else
     #define _DEBUG_SAVE_AAFIR_COEFFS(x, y)
 #endif
 
-
 /*****************************************************************************
  *
  * Implementation of the class 'AAFilter'
  *
  *****************************************************************************/
 
 AAFilter::AAFilter(uint len)
 {
     pFIR = FIRFilter::newInstance();
     cutoffFreq = 0.5;
     setLength(len);
 }
 
 
-
 AAFilter::~AAFilter()
 {
     delete pFIR;
 }
 
 
-
 // Sets new anti-alias filter cut-off edge frequency, scaled to
 // sampling frequency (nyquist frequency = 0.5).
 // The filter will cut frequencies higher than the given frequency.
 void AAFilter::setCutoffFreq(double newCutoffFreq)
 {
     cutoffFreq = newCutoffFreq;
     calculateCoeffs();
 }
 
 
-
 // Sets number of FIR filter taps
 void AAFilter::setLength(uint newLength)
 {
     length = newLength;
     calculateCoeffs();
 }
 
 
-
 // Calculates coefficients for a low-pass FIR filter using Hamming window
 void AAFilter::calculateCoeffs()
 {
     uint i;
     double cntTemp, temp, tempCoeff,h, w;
     double wc;
     double scaleCoeff, sum;
     double *work;
@@ -172,22 +160,20 @@ void AAFilter::calculateCoeffs()
 
     // Calculate a scaling coefficient in such a way that the result can be
     // divided by 16384
     scaleCoeff = 16384.0f / sum;
 
     for (i = 0; i < length; i ++) 
     {
         temp = work[i] * scaleCoeff;
-//#if SOUNDTOUCH_INTEGER_SAMPLES
         // scale & round to nearest integer
         temp += (temp >= 0) ? 0.5 : -0.5;
         // ensure no overfloods
         assert(temp >= -32768 && temp <= 32767);
-//#endif
         coeffs[i] = (SAMPLETYPE)temp;
     }
 
     // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
     pFIR->setCoefficients(coeffs, length, 14);
 
     _DEBUG_SAVE_AAFIR_COEFFS(coeffs, length);
 
--- a/media/libsoundtouch/src/AAFilter.h
+++ b/media/libsoundtouch/src/AAFilter.h
@@ -8,23 +8,16 @@
 /// transposing the sample rate with interpolation.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-07 19:41:23 +0000 (Tue, 07 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: AAFilter.h 187 2014-01-07 19:41:23Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
--- a/media/libsoundtouch/src/FIFOSampleBuffer.cpp
+++ b/media/libsoundtouch/src/FIFOSampleBuffer.cpp
@@ -10,23 +10,16 @@
 /// whenever necessary.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2012-11-08 18:53:01 +0000 (Thu, 08 Nov 2012) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -75,17 +68,18 @@ FIFOSampleBuffer::~FIFOSampleBuffer()
 }
 
 
 // Sets number of channels, 1 = mono, 2 = stereo
 void FIFOSampleBuffer::setChannels(int numChannels)
 {
     uint usedBytes;
 
-    assert(numChannels > 0);
+    if (!verifyNumberOfChannels(numChannels)) return;
+
     usedBytes = channels * samplesInBuffer;
     channels = (uint)numChannels;
     samplesInBuffer = usedBytes / channels;
 }
 
 
 // if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
 // zeroes this pointer by copying samples from the 'bufferPos' pointer 
@@ -126,17 +120,17 @@ void FIFOSampleBuffer::putSamples(uint n
 
 
 // Returns a pointer to the end of the used part of the sample buffer (i.e. 
 // where the new samples are to be inserted). This function may be used for 
 // inserting new samples into the sample buffer directly. Please be careful! 
 //
 // Parameter 'slackCapacity' tells the function how much free capacity (in
 // terms of samples) there _at least_ should be, in order to the caller to
-// succesfully insert all the required samples to the buffer. When necessary, 
+// successfully insert all the required samples to the buffer. When necessary, 
 // the function grows the buffer size to comply with this requirement.
 //
 // When using this function as means for inserting new samples, also remember 
 // to increase the sample count afterwards, by calling  the 
 // 'putSamples(numSamples)' function.
 SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity) 
 {
     ensureCapacity(samplesInBuffer + slackCapacity);
@@ -153,17 +147,17 @@ SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uin
 // 'receiveSamples(numSamples)' function
 SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
 {
     assert(buffer);
     return buffer + bufferPos * channels;
 }
 
 
-// Ensures that the buffer has enought capacity, i.e. space for _at least_
+// Ensures that the buffer has enough capacity, i.e. space for _at least_
 // 'capacityRequirement' number of samples. The buffer is grown in steps of
 // 4 kilobytes to eliminate the need for frequently growing up the buffer,
 // as well as to round the buffer size up to the virtual memory page size.
 void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
 {
     SAMPLETYPE *tempUnaligned, *temp;
 
     if (capacityRequirement > getCapacity()) 
@@ -266,9 +260,8 @@ void FIFOSampleBuffer::clear()
 uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
 {
     if (numSamples < samplesInBuffer)
     {
         samplesInBuffer = numSamples;
     }
     return samplesInBuffer;
 }
-
--- a/media/libsoundtouch/src/FIFOSampleBuffer.h
+++ b/media/libsoundtouch/src/FIFOSampleBuffer.h
@@ -10,23 +10,16 @@
 /// whenever necessary.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-05 21:40:22 +0000 (Sun, 05 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -114,17 +107,17 @@ public:
     /// inserting new samples into the sample buffer directly. Please be careful
     /// not corrupt the book-keeping!
     ///
     /// When using this function as means for inserting new samples, also remember 
     /// to increase the sample count afterwards, by calling  the 
     /// 'putSamples(numSamples)' function.
     SAMPLETYPE *ptrEnd(
                 uint slackCapacity   ///< How much free capacity (in samples) there _at least_ 
-                                     ///< should be so that the caller can succesfully insert the 
+                                     ///< should be so that the caller can successfully insert the 
                                      ///< desired samples to the buffer. If necessary, the function 
                                      ///< grows the buffer size to comply with this requirement.
                 );
 
     /// Adds 'numSamples' pcs of samples from the 'samples' memory position to
     /// the sample buffer.
     virtual void putSamples(const SAMPLETYPE *samples,  ///< Pointer to samples.
                             uint numSamples                         ///< Number of samples to insert.
--- a/media/libsoundtouch/src/FIFOSamplePipe.h
+++ b/media/libsoundtouch/src/FIFOSamplePipe.h
@@ -12,23 +12,16 @@
 /// may be either another processing stage, or a fifo sample buffer object.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2012-06-13 19:29:53 +0000 (Wed, 13 Jun 2012) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -53,16 +46,28 @@
 #include "STTypes.h"
 
 namespace soundtouch
 {
 
 /// Abstract base class for FIFO (first-in-first-out) sample processing classes.
 class FIFOSamplePipe
 {
+protected:
+
+    bool verifyNumberOfChannels(int nChannels) const
+    {
+        if ((nChannels > 0) && (nChannels <= SOUNDTOUCH_MAX_CHANNELS))
+        {
+            return true;
+        }
+        ST_THROW_RT_ERROR("Error: Illegal number of channels");
+        return false;
+    }
+
 public:
     // virtual default destructor
     virtual ~FIFOSamplePipe() {}
 
 
     /// Returns a pointer to the beginning of the output samples. 
     /// This function is provided for accessing the output samples directly. 
     /// Please be careful for not to corrupt the book-keeping!
@@ -117,17 +122,16 @@ public:
 
     /// allow trimming (downwards) amount of samples in pipeline.
     /// Returns adjusted amount of samples
     virtual uint adjustAmountOfSamples(uint numSamples) = 0;
 
 };
 
 
-
 /// Base-class for sound processing routines working in FIFO principle. With this base 
 /// class it's easy to implement sound processing stages that can be chained together,
 /// so that samples that are fed into beginning of the pipe automatically go through 
 /// all the processing stages.
 ///
 /// When samples are input to this class, they're first processed and then put to 
 /// the FIFO pipe that's defined as output of this class. This output pipe can be
 /// either other processing stage or a FIFO sample buffer.
@@ -140,39 +144,35 @@ protected:
     /// Sets output pipe.
     void setOutPipe(FIFOSamplePipe *pOutput)
     {
         assert(output == NULL);
         assert(pOutput != NULL);
         output = pOutput;
     }
 
-
     /// Constructor. Doesn't define output pipe; it has to be set be 
     /// 'setOutPipe' function.
     FIFOProcessor()
     {
         output = NULL;
     }
 
-
     /// Constructor. Configures output pipe.
     FIFOProcessor(FIFOSamplePipe *pOutput   ///< Output pipe.
                  )
     {
         output = pOutput;
     }
 
-
     /// Destructor.
     virtual ~FIFOProcessor()
     {
     }
 
-
     /// Returns a pointer to the beginning of the output samples. 
     /// This function is provided for accessing the output samples directly. 
     /// Please be careful for not to corrupt the book-keeping!
     ///
     /// When using this function to output samples, also remember to 'remove' the
     /// output samples from the buffer by calling the 
     /// 'receiveSamples(numSamples)' function
     virtual SAMPLETYPE *ptrBegin()
@@ -189,46 +189,42 @@ public:
     /// \return Number of samples returned.
     virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
                                 uint maxSamples                    ///< How many samples to receive at max.
                                 )
     {
         return output->receiveSamples(outBuffer, maxSamples);
     }
 
-
     /// Adjusts book-keeping so that given number of samples are removed from beginning of the 
     /// sample buffer without copying them anywhere. 
     ///
     /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
     /// with 'ptrBegin' function.
     virtual uint receiveSamples(uint maxSamples   ///< Remove this many samples from the beginning of pipe.
                                 )
     {
         return output->receiveSamples(maxSamples);
     }
 
-
     /// Returns number of samples currently available.
     virtual uint numSamples() const
     {
         return output->numSamples();
     }
 
-
     /// Returns nonzero if there aren't any samples available for outputting.
     virtual int isEmpty() const
     {
         return output->isEmpty();
     }
 
     /// allow trimming (downwards) amount of samples in pipeline.
     /// Returns adjusted amount of samples
     virtual uint adjustAmountOfSamples(uint numSamples)
     {
         return output->adjustAmountOfSamples(numSamples);
     }
-
 };
 
 }
 
 #endif
--- a/media/libsoundtouch/src/FIRFilter.cpp
+++ b/media/libsoundtouch/src/FIRFilter.cpp
@@ -1,28 +1,27 @@
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// General FIR digital filter routines with MMX optimization. 
 ///
-/// Note : MMX optimized functions reside in a separate, platform-specific file, 
+/// Notes : MMX optimized functions reside in a separate, platform-specific file, 
 /// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
 ///
+/// This source file contains OpenMP optimizations that allow speeding up the
+/// corss-correlation algorithm by executing it in several threads / CPU cores 
+/// in parallel. See the following article link for more detailed discussion 
+/// about SoundTouch OpenMP optimizations:
+/// http://www.softwarecoven.com/parallel-computing-in-embedded-mobile-devices
+///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIRFilter.cpp 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -64,16 +63,17 @@ FIRFilter::FIRFilter()
 }
 
 
 FIRFilter::~FIRFilter()
 {
     delete[] filterCoeffs;
 }
 
+
 // Usual C-version of the filter routine for stereo sound
 uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
 {
     int j, end;
 #ifdef SOUNDTOUCH_FLOAT_SAMPLES
     // when using floating point samples, use a scaler instead of a divider
     // because division is much slower operation than multiplying.
     double dScaler = 1.0 / (double)resultDivider;
@@ -122,18 +122,16 @@ uint FIRFilter::evaluateFilterStereo(SAM
 #endif // SOUNDTOUCH_INTEGER_SAMPLES
         dest[j] = (SAMPLETYPE)suml;
         dest[j + 1] = (SAMPLETYPE)sumr;
     }
     return numSamples - length;
 }
 
 
-
-
 // Usual C-version of the filter routine for mono sound
 uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
 {
     int j, end;
 #ifdef SOUNDTOUCH_FLOAT_SAMPLES
     // when using floating point samples, use a scaler instead of a divider
     // because division is much slower operation than multiplying.
     double dScaler = 1.0 / (double)resultDivider;
@@ -249,17 +247,16 @@ void FIRFilter::setCoefficients(const SA
 
 
 uint FIRFilter::getLength() const
 {
     return length;
 }
 
 
-
 // Applies the filter to the given sequence of samples. 
 //
 // Note : The amount of outputted samples is by value of 'filter_length' 
 // smaller than the amount of input samples.
 uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) 
 {
     assert(length > 0);
     assert(lengthDiv8 * 8 == length);
@@ -279,17 +276,16 @@ uint FIRFilter::evaluate(SAMPLETYPE *des
 #endif // USE_MULTICH_ALWAYS
     {
         assert(numChannels > 0);
         return evaluateFilterMulti(dest, src, numSamples, numChannels);
     }
 }
 
 
-
 // Operator 'new' is overloaded so that it automatically creates a suitable instance 
 // depending on if we've a MMX-capable CPU available or not.
 void * FIRFilter::operator new(size_t s)
 {
     // Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
     ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
     return newInstance();
 }
--- a/media/libsoundtouch/src/FIRFilter.h
+++ b/media/libsoundtouch/src/FIRFilter.h
@@ -6,23 +6,16 @@
 /// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIRFilter.h 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
--- a/media/libsoundtouch/src/InterpolateCubic.cpp
+++ b/media/libsoundtouch/src/InterpolateCubic.cpp
@@ -3,20 +3,16 @@
 /// Cubic interpolation routine.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateCubic.cpp 179 2014-01-06 18:41:42Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
--- a/media/libsoundtouch/src/InterpolateCubic.h
+++ b/media/libsoundtouch/src/InterpolateCubic.h
@@ -3,20 +3,16 @@
 /// Cubic interpolation routine.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateCubic.h 179 2014-01-06 18:41:42Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -51,17 +47,17 @@ protected:
                         int &srcSamples);
     virtual int transposeStereo(SAMPLETYPE *dest, 
                         const SAMPLETYPE *src, 
                         int &srcSamples);
     virtual int transposeMulti(SAMPLETYPE *dest, 
                         const SAMPLETYPE *src, 
                         int &srcSamples);
 
-    float fract;
+    double fract;
 
 public:
     InterpolateCubic();
 };
 
 }
 
 #endif
--- a/media/libsoundtouch/src/InterpolateLinear.cpp
+++ b/media/libsoundtouch/src/InterpolateLinear.cpp
@@ -3,20 +3,16 @@
 /// Linear interpolation algorithm.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateLinear.cpp 180 2014-01-06 19:16:02Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -165,19 +161,19 @@ int InterpolateLinearInteger::transposeM
     srcSamples = srcCount;
 
     return i;
 }
 
 
 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
 // iRate, larger faster iRates.
-void InterpolateLinearInteger::setRate(float newRate)
+void InterpolateLinearInteger::setRate(double newRate)
 {
-    iRate = (int)(newRate * SCALE + 0.5f);
+    iRate = (int)(newRate * SCALE + 0.5);
     TransposerBase::setRate(newRate);
 }
 
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // InterpolateLinearFloat - floating point arithmetic implementation
 // 
@@ -185,17 +181,17 @@ void InterpolateLinearInteger::setRate(f
 
 
 // Constructor
 InterpolateLinearFloat::InterpolateLinearFloat() : TransposerBase()
 {
     // Notice: use local function calling syntax for sake of clarity, 
     // to indicate the fact that C++ constructor can't call virtual functions.
     resetRegisters();
-    setRate(1.0f);
+    setRate(1.0);
 }
 
 
 void InterpolateLinearFloat::resetRegisters()
 {
     fract = 0;
 }
 
@@ -270,22 +266,23 @@ int InterpolateLinearFloat::transposeMul
 {
     int i;
     int srcSampleEnd = srcSamples - 1;
     int srcCount = 0;
 
     i = 0;
     while (srcCount < srcSampleEnd)
     {
-        float temp, vol1;
+        float temp, vol1, fract_float;
     
-        vol1 = (1.0f- fract);
+        vol1 = (float)(1.0 - fract);
+		fract_float = (float)fract;
         for (int c = 0; c < numChannels; c ++)
         {
-            temp = vol1 * src[c] + fract * src[c + numChannels];
+			temp = vol1 * src[c] + fract_float * src[c + numChannels];
             *dest = (SAMPLETYPE)temp;
             dest ++;
         }
         i++;
 
         fract += rate;
 
         int iWhole = (int)fract;
--- a/media/libsoundtouch/src/InterpolateLinear.h
+++ b/media/libsoundtouch/src/InterpolateLinear.h
@@ -3,20 +3,16 @@
 /// Linear interpolation routine.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateLinear.h 179 2014-01-06 18:41:42Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -37,17 +33,17 @@
 #define _InterpolateLinear_H_
 
 #include "RateTransposer.h"
 #include "STTypes.h"
 
 namespace soundtouch
 {
 
-/// Linear transposer class that uses integer arithmetics
+/// Linear transposer class that uses integer arithmetic
 class InterpolateLinearInteger : public TransposerBase
 {
 protected:
     int iFract;
     int iRate;
 
     virtual void resetRegisters();
 
@@ -58,25 +54,25 @@ protected:
                          const SAMPLETYPE *src, 
                          int &srcSamples);
     virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
 public:
     InterpolateLinearInteger();
 
     /// Sets new target rate. Normal rate = 1.0, smaller values represent slower 
     /// rate, larger faster rates.
-    virtual void setRate(float newRate);
+    virtual void setRate(double newRate);
 };
 
 
-/// Linear transposer class that uses floating point arithmetics
+/// Linear transposer class that uses floating point arithmetic
 class InterpolateLinearFloat : public TransposerBase
 {
 protected:
-    float fract;
+    double fract;
 
     virtual void resetRegisters();
 
     virtual int transposeMono(SAMPLETYPE *dest, 
                        const SAMPLETYPE *src, 
                        int &srcSamples);
     virtual int transposeStereo(SAMPLETYPE *dest, 
                          const SAMPLETYPE *src, 
--- a/media/libsoundtouch/src/InterpolateShannon.cpp
+++ b/media/libsoundtouch/src/InterpolateShannon.cpp
@@ -8,20 +8,16 @@
 /// for experimental purposes
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateShannon.cpp 195 2014-04-06 15:57:21Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
--- a/media/libsoundtouch/src/InterpolateShannon.h
+++ b/media/libsoundtouch/src/InterpolateShannon.h
@@ -8,20 +8,16 @@
 /// for experimental purposes
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// $Id: InterpolateShannon.h 179 2014-01-06 18:41:42Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -56,17 +52,17 @@ protected:
                         int &srcSamples);
     int transposeStereo(SAMPLETYPE *dest, 
                         const SAMPLETYPE *src, 
                         int &srcSamples);
     int transposeMulti(SAMPLETYPE *dest, 
                         const SAMPLETYPE *src, 
                         int &srcSamples);
 
-    float fract;
+    double fract;
 
 public:
     InterpolateShannon();
 };
 
 }
 
 #endif
--- a/media/libsoundtouch/src/RateTransposer.cpp
+++ b/media/libsoundtouch/src/RateTransposer.cpp
@@ -5,23 +5,16 @@
 /// alias filtering should be quite adequate for this application)
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: RateTransposer.cpp 195 2014-04-06 15:57:21Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -52,70 +45,76 @@ using namespace soundtouch;
 
 // Define default interpolation algorithm here
 TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
 
 
 // Constructor
 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
 {
-    bUseAAFilter = true;
+    bUseAAFilter = 
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+        true;
+#else
+        // Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
+        false;
+#endif
 
     // Instantiates the anti-alias filter
     pAAFilter = new AAFilter(64);
     pTransposer = TransposerBase::newInstance();
 }
 
 
-
 RateTransposer::~RateTransposer()
 {
     delete pAAFilter;
     delete pTransposer;
 }
 
 
-
 /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
 void RateTransposer::enableAAFilter(bool newMode)
 {
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+    // Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
     bUseAAFilter = newMode;
+#endif
 }
 
 
 /// Returns nonzero if anti-alias filter is enabled.
 bool RateTransposer::isAAFilterEnabled() const
 {
     return bUseAAFilter;
 }
 
 
 AAFilter *RateTransposer::getAAFilter()
 {
     return pAAFilter;
 }
 
 
-
 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
 // iRate, larger faster iRates.
-void RateTransposer::setRate(float newRate)
+void RateTransposer::setRate(double newRate)
 {
     double fCutoff;
 
     pTransposer->setRate(newRate);
 
     // design a new anti-alias filter
-    if (newRate > 1.0f) 
+    if (newRate > 1.0) 
     {
-        fCutoff = 0.5f / newRate;
+        fCutoff = 0.5 / newRate;
     } 
     else 
     {
-        fCutoff = 0.5f * newRate;
+        fCutoff = 0.5 * newRate;
     }
     pAAFilter->setCutoffFreq(fCutoff);
 }
 
 
 // Adds 'nSamples' pcs of samples from the 'samples' memory position into
 // the input of the object.
 void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
@@ -172,21 +171,20 @@ void RateTransposer::processSamples(cons
         pTransposer->transpose(outputBuffer, midBuffer);
     }
 }
 
 
 // Sets the number of channels, 1 = mono, 2 = stereo
 void RateTransposer::setChannels(int nChannels)
 {
-    assert(nChannels > 0);
+    if (!verifyNumberOfChannels(nChannels) ||
+        (pTransposer->numChannels == nChannels)) return;
 
-    if (pTransposer->numChannels == nChannels) return;
     pTransposer->setChannels(nChannels);
-
     inputBuffer.setChannels(nChannels);
     midBuffer.setChannels(nChannels);
     outputBuffer.setChannels(nChannels);
 }
 
 
 // Clears all the samples in the object
 void RateTransposer::clear()
@@ -203,16 +201,23 @@ int RateTransposer::isEmpty() const
     int res;
 
     res = FIFOProcessor::isEmpty();
     if (res == 0) return 0;
     return inputBuffer.isEmpty();
 }
 
 
+/// Return approximate initial input-output latency
+int RateTransposer::getLatency() const
+{
+    return (bUseAAFilter) ? pAAFilter->getLength() : 0;
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // TransposerBase - Base class for interpolation
 // 
 
 // static function to set interpolation algorithm
 void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a)
 {
@@ -220,17 +225,17 @@ void TransposerBase::setAlgorithm(Transp
 }
 
 
 // Transposes the sample rate of the given samples using linear interpolation. 
 // Returns the number of samples returned in the "dest" buffer
 int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src)
 {
     int numSrcSamples = src.numSamples();
-    int sizeDemand = (int)((float)numSrcSamples / rate) + 8;
+    int sizeDemand = (int)((double)numSrcSamples / rate) + 8;
     int numOutput;
     SAMPLETYPE *psrc = src.ptrBegin();
     SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand);
 
 #ifndef USE_MULTICH_ALWAYS
     if (numChannels == 1)
     {
         numOutput = transposeMono(pdest, psrc, numSrcSamples);
@@ -265,27 +270,27 @@ TransposerBase::~TransposerBase()
 
 void TransposerBase::setChannels(int channels)
 {
     numChannels = channels;
     resetRegisters();
 }
 
 
-void TransposerBase::setRate(float newRate)
+void TransposerBase::setRate(double newRate)
 {
     rate = newRate;
 }
 
 
 // static factory function
 TransposerBase *TransposerBase::newInstance()
 {
 #ifdef SOUNDTOUCH_INTEGER_SAMPLES
-    // Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
+    // Notice: For integer arithmetic support only linear algorithm (due to simplest calculus)
     return ::new InterpolateLinearInteger;
 #else
     switch (algorithm)
     {
         case LINEAR:
             return new InterpolateLinearFloat;
 
         case CUBIC:
--- a/media/libsoundtouch/src/RateTransposer.h
+++ b/media/libsoundtouch/src/RateTransposer.h
@@ -9,23 +9,16 @@
 /// algorithm implementation.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: RateTransposer.h 195 2014-04-06 15:57:21Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -76,24 +69,24 @@ protected:
                         int &srcSamples) = 0;
     virtual int transposeMulti(SAMPLETYPE *dest, 
                         const SAMPLETYPE *src, 
                         int &srcSamples) = 0;
 
     static ALGORITHM algorithm;
 
 public:
-    float rate;
+    double rate;
     int numChannels;
 
     TransposerBase();
     virtual ~TransposerBase();
 
     virtual int transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src);
-    virtual void setRate(float newRate);
+    virtual void setRate(double newRate);
     virtual void setChannels(int channels);
 
     // static factory function
     static TransposerBase *newInstance();
 
     // static function to set interpolation algorithm
     static void setAlgorithm(ALGORITHM a);
 };
@@ -127,53 +120,44 @@ protected:
     /// the 'set_returnBuffer_size' function.
     void processSamples(const SAMPLETYPE *src, 
                         uint numSamples);
 
 public:
     RateTransposer();
     virtual ~RateTransposer();
 
-    /// Operator 'new' is overloaded so that it automatically creates a suitable instance 
-    /// depending on if we're to use integer or floating point arithmetics.
-//    static void *operator new(size_t s);
-
-    /// Use this function instead of "new" operator to create a new instance of this class. 
-    /// This function automatically chooses a correct implementation, depending on if 
-    /// integer ot floating point arithmetics are to be used.
-//    static RateTransposer *newInstance();
-
     /// Returns the output buffer object
     FIFOSamplePipe *getOutput() { return &outputBuffer; };
 
-    /// Returns the store buffer object
-//    FIFOSamplePipe *getStore() { return &storeBuffer; };
-
     /// Return anti-alias filter object
     AAFilter *getAAFilter();
 
     /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
     void enableAAFilter(bool newMode);
 
     /// Returns nonzero if anti-alias filter is enabled.
     bool isAAFilterEnabled() const;
 
     /// Sets new target rate. Normal rate = 1.0, smaller values represent slower 
     /// rate, larger faster rates.
-    virtual void setRate(float newRate);
+    virtual void setRate(double newRate);
 
     /// Sets the number of channels, 1 = mono, 2 = stereo
     void setChannels(int channels);
 
     /// Adds 'numSamples' pcs of samples from the 'samples' memory position into
     /// the input of the object.
     void putSamples(const SAMPLETYPE *samples, uint numSamples);
 
     /// Clears all the samples in the object
     void clear();
 
     /// Returns nonzero if there aren't any samples available for outputting.
     int isEmpty() const;
+
+    /// Return approximate initial input-output latency
+    int getLatency() const;
 };
 
 }
 
 #endif
--- a/media/libsoundtouch/src/STTypes.h
+++ b/media/libsoundtouch/src/STTypes.h
@@ -3,23 +3,16 @@
 /// Common type definitions for SoundTouch audio processing library.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-05-18 15:25:07 +0000 (Mon, 18 May 2015) $
-// File revision : $Revision: 3 $
-//
-// $Id: STTypes.h 215 2015-05-18 15:25:07Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -63,16 +56,19 @@ typedef unsigned long   ulong;
 #define SOUNDTOUCH_API __declspec(dllimport)
 #endif
 #else
 #define SOUNDTOUCH_API
 #endif
 
 namespace soundtouch
 {
+    /// Max allowed number of channels
+    #define SOUNDTOUCH_MAX_CHANNELS     16
+
     /// Activate these undef's to overrule the possible sampletype 
     /// setting inherited from some other header file:
     //#undef SOUNDTOUCH_INTEGER_SAMPLES
     //#undef SOUNDTOUCH_FLOAT_SAMPLES
 
     /// If following flag is defined, always uses multichannel processing 
     /// routines also for mono and stero sound. This is for routine testing 
     /// purposes; output should be same with either routines, yet disabling 
@@ -143,18 +139,20 @@ namespace soundtouch
         typedef long  LONG_SAMPLETYPE;
 
         #ifdef SOUNDTOUCH_FLOAT_SAMPLES
             // check that only one sample type is defined
             #error "conflicting sample types defined"
         #endif // SOUNDTOUCH_FLOAT_SAMPLES
 
         #ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
-            // Allow MMX optimizations
-            #define SOUNDTOUCH_ALLOW_MMX   1
+            // Allow MMX optimizations (not available in X64 mode)
+            #if (!_M_X64)
+                #define SOUNDTOUCH_ALLOW_MMX   1
+            #endif
         #endif
 
     #else
 
         // floating point samples
         typedef float  SAMPLETYPE;
         // data type for sample accumulation: Use double to utilize full precision.
         typedef double LONG_SAMPLETYPE;
--- a/media/libsoundtouch/src/SoundTouch.cpp
+++ b/media/libsoundtouch/src/SoundTouch.cpp
@@ -36,23 +36,16 @@
 ///   combining the two other controls.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-10-08 15:26:57 +0000 (Wed, 08 Oct 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: SoundTouch.cpp 201 2014-10-08 15:26:57Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -105,30 +98,31 @@ SoundTouch::SoundTouch()
     rate = tempo = 0;
 
     virtualPitch = 
     virtualRate = 
     virtualTempo = 1.0;
 
     calcEffectiveRateAndTempo();
 
+    samplesExpectedOut = 0;
+    samplesOutput = 0;
+
     channels = 0;
     bSrateSet = false;
 }
 
 
-
 SoundTouch::~SoundTouch()
 {
     delete pRateTransposer;
     delete pTDStretch;
 }
 
 
-
 /// Get SoundTouch library version string
 const char *SoundTouch::getVersionString()
 {
     static const char *_version = SOUNDTOUCH_VERSION;
 
     return _version;
 }
 
@@ -138,109 +132,98 @@ uint SoundTouch::getVersionId()
 {
     return SOUNDTOUCH_VERSION_ID;
 }
 
 
 // Sets the number of channels, 1 = mono, 2 = stereo
 void SoundTouch::setChannels(uint numChannels)
 {
-    /*if (numChannels != 1 && numChannels != 2) 
-    {
-        //ST_THROW_RT_ERROR("Illegal number of channels");
-		return;
-    }*/
+    if (!verifyNumberOfChannels(numChannels)) return;
+
     channels = numChannels;
     pRateTransposer->setChannels((int)numChannels);
     pTDStretch->setChannels((int)numChannels);
 }
 
 
-
 // Sets new rate control value. Normal rate = 1.0, smaller values
 // represent slower rate, larger faster rates.
-void SoundTouch::setRate(float newRate)
+void SoundTouch::setRate(double newRate)
 {
     virtualRate = newRate;
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets new rate control value as a difference in percents compared
 // to the original rate (-50 .. +100 %)
-void SoundTouch::setRateChange(float newRate)
+void SoundTouch::setRateChange(double newRate)
 {
-    virtualRate = 1.0f + 0.01f * newRate;
+    virtualRate = 1.0 + 0.01 * newRate;
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets new tempo control value. Normal tempo = 1.0, smaller values
 // represent slower tempo, larger faster tempo.
-void SoundTouch::setTempo(float newTempo)
+void SoundTouch::setTempo(double newTempo)
 {
     virtualTempo = newTempo;
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets new tempo control value as a difference in percents compared
 // to the original tempo (-50 .. +100 %)
-void SoundTouch::setTempoChange(float newTempo)
+void SoundTouch::setTempoChange(double newTempo)
 {
-    virtualTempo = 1.0f + 0.01f * newTempo;
+    virtualTempo = 1.0 + 0.01 * newTempo;
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets new pitch control value. Original pitch = 1.0, smaller values
 // represent lower pitches, larger values higher pitch.
-void SoundTouch::setPitch(float newPitch)
+void SoundTouch::setPitch(double newPitch)
 {
     virtualPitch = newPitch;
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets pitch change in octaves compared to the original pitch
 // (-1.00 .. +1.00)
-void SoundTouch::setPitchOctaves(float newPitch)
+void SoundTouch::setPitchOctaves(double newPitch)
 {
-    virtualPitch = (float)exp(0.69314718056f * newPitch);
+    virtualPitch = exp(0.69314718056 * newPitch);
     calcEffectiveRateAndTempo();
 }
 
 
-
 // Sets pitch change in semi-tones compared to the original pitch
 // (-12 .. +12)
 void SoundTouch::setPitchSemiTones(int newPitch)
 {
-    setPitchOctaves((float)newPitch / 12.0f);
+    setPitchOctaves((double)newPitch / 12.0);
 }
 
 
-
-void SoundTouch::setPitchSemiTones(float newPitch)
+void SoundTouch::setPitchSemiTones(double newPitch)
 {
-    setPitchOctaves(newPitch / 12.0f);
+    setPitchOctaves(newPitch / 12.0);
 }
 
 
 // Calculates 'effective' rate and tempo values from the
 // nominal control values.
 void SoundTouch::calcEffectiveRateAndTempo()
 {
-    float oldTempo = tempo;
-    float oldRate = rate;
+    double oldTempo = tempo;
+    double oldRate = rate;
 
     tempo = virtualTempo / virtualPitch;
     rate = virtualPitch * virtualRate;
 
     if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
     if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
 
 #ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
@@ -278,52 +261,41 @@ void SoundTouch::calcEffectiveRateAndTem
         }
     } 
 }
 
 
 // Sets sample rate.
 void SoundTouch::setSampleRate(uint srate)
 {
-    bSrateSet = true;
     // set sample rate, leave other tempo changer parameters as they are.
     pTDStretch->setParameters((int)srate);
+    bSrateSet = true;
 }
 
 
 // Adds 'numSamples' pcs of samples from the 'samples' memory position into
 // the input of the object.
 void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
 {
     if (bSrateSet == false) 
     {
         ST_THROW_RT_ERROR("SoundTouch : Sample rate not defined");
     } 
     else if (channels == 0) 
     {
         ST_THROW_RT_ERROR("SoundTouch : Number of channels not defined");
     }
 
-    // Transpose the rate of the new samples if necessary
-    /* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
-    if (rate == 1.0f) 
-    {
-        // The rate value is same as the original, simply evaluate the tempo changer. 
-        assert(output == pTDStretch);
-        if (pRateTransposer->isEmpty() == 0) 
-        {
-            // yet flush the last samples in the pitch transposer buffer
-            // (may happen if 'rate' changes from a non-zero value to zero)
-            pTDStretch->moveSamples(*pRateTransposer);
-        }
-        pTDStretch->putSamples(samples, nSamples);
-    } 
-    */
+    // accumulate how many samples are expected out from processing, given the current 
+    // processing setting
+    samplesExpectedOut += (double)nSamples / ((double)rate * (double)tempo);
+
 #ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
-    else if (rate <= 1.0f) 
+    if (rate <= 1.0f) 
     {
         // transpose the rate down, output the transposed sound to tempo changer buffer
         assert(output == pTDStretch);
         pRateTransposer->putSamples(samples, nSamples);
         pTDStretch->moveSamples(*pRateTransposer);
     } 
     else 
 #endif
@@ -341,54 +313,40 @@ void SoundTouch::putSamples(const SAMPLE
 //
 // Note: This function is meant for extracting the last samples of a sound
 // stream. This function may introduce additional blank samples in the end
 // of the sound stream, and thus it's not recommended to call this function
 // in the middle of a sound stream.
 void SoundTouch::flush()
 {
     int i;
-    int nUnprocessed;
-    int nOut;
-    SAMPLETYPE *buff = new SAMPLETYPE[64 * channels];
-    
-    // check how many samples still await processing, and scale
-    // that by tempo & rate to get expected output sample count
-    nUnprocessed = numUnprocessedSamples();
-    nUnprocessed = (int)((double)nUnprocessed / (tempo * rate) + 0.5);
+    int numStillExpected;
+    SAMPLETYPE *buff = new SAMPLETYPE[128 * channels];
 
-    nOut = numSamples();        // ready samples currently in buffer ...
-    nOut += nUnprocessed;       // ... and how many we expect there to be in the end
-    
-    memset(buff, 0, 64 * channels * sizeof(SAMPLETYPE));
+    // how many samples are still expected to output
+    numStillExpected = (int)((long)(samplesExpectedOut + 0.5) - samplesOutput);
+    if (numStillExpected < 0) numStillExpected = 0;
+
+    memset(buff, 0, 128 * channels * sizeof(SAMPLETYPE));
     // "Push" the last active samples out from the processing pipeline by
     // feeding blank samples into the processing pipeline until new, 
     // processed samples appear in the output (not however, more than 
-    // 8ksamples in any case)
-    for (i = 0; i < 128; i ++) 
+    // 24ksamples in any case)
+    for (i = 0; (numStillExpected > (int)numSamples()) && (i < 200); i ++)
     {
-        putSamples(buff, 64);
-        if ((int)numSamples() >= nOut) 
-        {
-            // Enough new samples have appeared into the output!
-            // As samples come from processing with bigger chunks, now truncate it
-            // back to maximum "nOut" samples to improve duration accuracy 
-            adjustAmountOfSamples(nOut);
+        putSamples(buff, 128);
+    }
 
-            // finish
-            break;  
-        }
-    }
+    adjustAmountOfSamples(numStillExpected);
 
     delete[] buff;
 
-    // Clear working buffers
-    pRateTransposer->clear();
+    // Clear input buffers
     pTDStretch->clearInput();
-    // yet leave the 'tempoChanger' output intouched as that's where the
+    // yet leave the output intouched as that's where the
     // flushed samples are!
 }
 
 
 // Changes a setting controlling the processing system behaviour. See the
 // 'SETTING_...' defines for available setting ID's.
 bool SoundTouch::setSetting(int settingId, int value)
 {
@@ -447,58 +405,134 @@ int SoundTouch::getSetting(int settingId
     {
         case SETTING_USE_AA_FILTER :
             return (uint)pRateTransposer->isAAFilterEnabled();
 
         case SETTING_AA_FILTER_LENGTH :
             return pRateTransposer->getAAFilter()->getLength();
 
         case SETTING_USE_QUICKSEEK :
-            return (uint)   pTDStretch->isQuickSeekEnabled();
+            return (uint)pTDStretch->isQuickSeekEnabled();
 
         case SETTING_SEQUENCE_MS:
             pTDStretch->getParameters(NULL, &temp, NULL, NULL);
             return temp;
 
         case SETTING_SEEKWINDOW_MS:
             pTDStretch->getParameters(NULL, NULL, &temp, NULL);
             return temp;
 
         case SETTING_OVERLAP_MS:
             pTDStretch->getParameters(NULL, NULL, NULL, &temp);
             return temp;
 
-		case SETTING_NOMINAL_INPUT_SEQUENCE :
-			return pTDStretch->getInputSampleReq();
+        case SETTING_NOMINAL_INPUT_SEQUENCE :
+        {
+            int size = pTDStretch->getInputSampleReq();
+
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+            if (rate <= 1.0)
+            {
+                // transposing done before timestretch, which impacts latency
+                return (int)(size * rate + 0.5);
+            }
+#endif
+            return size;
+        }
+
+        case SETTING_NOMINAL_OUTPUT_SEQUENCE :
+        {
+            int size = pTDStretch->getOutputBatchSize();
 
-		case SETTING_NOMINAL_OUTPUT_SEQUENCE :
-			return pTDStretch->getOutputBatchSize();
+            if (rate > 1.0)
+            {
+                // transposing done after timestretch, which impacts latency
+                return (int)(size / rate + 0.5);
+            }
+            return size;
+        }
+
+        case SETTING_INITIAL_LATENCY:
+        {
+            double latency = pTDStretch->getLatency();
+            int latency_tr = pRateTransposer->getLatency();
 
-		default :
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+            if (rate <= 1.0)
+            {
+                // transposing done before timestretch, which impacts latency
+                latency = (latency + latency_tr) * rate;
+            }
+            else
+#endif
+            {
+                latency += (double)latency_tr / rate;
+            }
+
+            return (int)(latency + 0.5);
+        }
+
+        default :
             return 0;
     }
 }
 
 
 // Clears all the samples in the object's output and internal processing
 // buffers.
 void SoundTouch::clear()
 {
+    samplesExpectedOut = 0;
+    samplesOutput = 0;
     pRateTransposer->clear();
     pTDStretch->clear();
 }
 
 
-
 /// Returns number of samples currently unprocessed.
 uint SoundTouch::numUnprocessedSamples() const
 {
     FIFOSamplePipe * psp;
     if (pTDStretch)
     {
         psp = pTDStretch->getInput();
         if (psp)
         {
             return psp->numSamples();
         }
     }
     return 0;
 }
+
+
+/// Output samples from beginning of the sample buffer. Copies requested samples to 
+/// output buffer and removes them from the sample buffer. If there are less than 
+/// 'numsample' samples in the buffer, returns all that available.
+///
+/// \return Number of samples returned.
+uint SoundTouch::receiveSamples(SAMPLETYPE *output, uint maxSamples)
+{
+    uint ret = FIFOProcessor::receiveSamples(output, maxSamples);
+    samplesOutput += (long)ret;
+    return ret;
+}
+
+
+/// Adjusts book-keeping so that given number of samples are removed from beginning of the 
+/// sample buffer without copying them anywhere. 
+///
+/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
+/// with 'ptrBegin' function.
+uint SoundTouch::receiveSamples(uint maxSamples)
+{
+    uint ret = FIFOProcessor::receiveSamples(maxSamples);
+    samplesOutput += (long)ret;
+    return ret;
+}
+
+
+/// Get ratio between input and output audio durations, useful for calculating
+/// processed output duration: if you'll process a stream of N samples, then 
+/// you can expect to get out N * getInputOutputSampleRatio() samples.
+double SoundTouch::getInputOutputSampleRatio()
+{
+    return 1.0 / (tempo * rate);
+}
--- a/media/libsoundtouch/src/SoundTouch.h
+++ b/media/libsoundtouch/src/SoundTouch.h
@@ -36,23 +36,16 @@
 ///   combining the two other controls.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-05-18 15:28:41 +0000 (Mon, 18 May 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: SoundTouch.h 216 2015-05-18 15:28:41Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -74,20 +67,20 @@
 
 #include "FIFOSamplePipe.h"
 #include "STTypes.h"
 
 namespace soundtouch
 {
 
 /// Soundtouch library version string
-#define SOUNDTOUCH_VERSION          "1.9.0"
+#define SOUNDTOUCH_VERSION          "2.1.3"
 
 /// SoundTouch library version id
-#define SOUNDTOUCH_VERSION_ID       (10900)
+#define SOUNDTOUCH_VERSION_ID       (20103)
 
 //
 // Available setting IDs for the 'setSetting' & 'get_setting' functions:
 
 /// Enable/disable anti-alias filter in pitch transposer (0 = disable)
 #define SETTING_USE_AA_FILTER       0
 
 /// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
@@ -111,121 +104,177 @@ namespace soundtouch
 
 /// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences 
 /// are mixed back together, to form a continuous sound stream, this parameter defines over 
 /// how long period the two consecutive sequences are let to overlap each other. 
 /// See "STTypes.h" or README for more information.
 #define SETTING_OVERLAP_MS          5
 
 
-/// Call "getSetting" with this ID to query nominal average processing sequence
-/// size in samples. This value tells approcimate value how many input samples 
-/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
+/// Call "getSetting" with this ID to query processing sequence size in samples. 
+/// This value gives approximate value of how many input samples you'll need to 
+/// feed into SoundTouch after initial buffering to get out a new batch of
+/// output samples. 
+///
+/// This value does not include initial buffering at beginning of a new processing 
+/// stream, use SETTING_INITIAL_LATENCY to get the initial buffering size.
 ///
 /// Notices: 
 /// - This is read-only parameter, i.e. setSetting ignores this parameter
-/// - Returned value is approximate average value, exact processing batch
-///   size may wary from time to time
-/// - This parameter value is not constant but may change depending on 
+/// - This parameter value is not constant but change depending on 
 ///   tempo/pitch/rate/samplerate settings.
-#define SETTING_NOMINAL_INPUT_SEQUENCE		6
+#define SETTING_NOMINAL_INPUT_SEQUENCE      6
 
 
 /// Call "getSetting" with this ID to query nominal average processing output 
 /// size in samples. This value tells approcimate value how many output samples 
 /// SoundTouch outputs once it does DSP processing run for a batch of input samples.
-///	
+///
 /// Notices: 
 /// - This is read-only parameter, i.e. setSetting ignores this parameter
-/// - Returned value is approximate average value, exact processing batch
-///   size may wary from time to time
-/// - This parameter value is not constant but may change depending on 
+/// - This parameter value is not constant but change depending on 
 ///   tempo/pitch/rate/samplerate settings.
-#define SETTING_NOMINAL_OUTPUT_SEQUENCE		7
+#define SETTING_NOMINAL_OUTPUT_SEQUENCE     7
+
+
+/// Call "getSetting" with this ID to query initial processing latency, i.e.
+/// approx. how many samples you'll need to enter to SoundTouch pipeline before 
+/// you can expect to get first batch of ready output samples out. 
+///
+/// After the first output batch, you can then expect to get approx. 
+/// SETTING_NOMINAL_OUTPUT_SEQUENCE ready samples out for every
+/// SETTING_NOMINAL_INPUT_SEQUENCE samples that you enter into SoundTouch.
+///
+/// Example:
+///     processing with parameter -tempo=5
+///     => initial latency = 5509 samples
+///        input sequence  = 4167 samples
+///        output sequence = 3969 samples
+///
+/// Accordingly, you can expect to feed in approx. 5509 samples at beginning of 
+/// the stream, and then you'll get out the first 3969 samples. After that, for 
+/// every approx. 4167 samples that you'll put in, you'll receive again approx. 
+/// 3969 samples out.
+///
+/// This also means that average latency during stream processing is 
+/// INITIAL_LATENCY-OUTPUT_SEQUENCE/2, in the above example case 5509-3969/2 
+/// = 3524 samples
+/// 
+/// Notices: 
+/// - This is read-only parameter, i.e. setSetting ignores this parameter
+/// - This parameter value is not constant but change depending on 
+///   tempo/pitch/rate/samplerate settings.
+#define SETTING_INITIAL_LATENCY             8
+
 
 class SOUNDTOUCH_API SoundTouch : public FIFOProcessor
 {
 private:
     /// Rate transposer class instance
     class RateTransposer *pRateTransposer;
 
     /// Time-stretch class instance
     class TDStretch *pTDStretch;
 
     /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
-    float virtualRate;
+    double virtualRate;
 
     /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
-    float virtualTempo;
+    double virtualTempo;
 
     /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
-    float virtualPitch;
+    double virtualPitch;
 
     /// Flag: Has sample rate been set?
     bool  bSrateSet;
 
+    /// Accumulator for how many samples in total will be expected as output vs. samples put in,
+    /// considering current processing settings.
+    double samplesExpectedOut;
+
+    /// Accumulator for how many samples in total have been read out from the processing so far
+    long   samplesOutput;
+
     /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and 
     /// 'virtualPitch' parameters.
     void calcEffectiveRateAndTempo();
 
 protected :
     /// Number of channels
     uint  channels;
 
     /// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
-    float rate;
+    double rate;
 
     /// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
-    float tempo;
+    double tempo;
 
 public:
     SoundTouch();
     virtual ~SoundTouch();
 
     /// Get SoundTouch library version string
     static const char *getVersionString();
 
     /// Get SoundTouch library version Id
     static uint getVersionId();
 
     /// Sets new rate control value. Normal rate = 1.0, smaller values
     /// represent slower rate, larger faster rates.
-    void setRate(float newRate);
+    void setRate(double newRate);
 
     /// Sets new tempo control value. Normal tempo = 1.0, smaller values
     /// represent slower tempo, larger faster tempo.
-    void setTempo(float newTempo);
+    void setTempo(double newTempo);
 
     /// Sets new rate control value as a difference in percents compared
     /// to the original rate (-50 .. +100 %)
-    void setRateChange(float newRate);
+    void setRateChange(double newRate);
 
     /// Sets new tempo control value as a difference in percents compared
     /// to the original tempo (-50 .. +100 %)
-    void setTempoChange(float newTempo);
+    void setTempoChange(double newTempo);
 
     /// Sets new pitch control value. Original pitch = 1.0, smaller values
     /// represent lower pitches, larger values higher pitch.
-    void setPitch(float newPitch);
+    void setPitch(double newPitch);
 
     /// Sets pitch change in octaves compared to the original pitch  
     /// (-1.00 .. +1.00)
-    void setPitchOctaves(float newPitch);
+    void setPitchOctaves(double newPitch);
 
     /// Sets pitch change in semi-tones compared to the original pitch
     /// (-12 .. +12)
     void setPitchSemiTones(int newPitch);
-    void setPitchSemiTones(float newPitch);
+    void setPitchSemiTones(double newPitch);
 
     /// Sets the number of channels, 1 = mono, 2 = stereo
     void setChannels(uint numChannels);
 
     /// Sets sample rate.
     void setSampleRate(uint srate);
 
+    /// Get ratio between input and output audio durations, useful for calculating
+    /// processed output duration: if you'll process a stream of N samples, then 
+    /// you can expect to get out N * getInputOutputSampleRatio() samples.
+    ///
+    /// This ratio will give accurate target duration ratio for a full audio track, 
+    /// given that the the whole track is processed with same processing parameters.
+    /// 
+    /// If this ratio is applied to calculate intermediate offsets inside a processing
+    /// stream, then this ratio is approximate and can deviate +- some tens of milliseconds 
+    /// from ideal offset, yet by end of the audio stream the duration ratio will become
+    /// exact.
+    ///
+    /// Example: if processing with parameters "-tempo=15 -pitch=-3", the function
+    /// will return value 0.8695652... Now, if processing an audio stream whose duration
+    /// is exactly one million audio samples, then you can expect the processed 
+    /// output duration  be 0.869565 * 1000000 = 869565 samples.
+    double getInputOutputSampleRatio();
+
     /// Flushes the last samples from the processing pipeline to the output.
     /// Clears also the internal processing buffers.
     //
     /// Note: This function is meant for extracting the last samples of a sound
     /// stream. This function may introduce additional blank samples in the end
     /// of the sound stream, and thus it's not recommended to call this function
     /// in the middle of a sound stream.
     void flush();
@@ -235,38 +284,60 @@ public:
     /// calling this function, otherwise throws a runtime_error exception.
     virtual void putSamples(
             const SAMPLETYPE *samples,  ///< Pointer to sample buffer.
             uint numSamples                         ///< Number of samples in buffer. Notice
                                                     ///< that in case of stereo-sound a single sample
                                                     ///< contains data for both channels.
             );
 
+    /// Output samples from beginning of the sample buffer. Copies requested samples to 
+    /// output buffer and removes them from the sample buffer. If there are less than 
+    /// 'numsample' samples in the buffer, returns all that available.
+    ///
+    /// \return Number of samples returned.
+    virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
+        uint maxSamples                 ///< How many samples to receive at max.
+        );
+
+    /// Adjusts book-keeping so that given number of samples are removed from beginning of the 
+    /// sample buffer without copying them anywhere. 
+    ///
+    /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
+    /// with 'ptrBegin' function.
+    virtual uint receiveSamples(uint maxSamples   ///< Remove this many samples from the beginning of pipe.
+        );
+
     /// Clears all the samples in the object's output and internal processing
     /// buffers.
     virtual void clear();
 
     /// Changes a setting controlling the processing system behaviour. See the
     /// 'SETTING_...' defines for available setting ID's.
     /// 
-    /// \return 'true' if the setting was succesfully changed
+    /// \return 'true' if the setting was successfully changed
     bool setSetting(int settingId,   ///< Setting ID number. see SETTING_... defines.
                     int value        ///< New setting value.
                     );
 
     /// Reads a setting controlling the processing system behaviour. See the
     /// 'SETTING_...' defines for available setting ID's.
     ///
     /// \return the setting value.
     int getSetting(int settingId    ///< Setting ID number, see SETTING_... defines.
                    ) const;
 
     /// Returns number of samples currently unprocessed.
     virtual uint numUnprocessedSamples() const;
 
+    /// Return number of channels
+    uint numChannels() const
+    {
+        return channels;
+    }
 
     /// Other handy functions that are implemented in the ancestor classes (see
     /// classes 'FIFOProcessor' and 'FIFOSamplePipe')
     ///
     /// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
     /// - numSamples()     : Get number of 'ready' samples that can be received with 
     ///                      function 'receiveSamples()'
     /// - isEmpty()        : Returns nonzero if there aren't any 'ready' samples.
--- a/media/libsoundtouch/src/TDStretch.cpp
+++ b/media/libsoundtouch/src/TDStretch.cpp
@@ -1,30 +1,29 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// 
 /// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo 
 /// while maintaining the original pitch by using a time domain WSOLA-like 
 /// method with several performance-increasing tweaks.
 ///
-/// Note : MMX optimized functions reside in a separate, platform-specific 
-/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
+/// Notes : MMX optimized functions reside in a separate, platform-specific 
+/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'.
+///
+/// This source file contains OpenMP optimizations that allow speeding up the
+/// corss-correlation algorithm by executing it in several threads / CPU cores 
+/// in parallel. See the following article link for more detailed discussion 
+/// about SoundTouch OpenMP optimizations:
+/// http://www.softwarecoven.com/parallel-computing-in-embedded-mobile-devices
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-22 15:07:12 +0000 (Sun, 22 Feb 2015) $
-// File revision : $Revision: 1.12 $
-//
-// $Id: TDStretch.cpp 205 2015-02-22 15:07:12Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -58,17 +57,17 @@ using namespace soundtouch;
 
 /*****************************************************************************
  *
  * Constant definitions
  *
  *****************************************************************************/
 
 // Table for the hierarchical mixing position seeking algorithm
-static const short _scanOffsets[5][24]={
+const short _scanOffsets[5][24]={
     { 124,  186,  248,  310,  372,  434,  496,  558,  620,  682,  744, 806,
       868,  930,  992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488,   0},
     {-100,  -75,  -50,  -25,   25,   50,   75,  100,    0,    0,    0,   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   0},
     { -20,  -15,  -10,   -5,    5,   10,   15,   20,    0,    0,    0,   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   0},
     {  -4,   -3,   -2,   -1,    1,    2,    3,    4,    0,    0,    0,   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   0},
@@ -89,17 +88,19 @@ TDStretch::TDStretch() : FIFOProcessor(&
 
     pMidBuffer = NULL;
     pMidBufferUnaligned = NULL;
     overlapLength = 0;
 
     bAutoSeqSetting = true;
     bAutoSeekSetting = true;
 
-//    outDebt = 0;
+    maxnorm = 0;
+    maxnormf = 1e8;
+
     skipFract = 0;
 
     tempo = 1.0f;
     setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
     setTempo(1.0f);
 
     clear();
 }
@@ -121,18 +122,23 @@ TDStretch::~TDStretch()
 // 'seekwindowMS' = seeking window length for scanning the best overlapping 
 //      position (default = 28 ms)
 // 'overlapMS' = overlapping length (default = 12 ms)
 
 void TDStretch::setParameters(int aSampleRate, int aSequenceMS, 
                               int aSeekWindowMS, int aOverlapMS)
 {
     // accept only positive parameter values - if zero or negative, use old values instead
-    if (aSampleRate > 0)   this->sampleRate = aSampleRate;
-    if (aOverlapMS > 0)    this->overlapMs = aOverlapMS;
+    if (aSampleRate > 0)
+    {
+        if (aSampleRate > 192000) ST_THROW_RT_ERROR("Error: Excessive samplerate");
+        this->sampleRate = aSampleRate;
+    }
+
+    if (aOverlapMS > 0) this->overlapMs = aOverlapMS;
 
     if (aSequenceMS > 0)
     {
         this->sequenceMs = aSequenceMS;
         bAutoSeqSetting = false;
     } 
     else if (aSequenceMS == 0)
     {
@@ -212,16 +218,17 @@ void TDStretch::clearMidBuffer()
     memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
 }
 
 
 void TDStretch::clearInput()
 {
     inputBuffer.clear();
     clearMidBuffer();
+    isBeginning = true;
 }
 
 
 // Clears the sample buffers
 void TDStretch::clear()
 {
     outputBuffer.clear();
     clearInput();
@@ -245,17 +252,17 @@ bool TDStretch::isQuickSeekEnabled() con
 
 
 // Seeks for the optimal overlap-mixing position.
 int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
 {
     if (bQuickSeek) 
     {
         return seekBestOverlapPositionQuick(refPos);
-    } 
+    }
     else 
     {
         return seekBestOverlapPositionFull(refPos);
     }
 }
 
 
 // Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
@@ -277,36 +284,36 @@ inline void TDStretch::overlap(SAMPLETYP
 #endif // USE_MULTICH_ALWAYS
     {
         assert(channels > 0);
         overlapMulti(pOutput, pInput + channels * ovlPos);
     }
 }
 
 
-
 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
 // routine
 //
 // The best position is determined as the position where the two overlapped
 // sample sequences are 'most alike', in terms of the highest cross-correlation
 // value over the overlapping period
 int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos) 
 {
     int bestOffs;
     double bestCorr;
     int i;
     double norm;
 
-    bestCorr = FLT_MIN;
+    bestCorr = -FLT_MAX;
     bestOffs = 0;
 
     // Scans for the best correlation value by testing each possible position
     // over the permitted range.
     bestCorr = calcCrossCorr(refPos, pMidBuffer, norm);
+    bestCorr = (bestCorr + 0.1) * 0.75;
 
     #pragma omp parallel for
     for (i = 1; i < seekLength; i ++) 
     {
         double corr;
         // Calculates correlation value for the mixing position corresponding to 'i'
 #ifdef _OPENMP
         // in parallel OpenMP mode, can't use norm accumulator version as parallel executor won't
@@ -331,104 +338,202 @@ int TDStretch::seekBestOverlapPositionFu
             #pragma omp critical
             if (corr > bestCorr)
             {
                 bestCorr = corr;
                 bestOffs = i;
             }
         }
     }
+
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
+    adaptNormalizer();
+#endif
+
     // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     clearCrossCorrState();
 
     return bestOffs;
 }
 
 
-// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
-// routine
+// Quick seek algorithm for improved runtime-performance: First roughly scans through the 
+// correlation area, and then scan surroundings of two best preliminary correlation candidates
+// with improved precision
 //
-// The best position is determined as the position where the two overlapped
-// sample sequences are 'most alike', in terms of the highest cross-correlation
-// value over the overlapping period
-int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos) 
+// Based on testing:
+// - This algorithm gives on average 99% as good match as the full algorithm
+// - this quick seek algorithm finds the best match on ~90% of cases
+// - on those 10% of cases when this algorithm doesn't find best match, 
+//   it still finds on average ~90% match vs. the best possible match
+int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
 {
-    int j;
+#define _MIN(a, b)   (((a) < (b)) ? (a) : (b))
+#define SCANSTEP    16
+#define SCANWIND    8
+
     int bestOffs;
-    double bestCorr, corr;
-    int scanCount, corrOffset, tempOffset;
+    int i;
+    int bestOffs2;
+    float bestCorr, corr;
+    float bestCorr2;
+    double norm;
+
+    // note: 'float' types used in this function in case that the platform would need to use software-fp
 
-    bestCorr = FLT_MIN;
-    bestOffs = _scanOffsets[0][0];
-    corrOffset = 0;
-    tempOffset = 0;
+    bestCorr =
+    bestCorr2 = -FLT_MAX;
+    bestOffs = 
+    bestOffs2 = SCANWIND;
 
-    // Scans for the best correlation value using four-pass hierarchical search.
+    // Scans for the best correlation value by testing each possible position
+    // over the permitted range. Look for two best matches on the first pass to
+    // increase possibility of ideal match.
+    //
+    // Begin from "SCANSTEP" instead of SCANWIND to make the calculation
+    // catch the 'middlepoint' of seekLength vector as that's the a-priori 
+    // expected best match position
     //
-    // The look-up table 'scans' has hierarchical position adjusting steps.
-    // In first pass the routine searhes for the highest correlation with 
-    // relatively coarse steps, then rescans the neighbourhood of the highest
-    // correlation with better resolution and so on.
-    for (scanCount = 0;scanCount < 4; scanCount ++) 
+    // Roughly:
+    // - 15% of cases find best result directly on the first round,
+    // - 75% cases find better match on 2nd round around the best match from 1st round
+    // - 10% cases find better match on 2nd round around the 2nd-best-match from 1st round
+    for (i = SCANSTEP; i < seekLength - SCANWIND - 1; i += SCANSTEP)
     {
-        j = 0;
-        while (_scanOffsets[scanCount][j]) 
+        // Calculates correlation value for the mixing position corresponding
+        // to 'i'
+        corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm);
+        // heuristic rule to slightly favour values close to mid of the seek range
+        float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength;
+        corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp));
+
+        // Checks for the highest correlation value
+        if (corr > bestCorr)
         {
-            double norm;
-            tempOffset = corrOffset + _scanOffsets[scanCount][j];
-            if (tempOffset >= seekLength) break;
+            // found new best match. keep the previous best as 2nd best match
+            bestCorr2 = bestCorr;
+            bestOffs2 = bestOffs;
+            bestCorr = corr;
+            bestOffs = i;
+        }
+        else if (corr > bestCorr2)
+        {
+            // not new best, but still new 2nd best match
+            bestCorr2 = corr;
+            bestOffs2 = i;
+        }
+    }
+
+    // Scans surroundings of the found best match with small stepping
+    int end = _MIN(bestOffs + SCANWIND + 1, seekLength);
+    for (i = bestOffs - SCANWIND; i < end; i++)
+    {
+        if (i == bestOffs) continue;    // this offset already calculated, thus skip
 
-            // Calculates correlation value for the mixing position corresponding
-            // to 'tempOffset'
-            corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer, norm);
-            // heuristic rule to slightly favour values close to mid of the range
-            double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
-            corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
+        // Calculates correlation value for the mixing position corresponding
+        // to 'i'
+        corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm);
+        // heuristic rule to slightly favour values close to mid of the range
+        float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength;
+        corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp));
+
+        // Checks for the highest correlation value
+        if (corr > bestCorr)
+        {
+            bestCorr = corr;
+            bestOffs = i;
+        }
+    }
 
-            // Checks for the highest correlation value
-            if (corr > bestCorr) 
-            {
-                bestCorr = corr;
-                bestOffs = tempOffset;
-            }
-            j ++;
+    // Scans surroundings of the 2nd best match with small stepping
+    end = _MIN(bestOffs2 + SCANWIND + 1, seekLength);
+    for (i = bestOffs2 - SCANWIND; i < end; i++)
+    {
+        if (i == bestOffs2) continue;    // this offset already calculated, thus skip
+
+        // Calculates correlation value for the mixing position corresponding
+        // to 'i'
+        corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm);
+        // heuristic rule to slightly favour values close to mid of the range
+        float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength;
+        corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp));
+
+        // Checks for the highest correlation value
+        if (corr > bestCorr)
+        {
+            bestCorr = corr;
+            bestOffs = i;
         }
-        corrOffset = bestOffs;
     }
+
     // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     clearCrossCorrState();
 
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
+    adaptNormalizer();
+#endif
+
     return bestOffs;
 }
 
 
 
+
+/// For integer algorithm: adapt normalization factor divider with music so that 
+/// it'll not be pessimistically restrictive that can degrade quality on quieter sections
+/// yet won't cause integer overflows either
+void TDStretch::adaptNormalizer()
+{
+    // Do not adapt normalizer over too silent sequences to avoid averaging filter depleting to
+    // too low values during pauses in music
+    if ((maxnorm > 1000) || (maxnormf > 40000000))
+    { 
+        //norm averaging filter
+        maxnormf = 0.9f * maxnormf + 0.1f * (float)maxnorm;
+
+        if ((maxnorm > 800000000) && (overlapDividerBitsNorm < 16))
+        {
+            // large values, so increase divider
+            overlapDividerBitsNorm++;
+            if (maxnorm > 1600000000) overlapDividerBitsNorm++; // extra large value => extra increase
+        }
+        else if ((maxnormf < 1000000) && (overlapDividerBitsNorm > 0))
+        {
+            // extra small values, decrease divider
+            overlapDividerBitsNorm--;
+        }
+    }
+
+    maxnorm = 0;
+}
+
+
 /// clear cross correlation routine state if necessary 
 void TDStretch::clearCrossCorrState()
 {
     // default implementation is empty.
 }
 
 
 /// Calculates processing sequence length according to tempo setting
 void TDStretch::calcSeqParameters()
 {
     // Adjust tempo param according to tempo, so that variating processing sequence length is used
-    // at varius tempo settings, between the given low...top limits
+    // at various tempo settings, between the given low...top limits
     #define AUTOSEQ_TEMPO_LOW   0.5     // auto setting low tempo range (-50%)
     #define AUTOSEQ_TEMPO_TOP   2.0     // auto setting top tempo range (+100%)
 
     // sequence-ms setting values at above low & top tempo
-    #define AUTOSEQ_AT_MIN      125.0
-    #define AUTOSEQ_AT_MAX      50.0
+    #define AUTOSEQ_AT_MIN      90.0
+    #define AUTOSEQ_AT_MAX      40.0
     #define AUTOSEQ_K           ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
     #define AUTOSEQ_C           (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW))
 
-    // seek-window-ms setting values at above low & top tempo
-    #define AUTOSEEK_AT_MIN     25.0
+    // seek-window-ms setting values at above low & top tempoq
+    #define AUTOSEEK_AT_MIN     20.0
     #define AUTOSEEK_AT_MAX     15.0
     #define AUTOSEEK_K          ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
     #define AUTOSEEK_C          (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
 
     #define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
 
     double seq, seek;
     
@@ -454,43 +559,42 @@ void TDStretch::calcSeqParameters()
     }
     seekLength = (sampleRate * seekWindowMs) / 1000;
 }
 
 
 
 // Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower 
 // tempo, larger faster tempo.
-void TDStretch::setTempo(float newTempo)
+void TDStretch::setTempo(double newTempo)
 {
     int intskip;
 
     tempo = newTempo;
 
     // Calculate new sequence duration
     calcSeqParameters();
 
     // Calculate ideal skip length (according to tempo value) 
     nominalSkip = tempo * (seekWindowLength - overlapLength);
-    intskip = (int)(nominalSkip + 0.5f);
+    intskip = (int)(nominalSkip + 0.5);
 
     // Calculate how many samples are needed in the 'inputBuffer' to 
     // process another batch of samples
     //sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
     sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
 }
 
 
 
 // Sets the number of channels, 1 = mono, 2 = stereo
 void TDStretch::setChannels(int numChannels)
 {
-    assert(numChannels > 0);
-    if (channels == numChannels) return;
-//    assert(numChannels == 1 || numChannels == 2);
+    if (!verifyNumberOfChannels(numChannels) ||
+        (channels == numChannels)) return;
 
     channels = numChannels;
     inputBuffer.setChannels(channels);
     outputBuffer.setChannels(channels);
 
     // re-init overlap/buffer
     overlapLength=0;
     setParameters(sampleRate);
@@ -529,62 +633,89 @@ void TDStretch::processNominalTempo()
 }
 */
 
 
 // Processes as many processing frames of the samples 'inputBuffer', store
 // the result into 'outputBuffer'
 void TDStretch::processSamples()
 {
-    int ovlSkip, offset;
+    int ovlSkip;
+    int offset = 0;
     int temp;
 
     /* Removed this small optimization - can introduce a click to sound when tempo setting
        crosses the nominal value
     if (tempo == 1.0f) 
     {
         // tempo not changed from the original, so bypass the processing
         processNominalTempo();
         return;
     }
     */
 
     // Process samples as long as there are enough samples in 'inputBuffer'
     // to form a processing frame.
     while ((int)inputBuffer.numSamples() >= sampleReq) 
     {
-        // If tempo differs from the normal ('SCALE'), scan for the best overlapping
-        // position
-        offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
+        if (isBeginning == false)
+        {
+            // apart from the very beginning of the track, 
+            // scan for the best overlapping position & do overlap-add
+            offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
 
-        // Mix the samples in the 'inputBuffer' at position of 'offset' with the 
-        // samples in 'midBuffer' using sliding overlapping
-        // ... first partially overlap with the end of the previous sequence
-        // (that's in 'midBuffer')
-        overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
-        outputBuffer.putSamples((uint)overlapLength);
+            // Mix the samples in the 'inputBuffer' at position of 'offset' with the 
+            // samples in 'midBuffer' using sliding overlapping
+            // ... first partially overlap with the end of the previous sequence
+            // (that's in 'midBuffer')
+            overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
+            outputBuffer.putSamples((uint)overlapLength);
+            offset += overlapLength;
+        }
+        else
+        {
+            // Adjust processing offset at beginning of track by not perform initial overlapping
+            // and compensating that in the 'input buffer skip' calculation
+            isBeginning = false;
+            int skip = (int)(tempo * overlapLength + 0.5);
+
+            #ifdef SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
+                #ifdef SOUNDTOUCH_ALLOW_SSE
+                // if SSE mode, round the skip amount to value corresponding to aligned memory address
+                if (channels == 1)
+                {
+                    skip &= -4;
+                }
+                else if (channels == 2)
+                {
+                    skip &= -2;
+                }
+                #endif
+            #endif
+            skipFract -= skip;
+            assert(nominalSkip >= -skipFract);
+        }
 
         // ... then copy sequence samples from 'inputBuffer' to output:
 
-        // length of sequence
-        temp = (seekWindowLength - 2 * overlapLength);
-
         // crosscheck that we don't have buffer overflow...
-        if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
+        if ((int)inputBuffer.numSamples() < (offset + seekWindowLength - overlapLength))
         {
             continue;    // just in case, shouldn't really happen
         }
 
-        outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
+        // length of sequence
+        temp = (seekWindowLength - 2 * overlapLength);
+        outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * offset, (uint)temp);
 
         // Copies the end of the current sequence from 'inputBuffer' to 
         // 'midBuffer' for being mixed with the beginning of the next 
         // processing sequence and so on
-        assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
-        memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength), 
+        assert((offset + temp + overlapLength) <= (int)inputBuffer.numSamples());
+        memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp), 
             channels * sizeof(SAMPLETYPE) * overlapLength);
 
         // Remove the processed samples from the input buffer. Update
         // the difference between integer & nominal skip step to 'skipFract'
         // in order to prevent the error from accumulating over time.
         skipFract += nominalSkip;   // real skip size
         ovlSkip = (int)skipFract;   // rounded to integer skip
         skipFract -= ovlSkip;       // maintain the fraction part, i.e. real vs. integer skip
@@ -670,17 +801,17 @@ TDStretch * TDStretch::newInstance()
         // ISA optimizations not supported, use plain C version
         return ::new TDStretch;
     }
 }
 
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// Integer arithmetics specific algorithm implementations.
+// Integer arithmetic specific algorithm implementations.
 //
 //////////////////////////////////////////////////////////////////////////////
 
 #ifdef SOUNDTOUCH_INTEGER_SAMPLES
 
 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' 
 // version of the routine.
 void TDStretch::overlapStereo(short *poutput, const short *input) const
@@ -733,103 +864,119 @@ void TDStretch::calculateOverlapLength(i
 {
     int newOvl;
 
     assert(aoverlapMs >= 0);
 
     // calculate overlap length so that it's power of 2 - thus it's easy to do
     // integer division by right-shifting. Term "-1" at end is to account for 
     // the extra most significatnt bit left unused in result by signed multiplication 
-    overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
-    if (overlapDividerBits > 9) overlapDividerBits = 9;
-    if (overlapDividerBits < 3) overlapDividerBits = 3;
-    newOvl = (int)pow(2.0, (int)overlapDividerBits + 1);    // +1 => account for -1 above
+    overlapDividerBitsPure = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
+    if (overlapDividerBitsPure > 9) overlapDividerBitsPure = 9;
+    if (overlapDividerBitsPure < 3) overlapDividerBitsPure = 3;
+    newOvl = (int)pow(2.0, (int)overlapDividerBitsPure + 1);    // +1 => account for -1 above
 
     acceptNewOverlapLength(newOvl);
 
+    overlapDividerBitsNorm = overlapDividerBitsPure;
+
     // calculate sloping divider so that crosscorrelation operation won't 
     // overflow 32-bit register. Max. sum of the crosscorrelation sum without 
     // divider would be 2^30*(N^3-N)/3, where N = overlap length
     slopingDivider = (newOvl * newOvl - 1) / 3;
 }
 
 
-double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const
+double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, double &norm)
 {
     long corr;
-    long lnorm;
+    unsigned long lnorm;
     int i;
 
     corr = lnorm = 0;
     // Same routine for stereo and mono. For stereo, unroll loop for better
     // efficiency and gives slightly better resolution against rounding. 
     // For mono it same routine, just  unrolls loop by factor of 4
     for (i = 0; i < channels * overlapLength; i += 4) 
     {
         corr += (mixingPos[i] * compare[i] + 
-                 mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;  // notice: do intermediate division here to avoid integer overflow
+                 mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm;  // notice: do intermediate division here to avoid integer overflow
         corr += (mixingPos[i + 2] * compare[i + 2] + 
-                 mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
+                mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm;
         lnorm += (mixingPos[i] * mixingPos[i] + 
-                  mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits; // notice: do intermediate division here to avoid integer overflow
+                mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow
         lnorm += (mixingPos[i + 2] * mixingPos[i + 2] + 
-                  mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
+                mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBitsNorm;
     }
 
+    if (lnorm > maxnorm)
+    {
+        // modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
+        #pragma omp critical
+        if (lnorm > maxnorm)
+        {
+            maxnorm = lnorm;
+        }
+    }
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
     norm = (double)lnorm;
     return (double)corr / sqrt((norm < 1e-9) ? 1.0 : norm);
 }
 
 
 /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value
-double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const
+double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm)
 {
     long corr;
-    long lnorm;
+    unsigned long lnorm;
     int i;
 
     // cancel first normalizer tap from previous round
     lnorm = 0;
     for (i = 1; i <= channels; i ++)
     {
-        lnorm -= (mixingPos[-i] * mixingPos[-i]) >> overlapDividerBits;
+        lnorm -= (mixingPos[-i] * mixingPos[-i]) >> overlapDividerBitsNorm;
     }
 
     corr = 0;
     // Same routine for stereo and mono. For stereo, unroll loop for better
     // efficiency and gives slightly better resolution against rounding. 
     // For mono it same routine, just  unrolls loop by factor of 4
     for (i = 0; i < channels * overlapLength; i += 4) 
     {
         corr += (mixingPos[i] * compare[i] + 
-                 mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;  // notice: do intermediate division here to avoid integer overflow
+                 mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm;  // notice: do intermediate division here to avoid integer overflow
         corr += (mixingPos[i + 2] * compare[i + 2] + 
-                 mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
+                 mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm;
     }
 
     // update normalizer with last samples of this round
     for (int j = 0; j < channels; j ++)
     {
         i --;
-        lnorm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits;
+        lnorm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBitsNorm;
     }
+
     norm += (double)lnorm;
+    if (norm > maxnorm)
+    {
+        maxnorm = (unsigned long)norm;
+    }
 
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
     return (double)corr / sqrt((norm < 1e-9) ? 1.0 : norm);
 }
 
 #endif // SOUNDTOUCH_INTEGER_SAMPLES
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// Floating point arithmetics specific algorithm implementations.
+// Floating point arithmetic specific algorithm implementations.
 //
 
 #ifdef SOUNDTOUCH_FLOAT_SAMPLES
 
 // Overlaps samples in 'midBuffer' with the samples in 'pInput'
 void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
 {
     int i;
@@ -893,17 +1040,17 @@ void TDStretch::calculateOverlapLength(i
     // must be divisible by 8
     newOvl -= newOvl % 8;
 
     acceptNewOverlapLength(newOvl);
 }
 
 
 /// Calculate cross-correlation
-double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &anorm) const
+double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &anorm)
 {
     double corr;
     double norm;
     int i;
 
     corr = norm = 0;
     // Same routine for stereo and mono. For Stereo, unroll by factor of 2.
     // For mono it's same routine yet unrollsd by factor of 4.
@@ -924,17 +1071,17 @@ double TDStretch::calcCrossCorr(const fl
     }
 
     anorm = norm;
     return corr / sqrt((norm < 1e-9 ? 1.0 : norm));
 }
 
 
 /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value
-double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const
+double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm)
 {
     double corr;
     int i;
 
     corr = 0;
 
     // cancel first normalizer tap from previous round
     for (i = 1; i <= channels; i ++)
--- a/media/libsoundtouch/src/TDStretch.h
+++ b/media/libsoundtouch/src/TDStretch.h
@@ -8,23 +8,16 @@
 /// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: TDStretch.h 195 2014-04-06 15:57:21Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -107,58 +100,67 @@ namespace soundtouch
 
 /// Class that does the time-stretch (tempo change) effect for the processed
 /// sound.
 class TDStretch : public FIFOProcessor
 {
 protected:
     int channels;
     int sampleReq;
-    float tempo;
 
-    SAMPLETYPE *pMidBuffer;
-    SAMPLETYPE *pMidBufferUnaligned;
     int overlapLength;
     int seekLength;
     int seekWindowLength;
-    int overlapDividerBits;
+    int overlapDividerBitsNorm;
+    int overlapDividerBitsPure;
     int slopingDivider;
-    float nominalSkip;
-    float skipFract;
-    FIFOSampleBuffer outputBuffer;
-    FIFOSampleBuffer inputBuffer;
-    bool bQuickSeek;
-
     int sampleRate;
     int sequenceMs;
     int seekWindowMs;
     int overlapMs;
+
+    unsigned long maxnorm;
+    float maxnormf;
+
+    double tempo;
+    double nominalSkip;
+    double skipFract;
+
+    bool bQuickSeek;
     bool bAutoSeqSetting;
     bool bAutoSeekSetting;
+    bool isBeginning;
+
+    SAMPLETYPE *pMidBuffer;
+    SAMPLETYPE *pMidBufferUnaligned;
+
+    FIFOSampleBuffer outputBuffer;
+    FIFOSampleBuffer inputBuffer;
 
     void acceptNewOverlapLength(int newOverlapLength);
 
     virtual void clearCrossCorrState();
     void calculateOverlapLength(int overlapMs);
 
-    virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const;
-    virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const;
+    virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm);
+    virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm);
 
     virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos);
     virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos);
-    int seekBestOverlapPosition(const SAMPLETYPE *refPos);
+    virtual int seekBestOverlapPosition(const SAMPLETYPE *refPos);
 
     virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
     virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
     virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
 
     void clearMidBuffer();
     void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
 
     void calcSeqParameters();
+    void adaptNormalizer();
 
     /// Changes the tempo of the given sound samples.
     /// Returns amount of samples returned in the "output" buffer.
     /// The maximum amount of samples that can be returned at a time is set by
     /// the 'set_returnBuffer_size' function.
     void processSamples();
     
 public:
@@ -177,17 +179,17 @@ public:
     /// Returns the output buffer object
     FIFOSamplePipe *getOutput() { return &outputBuffer; };
 
     /// Returns the input buffer object
     FIFOSamplePipe *getInput() { return &inputBuffer; };
 
     /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower 
     /// tempo, larger faster tempo.
-    void setTempo(float newTempo);
+    void setTempo(double newTempo);
 
     /// Returns nonzero if there aren't any samples available for outputting.
     virtual void clear();
 
     /// Clears the input buffer
     void clearInput();
 
     /// Sets the number of channels, 1 = mono, 2 = stereo
@@ -233,40 +235,45 @@ public:
         return (int)(nominalSkip + 0.5);
     }
 
     /// return nominal output sample amount when running a processing batch
     int getOutputBatchSize() const
     {
         return seekWindowLength - overlapLength;
     }
+
+	/// return approximate initial input-output latency
+	int getLatency() const
+	{
+		return sampleReq;
+	}
 };
 
 
-
 // Implementation-specific class declarations:
 
 #ifdef SOUNDTOUCH_ALLOW_MMX
     /// Class that implements MMX optimized routines for 16bit integer samples type.
     class TDStretchMMX : public TDStretch
     {
     protected:
-        double calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const;
-        double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const;
+        double calcCrossCorr(const short *mixingPos, const short *compare, double &norm);
+        double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm);
         virtual void overlapStereo(short *output, const short *input) const;
         virtual void clearCrossCorrState();
     };
 #endif /// SOUNDTOUCH_ALLOW_MMX
 
 
 #ifdef SOUNDTOUCH_ALLOW_SSE
     /// Class that implements SSE optimized routines for floating point samples type.
     class TDStretchSSE : public TDStretch
     {
     protected:
-        double calcCrossCorr(const float *mixingPos, const float *compare, double &norm) const;
-        double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const;
+        double calcCrossCorr(const float *mixingPos, const float *compare, double &norm);
+        double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm);
     };
 
 #endif /// SOUNDTOUCH_ALLOW_SSE
 
 }
 #endif  /// TDStretch_H
--- a/media/libsoundtouch/src/cpu_detect.h
+++ b/media/libsoundtouch/src/cpu_detect.h
@@ -7,23 +7,16 @@
 /// platforms, respectively.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2008-02-10 16:26:55 +0000 (Sun, 10 Feb 2008) $
-// File revision : $Revision: 4 $
-//
-// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
--- a/media/libsoundtouch/src/cpu_detect_x86.cpp
+++ b/media/libsoundtouch/src/cpu_detect_x86.cpp
@@ -6,23 +6,16 @@
 /// for the Microsoft compiler version.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-07 18:24:28 +0000 (Tue, 07 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: cpu_detect_x86.cpp 183 2014-01-07 18:24:28Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -69,17 +62,16 @@ static uint _dwDisabledISA = 0x00;      
 
 // Disables given set of instruction extensions. See SUPPORT_... defines.
 void disableExtensions(uint dwDisableMask)
 {
     _dwDisabledISA = dwDisableMask;
 }
 
 
-
 /// Checks which instruction set extensions are supported by the CPU.
 uint detectCPUextensions(void)
 {
 /// If building for a 64bit system (no Itanium) and the user wants optimizations.
 /// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19.
 /// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
 #if ((defined(__GNUC__) && defined(__x86_64__)) \
     || defined(_M_X64))  \
--- a/media/libsoundtouch/src/mmx_optimized.cpp
+++ b/media/libsoundtouch/src/mmx_optimized.cpp
@@ -15,23 +15,16 @@
 /// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-22 15:10:38 +0000 (Sun, 22 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: mmx_optimized.cpp 206 2015-02-22 15:10:38Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -63,28 +56,28 @@ using namespace soundtouch;
 
 #include "TDStretch.h"
 #include <mmintrin.h>
 #include <limits.h>
 #include <math.h>
 
 
 // Calculates cross correlation of two buffers
-double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &dnorm) const
+double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &dnorm)
 {
     const __m64 *pVec1, *pVec2;
     __m64 shifter;
     __m64 accu, normaccu;
     long corr, norm;
     int i;
    
     pVec1 = (__m64*)pV1;
     pVec2 = (__m64*)pV2;
 
-    shifter = _m_from_int(overlapDividerBits);
+    shifter = _m_from_int(overlapDividerBitsNorm);
     normaccu = accu = _mm_setzero_si64();
 
     // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples 
     // during each round for improved CPU-level parallellization.
     for (i = 0; i < channels * overlapLength / 16; i ++)
     {
         __m64 temp, temp2;
 
@@ -118,46 +111,56 @@ double TDStretchMMX::calcCrossCorr(const
     corr = _m_to_int(accu);
 
     normaccu = _mm_add_pi32(normaccu, _mm_srli_si64(normaccu, 32));
     norm = _m_to_int(normaccu);
 
     // Clear MMS state
     _m_empty();
 
+    if (norm > (long)maxnorm)
+    {
+        // modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
+        #pragma omp critical
+        if (norm > (long)maxnorm)
+        {
+            maxnorm = norm;
+        }
+    }
+
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
     dnorm = (double)norm;
 
     return (double)corr / sqrt(dnorm < 1e-9 ? 1.0 : dnorm);
     // Note: Warning about the missing EMMS instruction is harmless
     // as it'll be called elsewhere.
 }
 
 
 /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value
-double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, double &dnorm) const
+double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, double &dnorm)
 {
     const __m64 *pVec1, *pVec2;
     __m64 shifter;
     __m64 accu;
     long corr, lnorm;
     int i;
    
     // cancel first normalizer tap from previous round
     lnorm = 0;
     for (i = 1; i <= channels; i ++)
     {
-        lnorm -= (pV1[-i] * pV1[-i]) >> overlapDividerBits;
+        lnorm -= (pV1[-i] * pV1[-i]) >> overlapDividerBitsNorm;
     }
 
     pVec1 = (__m64*)pV1;
     pVec2 = (__m64*)pV2;
 
-    shifter = _m_from_int(overlapDividerBits);
+    shifter = _m_from_int(overlapDividerBitsNorm);
     accu = _mm_setzero_si64();
 
     // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples 
     // during each round for improved CPU-level parallellization.
     for (i = 0; i < channels * overlapLength / 16; i ++)
     {
         __m64 temp;
 
@@ -186,35 +189,39 @@ double TDStretchMMX::calcCrossCorrAccumu
 
     // Clear MMS state
     _m_empty();
 
     // update normalizer with last samples of this round
     pV1 = (short *)pVec1;
     for (int j = 1; j <= channels; j ++)
     {
-        lnorm += (pV1[-j] * pV1[-j]) >> overlapDividerBits;
+        lnorm += (pV1[-j] * pV1[-j]) >> overlapDividerBitsNorm;
     }
     dnorm += (double)lnorm;
 
+    if (lnorm > (long)maxnorm)
+    {
+        maxnorm = lnorm;
+    }
+
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
     return (double)corr / sqrt((dnorm < 1e-9) ? 1.0 : dnorm);
 }
 
 
 void TDStretchMMX::clearCrossCorrState()
 {
     // Clear MMS state
     _m_empty();
     //_asm EMMS;
 }
 
 
-
 // MMX-optimized version of the function overlapStereo
 void TDStretchMMX::overlapStereo(short *output, const short *input) const
 {
     const __m64 *pVinput, *pVMidBuf;
     __m64 *pVdest;
     __m64 mix1, mix2, adder, shifter;
     int i;
 
@@ -228,17 +235,17 @@ void TDStretchMMX::overlapStereo(short *
     
     mix1  = _mm_set_pi16(0, overlapLength,   0, overlapLength);
     adder = _mm_set_pi16(1, -1, 1, -1);
     mix2  = _mm_add_pi16(mix1, adder);
     adder = _mm_add_pi16(adder, adder);
 
     // Overlaplength-division by shifter. "+1" is to account for "-1" deduced in
     // overlapDividerBits calculation earlier.
-    shifter = _m_from_int(overlapDividerBits + 1);
+    shifter = _m_from_int(overlapDividerBitsPure + 1);
 
     for (i = 0; i < overlapLength / 4; i ++)
     {
         __m64 temp1, temp2;
                 
         // load & shuffle data so that input & mixbuffer data samples are paired
         temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]);     // = i0l m0l i0r m0r
         temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]);     // = i1l m1l i1r m1r
@@ -320,17 +327,16 @@ void FIRFilterMMX::setCoefficients(const
         filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];
         filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];
         filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];
         filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];
     }
 }
 
 
-
 // mmx-optimized version of the filter routine for stereo sound
 uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numSamples) const
 {
     // Create stack copies of the needed member variables for asm routines :
     uint i, j;
     __m64 *pVdest = (__m64*)dest;
 
     if (length < 2) return 0;
@@ -377,9 +383,14 @@ uint FIRFilterMMX::evaluateFilterStereo(
         pVdest ++;
     }
 
    _m_empty();  // clear emms state
 
     return (numSamples & 0xfffffffe) - length;
 }
 
+#else
+
+// workaround to not complain about empty module
+bool _dontcomplain_mmx_empty;
+
 #endif  // SOUNDTOUCH_ALLOW_MMX
--- a/media/libsoundtouch/src/sse_optimized.cpp
+++ b/media/libsoundtouch/src/sse_optimized.cpp
@@ -18,23 +18,16 @@
 /// perform a search with keywords "processor pack".
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: sse_optimized.cpp 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
 //  License as published by the Free Software Foundation; either
@@ -66,17 +59,17 @@ using namespace soundtouch;
 //
 //////////////////////////////////////////////////////////////////////////////
 
 #include "TDStretch.h"
 #include <xmmintrin.h>
 #include <math.h>
 
 // Calculates cross correlation of two buffers
-double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &anorm) const
+double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &anorm)
 {
     int i;
     const float *pVec1;
     const __m128 *pVec2;
     __m128 vSum, vNorm;
 
     // Note. It means a major slow-down if the routine needs to tolerate 
     // unaligned __m128 memory accesses. It's way faster if we can skip 
@@ -178,17 +171,17 @@ double TDStretchSSE::calcCrossCorr(const
         pV2 += 16;
     }
     return corr / sqrt(norm);
     */
 }
 
 
 
-double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm) const
+double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm)
 {
     // call usual calcCrossCorr function because SSE does not show big benefit of 
     // accumulating "norm" value, and also the "norm" rolling algorithm would get 
     // complicated due to SSE-specific alignment-vs-nonexact correlation rules.
     return calcCrossCorr(pV1, pV2, norm);
 }