Bug 847827 - Update libsoundtouch to allow changing playback rate with multichannel audio. r=padenot
authorMichael Pruett <michael@68k.org>
Thu, 10 Apr 2014 10:37:07 +0200
changeset 189982 a5f46ce505386d8c814ff6ab142069363734314a
parent 189981 f2b29dbe2ae9246e0a21af4bab7ba6c31b9930b7
child 189983 285a0529b82d012c43da21145727ceb0f3fe32c5
push idunknown
push userunknown
push dateunknown
reviewerspadenot
bugs847827
milestone31.0a1
Bug 847827 - Update libsoundtouch to allow changing playback rate with multichannel audio. r=padenot
content/media/AudioStream.cpp
content/media/MediaDecoderStateMachine.cpp
content/media/test/manifest.js
media/libsoundtouch/README_MOZILLA
media/libsoundtouch/moz-libsoundtouch.patch
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/moz.build
media/libsoundtouch/src/sse_optimized.cpp
media/libsoundtouch/update.sh
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -190,20 +190,16 @@ nsresult AudioStream::EnsureTimeStretche
   MonitorAutoLock mon(mMonitor);
   return EnsureTimeStretcherInitializedUnlocked();
 }
 
 nsresult AudioStream::EnsureTimeStretcherInitializedUnlocked()
 {
   mMonitor.AssertCurrentThreadOwns();
   if (!mTimeStretcher) {
-    // SoundTouch does not support a number of channels > 2
-    if (mOutChannels > 2) {
-      return NS_ERROR_FAILURE;
-    }
     mTimeStretcher = new soundtouch::SoundTouch();
     mTimeStretcher->setSampleRate(mInRate);
     mTimeStretcher->setChannels(mOutChannels);
     mTimeStretcher->setPitch(1.0);
   }
   return NS_OK;
 }
 
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -2759,22 +2759,16 @@ nsIEventTarget* MediaDecoderStateMachine
 
 void MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   NS_ASSERTION(aPlaybackRate != 0,
       "PlaybackRate == 0 should be handled before this function.");
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
-  // We don't currently support more than two channels when changing playback
-  // rate.
-  if (mAudioStream && mAudioStream->GetChannels() > 2) {
-    return;
-  }
-
   if (mPlaybackRate == aPlaybackRate) {
     return;
   }
 
   // Get position of the last time we changed the rate.
   if (!HasAudio()) {
     // mBasePosition is a position in the video stream, not an absolute time.
     if (mState == DECODER_STATE_SEEKING) {
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -39,17 +39,18 @@ var gProgressTests = [
 
 // Used by test_played.html
 var gPlayedTests = [
   { name:"big.wav", type:"audio/x-wav", duration:9.0 },
   { name:"seek.ogv", type:"video/ogg", duration:3.966 },
   { name:"seek.webm", type:"video/webm", duration:3.966 },
   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
-  { name:"vbr.mp3", type:"audio/mpeg", duration:10.0 }
+  { name:"vbr.mp3", type:"audio/mpeg", duration:10.0 },
+  { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 }
 ];
 
 // Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
 // anything for testing clone-specific bugs.
 var cloneKey = Math.floor(Math.random()*100000000);
 var gCloneTests = gSmallTests.concat([
   // Actual duration is ~200ms, we have Content-Duration lie about it.
   { name:"bug520908.ogv", type:"video/ogg", duration:9000 },
--- a/media/libsoundtouch/README_MOZILLA
+++ b/media/libsoundtouch/README_MOZILLA
@@ -1,8 +1,8 @@
 These files are from the SoundTouch library (http://www.surina.net/soundtouch/),
-and are extracted from the revision r160 of the svn repository at
+and are extracted from the revision r198 of the svn repository at
 https://soundtouch.svn.sourceforge.net/svnroot/soundtouch/trunk.
 
 The whole library is not used, only the relevant files are imported in the tree,
 using the script `update.sh`. Some changes have been made to the files, using
 the patch `moz-libsoundtouch.patch`. We also use a custom soundtouch_config.h.
 
--- a/media/libsoundtouch/moz-libsoundtouch.patch
+++ b/media/libsoundtouch/moz-libsoundtouch.patch
@@ -1,43 +1,24 @@
 diff -u /src/cpu_detect_x86.cpp /src/cpu_detect_x86.cpp
 --- /src/cpu_detect_x86.cpp
 +++ /src/cpu_detect_x86.cpp
-@@ -43,18 +43,23 @@
- #include "STTypes.h"
+@@ -44,9 +44,8 @@
+ 
  
  #if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
 -
--    #if defined(__GNUC__) && defined(__i386__)
--        // gcc
-+    #if defined(__GNUC__) && defined (HAVE_CPUID_H)
-+        // gcc and clang
-         #include "cpuid.h"
-     #elif defined(_M_IX86)
-         // windows non-gcc
-         #include <intrin.h>
--        #define bit_MMX     (1 << 23)
--        #define bit_SSE     (1 << 25)
--        #define bit_SSE2    (1 << 26)
-     #endif
--
-+    // If we still don't have the macros, define them (Windows, MacOS)
-+    #ifndef bit_MMX
-+        #define bit_MMX (1 << 23)
-+    #endif
-+    #ifndef bit_SSE
-+       #define bit_SSE (1 << 25)
-+    #endif
-+    #ifndef bit_SSE2
-+        #define bit_SSE2 (1 << 26)
-+    #endif
- #endif
- 
- 
-@@ -101,18 +106,7 @@
+-   #if defined(__GNUC__) && defined(__i386__)
+-       // gcc
++   #if defined(__GNUC__) && defined(HAVE_CPUID_H)
++       // gcc and clang
+        #include "cpuid.h"
+    #elif defined(_M_IX86)
+        // windows non-gcc
+@@ -97,18 +96,7 @@
   
      uint res = 0;
   
 -#if defined(__GNUC__)
 -    // GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support.
 -    uint eax, ebx, ecx, edx;  // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable.
 -
 -    // Check if no cpuid support.
@@ -47,17 +28,17 @@ diff -u /src/cpu_detect_x86.cpp /src/cpu
 -    if (edx & bit_SSE)  res = res | SUPPORT_SSE;
 -    if (edx & bit_SSE2) res = res | SUPPORT_SSE2;
 -
 -#else
 +#if !defined(__GNUC__)
      // Window / VS version of cpuid. Notice that Visual Studio 2005 or later required 
      // for __cpuid intrinsic support.
      int reg[4] = {-1};
-@@ -125,7 +119,19 @@
+@@ -121,7 +109,19 @@
      if ((unsigned int)reg[3] & bit_MMX)  res = res | SUPPORT_MMX;
      if ((unsigned int)reg[3] & bit_SSE)  res = res | SUPPORT_SSE;
      if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2;
 +#elif defined(HAVE_CPUID_H)
 +    // GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support.
 +    uint eax, ebx, ecx, edx;  // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable.
 +
 +    // Check if no cpuid support.
@@ -67,523 +48,112 @@ diff -u /src/cpu_detect_x86.cpp /src/cpu
 +    if (edx & bit_SSE)  res = res | SUPPORT_SSE;
 +    if (edx & bit_SSE2) res = res | SUPPORT_SSE2;
 +#else
 +    // Compatible with GCC but no cpuid.h.
 +    return 0;
  #endif
  
      return res & ~_dwDisabledISA;
---- /src/STTypes.h	2012-08-02 10:04:06.301691592 -0700
+diff -u /src/STTypes.h /src/STTypes.h
+--- /src/STTypes.h
 +++ /src/STTypes.h
-@@ -42,21 +42,17 @@
- typedef unsigned int    uint;
- typedef unsigned long   ulong;
+@@ -54,12 +54,17 @@
+ #define SOUNDTOUCH_ALIGN_POINTER_16(x)      ( ( (ulongptr)(x) + 15 ) & ~(ulongptr)15 )
+ 
  
--#ifdef __GNUC__
--    // In GCC, include soundtouch_config.h made by config scritps
+-#if (defined(__GNUC__) && !defined(ANDROID))
+-    // In GCC, include soundtouch_config.h made by config scritps.
+-    // Skip this in Android compilation that uses GCC but without configure scripts.
 -    #include "soundtouch_config.h"
 -#endif
--
--#ifndef _WINDEF_
--    // if these aren't defined already by Windows headers, define now
--
--    typedef int BOOL;
--
--    #define FALSE   0
--    #define TRUE    1
--
--#endif  // _WINDEF_
 +#include "soundtouch_config.h"
  
 +#ifdef WIN32
 +#ifdef BUILDING_SOUNDTOUCH
 +#define EXPORT __declspec(dllexport)
 +#else
 +#define EXPORT __declspec(dllimport)
 +#endif
 +#else
 +#define EXPORT
 +#endif
  
  namespace soundtouch
  {
-@@ -82,7 +78,7 @@
-         ///   also in GNU environment, then please #undef the INTEGER_SAMPLE
-         ///   and FLOAT_SAMPLE defines first as in comments above.
-         //#define SOUNDTOUCH_INTEGER_SAMPLES     1    //< 16bit integer samples
--        #define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples
-+        #define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples 
-      
-     #endif
- 
-@@ -144,10 +140,10 @@
- 
-     #endif  // SOUNDTOUCH_INTEGER_SAMPLES
- 
--};
-+}
+@@ -164,7 +169,7 @@
+ };
  
  // define ST_NO_EXCEPTION_HANDLING switch to disable throwing std exceptions:
 -// #define ST_NO_EXCEPTION_HANDLING    1
 +#define ST_NO_EXCEPTION_HANDLING    1
  #ifdef ST_NO_EXCEPTION_HANDLING
      // Exceptions disabled. Throw asserts instead if enabled.
      #include <assert.h>
---- /src/SoundTouch.h	2012-08-02 10:04:06.301691592 -0700
+diff -u /src/SoundTouch.h /src/SoundTouch.h
+--- /src/SoundTouch.h
 +++ /src/SoundTouch.h
 @@ -141,7 +141,7 @@
  ///   tempo/pitch/rate/samplerate settings.
  #define SETTING_NOMINAL_OUTPUT_SEQUENCE		7
  
 -class SoundTouch : public FIFOProcessor
 +class EXPORT SoundTouch : public FIFOProcessor
  {
  private:
      /// Rate transposer class instance
-@@ -160,7 +160,7 @@
-     float virtualPitch;
- 
-     /// Flag: Has sample rate been set?
--    BOOL  bSrateSet;
-+    bool  bSrateSet;
- 
-     /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and 
-     /// 'virtualPitch' parameters.
-@@ -247,8 +247,8 @@
-     /// 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
--    BOOL setSetting(int settingId,   ///< Setting ID number. see SETTING_... defines.
-+    /// \return 'true' if the setting was succesfully changed
-+    bool setSetting(int settingId,   ///< Setting ID number. see SETTING_... defines.
-                     int value        ///< New setting value.
-                     );
- 
---- /src/RateTransposer.cpp
-+++ /src/RateTransposer.cpp
-@@ -120,17 +120,17 @@ RateTransposer *RateTransposer::newInsta
- #endif
- }
- 
- 
- // Constructor
- RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
- {
-     numChannels = 2;
--    bUseAAFilter = TRUE;
-+    bUseAAFilter = true;
-     fRate = 0;
- 
-     // Instantiates the anti-alias filter with default tap length
-     // of 32
-     pAAFilter = new AAFilter(32);
- }
- 
- 
-@@ -138,24 +138,24 @@ RateTransposer::RateTransposer() : FIFOP
- RateTransposer::~RateTransposer()
- {
-     delete pAAFilter;
- }
- 
- 
- 
- /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
--void RateTransposer::enableAAFilter(BOOL newMode)
-+void RateTransposer::enableAAFilter(bool newMode)
- {
-     bUseAAFilter = newMode;
- }
- 
- 
- /// Returns nonzero if anti-alias filter is enabled.
--BOOL RateTransposer::isAAFilterEnabled() const
-+bool RateTransposer::isAAFilterEnabled() const
- {
-     return bUseAAFilter;
- }
- 
- 
- AAFilter *RateTransposer::getAAFilter()
- {
-     return pAAFilter;
-@@ -281,17 +281,17 @@ void RateTransposer::processSamples(cons
-     uint count;
-     uint sizeReq;
- 
-     if (nSamples == 0) return;
-     assert(pAAFilter);
- 
-     // If anti-alias filter is turned off, simply transpose without applying
-     // the filter
--    if (bUseAAFilter == FALSE) 
-+    if (bUseAAFilter == false) 
-     {
-         sizeReq = (uint)((float)nSamples / fRate + 1.0f);
-         count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
-         outputBuffer.putSamples(count);
-         return;
-     }
- 
-     // Transpose with anti-alias filter
---- /src/RateTransposer.h
-+++ /src/RateTransposer.h
-@@ -76,17 +76,17 @@ protected:
-     FIFOSampleBuffer storeBuffer;
- 
-     /// Buffer for keeping samples between transposing & anti-alias filter
-     FIFOSampleBuffer tempBuffer;
- 
-     /// Output sample buffer
-     FIFOSampleBuffer outputBuffer;
- 
--    BOOL bUseAAFilter;
-+    bool bUseAAFilter;
- 
-     virtual void resetRegisters() = 0;
- 
-     virtual uint transposeStereo(SAMPLETYPE *dest, 
-                          const SAMPLETYPE *src, 
-                          uint numSamples) = 0;
-     virtual uint transposeMono(SAMPLETYPE *dest, 
-                        const SAMPLETYPE *src, 
-@@ -126,20 +126,20 @@ public:
- 
-     /// 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);
-+    void enableAAFilter(bool newMode);
- 
-     /// Returns nonzero if anti-alias filter is enabled.
--    BOOL isAAFilterEnabled() const;
-+    bool isAAFilterEnabled() const;
- 
-     /// Sets new target rate. Normal rate = 1.0, smaller values represent slower 
-     /// rate, larger faster rates.
-     virtual void setRate(float newRate);
- 
-     /// Sets the number of channels, 1 = mono, 2 = stereo
-     void setChannels(int channels);
- 
---- /src/SoundTouch.cpp
-+++ /src/SoundTouch.cpp
-@@ -106,17 +106,17 @@ SoundTouch::SoundTouch()
- 
-     virtualPitch = 
-     virtualRate = 
-     virtualTempo = 1.0;
- 
-     calcEffectiveRateAndTempo();
- 
-     channels = 0;
--    bSrateSet = FALSE;
-+    bSrateSet = false;
- }
- 
- 
- 
- SoundTouch::~SoundTouch()
- {
-     delete pRateTransposer;
-     delete pTDStretch;
-@@ -277,27 +277,27 @@ void SoundTouch::calcEffectiveRateAndTem
-         }
-     } 
- }
- 
- 
- // Sets sample rate.
- void SoundTouch::setSampleRate(uint srate)
- {
--    bSrateSet = TRUE;
-+    bSrateSet = true;
-     // set sample rate, leave other tempo changer parameters as they are.
-     pTDStretch->setParameters((int)srate);
- }
- 
- 
- // 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) 
-+    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");
-     }
- 
-@@ -382,57 +382,57 @@ void SoundTouch::flush()
-     pTDStretch->clearInput();
-     // yet leave the 'tempoChanger' 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)
-+bool SoundTouch::setSetting(int settingId, int value)
- {
-     int sampleRate, sequenceMs, seekWindowMs, overlapMs;
- 
-     // read current tdstretch routine parameters
-     pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
- 
-     switch (settingId) 
-     {
-         case SETTING_USE_AA_FILTER :
-             // enables / disabless anti-alias filter
--            pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
--            return TRUE;
-+            pRateTransposer->enableAAFilter((value != 0) ? true : false);
-+            return true;
- 
-         case SETTING_AA_FILTER_LENGTH :
-             // sets anti-alias filter length
-             pRateTransposer->getAAFilter()->setLength(value);
--            return TRUE;
-+            return true;
- 
-         case SETTING_USE_QUICKSEEK :
-             // enables / disables tempo routine quick seeking algorithm
--            pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE);
--            return TRUE;
-+            pTDStretch->enableQuickSeek((value != 0) ? true : false);
-+            return true;
- 
-         case SETTING_SEQUENCE_MS:
-             // change time-stretch sequence duration parameter
-             pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs);
--            return TRUE;
-+            return true;
- 
-         case SETTING_SEEKWINDOW_MS:
-             // change time-stretch seek window length parameter
-             pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
--            return TRUE;
-+            return true;
- 
-         case SETTING_OVERLAP_MS:
-             // change time-stretch overlap length parameter
-             pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
--            return TRUE;
-+            return true;
- 
-         default :
--            return FALSE;
-+            return false;
-     }
- }
- 
- 
- // Reads a setting controlling the processing system behaviour. See the
- // 'SETTING_...' defines for available setting ID's.
- //
- // Returns the setting value.
---- /src/TDStretch.cpp
-+++ /src/TDStretch.cpp
-@@ -81,25 +81,25 @@ static const short _scanOffsets[5][24]={
-  *
-  * Implementation of the class 'TDStretch'
-  *
-  *****************************************************************************/
- 
- 
- TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
- {
--    bQuickSeek = FALSE;
-+    bQuickSeek = false;
-     channels = 2;
- 
-     pMidBuffer = NULL;
-     pMidBufferUnaligned = NULL;
-     overlapLength = 0;
- 
--    bAutoSeqSetting = TRUE;
--    bAutoSeekSetting = TRUE;
-+    bAutoSeqSetting = true;
-+    bAutoSeekSetting = true;
- 
- //    outDebt = 0;
-     skipFract = 0;
- 
-     tempo = 1.0f;
-     setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
-     setTempo(1.0f);
- 
-@@ -129,33 +129,33 @@ void TDStretch::setParameters(int aSampl
- {
-     // 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 (aSequenceMS > 0)
-     {
-         this->sequenceMs = aSequenceMS;
--        bAutoSeqSetting = FALSE;
-+        bAutoSeqSetting = false;
-     } 
-     else if (aSequenceMS == 0)
-     {
-         // if zero, use automatic setting
--        bAutoSeqSetting = TRUE;
-+        bAutoSeqSetting = true;
-     }
- 
-     if (aSeekWindowMS > 0) 
-     {
-         this->seekWindowMs = aSeekWindowMS;
--        bAutoSeekSetting = FALSE;
-+        bAutoSeekSetting = false;
-     } 
-     else if (aSeekWindowMS == 0) 
-     {
-         // if zero, use automatic setting
--        bAutoSeekSetting = TRUE;
-+        bAutoSeekSetting = true;
-     }
- 
-     calcSeqParameters();
- 
-     calculateOverlapLength(overlapMs);
- 
-     // set tempo to recalculate 'sampleReq'
-     setTempo(tempo);
-@@ -229,24 +229,24 @@ void TDStretch::clear()
-     outputBuffer.clear();
-     clearInput();
- }
- 
- 
- 
- // Enables/disables the quick position seeking algorithm. Zero to disable, nonzero
- // to enable
--void TDStretch::enableQuickSeek(BOOL enable)
-+void TDStretch::enableQuickSeek(bool enable)
- {
-     bQuickSeek = enable;
- }
- 
- 
- // Returns nonzero if the quick seeking algorithm is enabled.
--BOOL TDStretch::isQuickSeekEnabled() const
-+bool TDStretch::isQuickSeekEnabled() const
- {
-     return bQuickSeek;
- }
- 
- 
- // Seeks for the optimal overlap-mixing position.
- int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
- {
---- /src/TDStretch.h
-+++ /src/TDStretch.h
-@@ -120,24 +120,24 @@ protected:
-     int seekLength;
-     int seekWindowLength;
-     int overlapDividerBits;
-     int slopingDivider;
-     float nominalSkip;
-     float skipFract;
-     FIFOSampleBuffer outputBuffer;
-     FIFOSampleBuffer inputBuffer;
--    BOOL bQuickSeek;
-+    bool bQuickSeek;
- 
-     int sampleRate;
-     int sequenceMs;
-     int seekWindowMs;
-     int overlapMs;
--    BOOL bAutoSeqSetting;
--    BOOL bAutoSeekSetting;
-+    bool bAutoSeqSetting;
-+    bool bAutoSeekSetting;
- 
-     void acceptNewOverlapLength(int newOverlapLength);
- 
-     virtual void clearCrossCorrState();
-     void calculateOverlapLength(int overlapMs);
- 
-     virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
- 
-@@ -188,20 +188,20 @@ public:
-     /// Clears the input buffer
-     void clearInput();
- 
-     /// Sets the number of channels, 1 = mono, 2 = stereo
-     void setChannels(int numChannels);
- 
-     /// Enables/disables the quick position seeking algorithm. Zero to disable, 
-     /// nonzero to enable
--    void enableQuickSeek(BOOL enable);
-+    void enableQuickSeek(bool enable);
- 
-     /// Returns nonzero if the quick seeking algorithm is enabled.
--    BOOL isQuickSeekEnabled() const;
-+    bool isQuickSeekEnabled() const;
- 
-     /// Sets routine control parameters. These control are certain time constants
-     /// defining how the sound is stretched to the desired duration.
-     //
-     /// 'sampleRate' = sample rate of the sound
-     /// 'sequenceMS' = one processing sequence length in milliseconds
-     /// 'seekwindowMS' = seeking window length for scanning the best overlapping 
-     ///      position
+diff -u /src/FIRFilter.cpp /src/FIRFilter.cpp
 --- /src/FIRFilter.cpp
 +++ /src/FIRFilter.cpp
-@@ -223,19 +223,21 @@ 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();
- }
+@@ -46,6 +46,11 @@
+ #include "FIRFilter.h"
+ #include "cpu_detect.h"
  
++#ifdef _MSC_VER
++#include <malloc.h>
++#define alloca _alloca
++#endif
++
+ using namespace soundtouch;
+ 
+ /*****************************************************************************
+@@ -291,9 +296,11 @@
  
  FIRFilter * FIRFilter::newInstance()
  {
 +#if defined(SOUNDTOUCH_ALLOW_MMX) || defined(SOUNDTOUCH_ALLOW_SSE)
      uint uExtensions;
  
      uExtensions = detectCPUextensions();
 +#endif
  
      // Check if MMX/SSE instruction set extensions supported by CPU
  
- #ifdef SOUNDTOUCH_ALLOW_MMX
-     // MMX routines available only with integer sample types
-     if (uExtensions & SUPPORT_MMX)
-     {
-         return ::new FIRFilterMMX;
+diff -u /src/TDStretch.cpp /src/TDStretch.cpp
 --- /src/TDStretch.cpp
 +++ /src/TDStretch.cpp
-@@ -604,19 +604,21 @@ void * TDStretch::operator new(size_t s)
-     // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
-     ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
-     return newInstance();
- }
- 
+@@ -624,9 +624,11 @@
  
  TDStretch * TDStretch::newInstance()
  {
 +#if defined(SOUNDTOUCH_ALLOW_MMX) || defined(SOUNDTOUCH_ALLOW_SSE)
      uint uExtensions;
  
      uExtensions = detectCPUextensions();
 +#endif
  
      // Check if MMX/SSE instruction set extensions supported by CPU
  
- #ifdef SOUNDTOUCH_ALLOW_MMX
-     // MMX routines available only with integer sample types
-     if (uExtensions & SUPPORT_MMX)
-     {
-         return ::new TDStretchMMX;
-(END)
+diff -u /src/SoundTouch.cpp /src/SoundTouch.cpp
+--- /src/SoundTouch.cpp
++++ /src/SoundTouch.cpp
+@@ -80,6 +80,11 @@
+ #include "RateTransposer.h"
+ #include "cpu_detect.h"
+ 
++#ifdef _MSC_VER
++#include <malloc.h>
++#define alloca _alloca
++#endif
++
+ using namespace soundtouch;
+     
+ /// test if two floating point numbers are equal
--- a/media/libsoundtouch/src/AAFilter.cpp
+++ b/media/libsoundtouch/src/AAFilter.cpp
@@ -7,20 +7,20 @@
 /// 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$
+// Last changed  : $Date: 2014-01-05 15:40:22 -0600 (Sun, 05 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: AAFilter.cpp 177 2014-01-05 21:40:22Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -47,16 +47,40 @@
 #include "AAFilter.h"
 #include "FIRFilter.h"
 
 using namespace soundtouch;
 
 #define PI        3.141592655357989
 #define TWOPI    (2 * PI)
 
+// define this to save AA filter coefficients to a file
+// #define _DEBUG_SAVE_AAFILTER_COEFFICIENTS   1
+
+#ifdef _DEBUG_SAVE_AAFILTER_COEFFICIENTS
+    #include <stdio.h>
+
+    static void _DEBUG_SAVE_AAFIR_COEFFS(SAMPLETYPE *coeffs, int len)
+    {
+        FILE *fptr = fopen("aa_filter_coeffs.txt", "wt");
+        if (fptr == NULL) return;
+
+        for (int i = 0; i < len; i ++)
+        {
+            double temp = coeffs[i];
+            fprintf(fptr, "%lf\n", temp);
+        }
+        fclose(fptr);
+    }
+
+#else
+    #define _DEBUG_SAVE_AAFIR_COEFFS(x, y)
+#endif
+
+
 /*****************************************************************************
  *
  * Implementation of the class 'AAFilter'
  *
  *****************************************************************************/
 
 AAFilter::AAFilter(uint len)
 {
@@ -94,42 +118,41 @@ void AAFilter::setLength(uint newLength)
 
 
 
 // Calculates coefficients for a low-pass FIR filter using Hamming window
 void AAFilter::calculateCoeffs()
 {
     uint i;
     double cntTemp, temp, tempCoeff,h, w;
-    double fc2, wc;
+    double wc;
     double scaleCoeff, sum;
     double *work;
     SAMPLETYPE *coeffs;
 
     assert(length >= 2);
     assert(length % 4 == 0);
     assert(cutoffFreq >= 0);
     assert(cutoffFreq <= 0.5);
 
     work = new double[length];
     coeffs = new SAMPLETYPE[length];
 
-    fc2 = 2.0 * cutoffFreq; 
-    wc = PI * fc2;
+    wc = 2.0 * PI * cutoffFreq;
     tempCoeff = TWOPI / (double)length;
 
     sum = 0;
     for (i = 0; i < length; i ++) 
     {
         cntTemp = (double)i - (double)(length / 2);
 
         temp = cntTemp * wc;
         if (temp != 0) 
         {
-            h = fc2 * sin(temp) / temp;                     // sinc function
+            h = sin(temp) / temp;                     // sinc function
         } 
         else 
         {
             h = 1.0;
         }
         w = 0.54 + 0.46 * cos(tempCoeff * cntTemp);       // hamming window
 
         temp = w * h;
@@ -148,37 +171,66 @@ void AAFilter::calculateCoeffs()
     assert(work[length/2 - 1] > -1e-6);
 
     // 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 = work[i] * scaleCoeff;
         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);
+
     delete[] work;
     delete[] coeffs;
 }
 
 
 // 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 AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
 {
     return pFIR->evaluate(dest, src, numSamples, numChannels);
 }
 
 
+/// Applies the filter to the given src & dest pipes, so that processed amount of
+/// samples get removed from src, and produced amount added to dest 
+/// Note : The amount of outputted samples is by value of 'filter length' 
+/// smaller than the amount of input samples.
+uint AAFilter::evaluate(FIFOSampleBuffer &dest, FIFOSampleBuffer &src) const
+{
+    SAMPLETYPE *pdest;
+    const SAMPLETYPE *psrc;
+    uint numSrcSamples;
+    uint result;
+    int numChannels = src.getChannels();
+
+    assert(numChannels == dest.getChannels());
+
+    numSrcSamples = src.numSamples();
+    psrc = src.ptrBegin();
+    pdest = dest.ptrEnd(numSrcSamples);
+    result = pFIR->evaluate(pdest, psrc, numSrcSamples, numChannels);
+    src.receiveSamples(result);
+    dest.putSamples(result);
+
+    return result;
+}
+
+
 uint AAFilter::getLength() const
 {
     return pFIR->getLength();
 }
--- a/media/libsoundtouch/src/AAFilter.h
+++ b/media/libsoundtouch/src/AAFilter.h
@@ -8,20 +8,20 @@
 /// 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$
+// Last changed  : $Date: 2014-01-07 13:41:23 -0600 (Tue, 07 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: AAFilter.h 187 2014-01-07 19:41:23Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -40,16 +40,17 @@
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 #ifndef AAFilter_H
 #define AAFilter_H
 
 #include "STTypes.h"
+#include "FIFOSampleBuffer.h"
 
 namespace soundtouch
 {
 
 class AAFilter
 {
 protected:
     class FIRFilter *pFIR;
@@ -79,13 +80,21 @@ public:
 
     /// 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 evaluate(SAMPLETYPE *dest, 
                   const SAMPLETYPE *src, 
                   uint numSamples, 
                   uint numChannels) const;
+
+    /// Applies the filter to the given src & dest pipes, so that processed amount of
+    /// samples get removed from src, and produced amount added to dest 
+    /// Note : The amount of outputted samples is by value of 'filter length' 
+    /// smaller than the amount of input samples.
+    uint evaluate(FIFOSampleBuffer &dest, 
+                  FIFOSampleBuffer &src) const;
+
 };
 
 }
 
 #endif
--- a/media/libsoundtouch/src/FIFOSampleBuffer.cpp
+++ b/media/libsoundtouch/src/FIFOSampleBuffer.cpp
@@ -10,20 +10,20 @@
 /// whenever necessary.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date$
+// Last changed  : $Date: 2012-11-08 12:53:01 -0600 (Thu, 08 Nov 2012) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
--- a/media/libsoundtouch/src/FIFOSampleBuffer.h
+++ b/media/libsoundtouch/src/FIFOSampleBuffer.h
@@ -10,20 +10,20 @@
 /// whenever necessary.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date$
+// Last changed  : $Date: 2014-01-05 15:40:22 -0600 (Sun, 05 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -157,16 +157,22 @@ public:
                                 );
 
     /// Returns number of samples currently available.
     virtual uint numSamples() const;
 
     /// Sets number of channels, 1 = mono, 2 = stereo.
     void setChannels(int numChannels);
 
+    /// Get number of channels
+    int getChannels() 
+    {
+        return channels;
+    }
+
     /// Returns nonzero if there aren't any samples available for outputting.
     virtual int isEmpty() const;
 
     /// Clears all the samples.
     virtual void clear();
 
     /// allow trimming (downwards) amount of samples in pipeline.
     /// Returns adjusted amount of samples
--- a/media/libsoundtouch/src/FIFOSamplePipe.h
+++ b/media/libsoundtouch/src/FIFOSamplePipe.h
@@ -12,20 +12,20 @@
 /// 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$
+// Last changed  : $Date: 2012-06-13 14:29:53 -0500 (Wed, 13 Jun 2012) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
--- a/media/libsoundtouch/src/FIRFilter.cpp
+++ b/media/libsoundtouch/src/FIRFilter.cpp
@@ -6,20 +6,20 @@
 /// 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$
+// Last changed  : $Date: 2013-06-12 10:24:44 -0500 (Wed, 12 Jun 2013) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: FIRFilter.cpp 171 2013-06-12 15:24:44Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -41,16 +41,21 @@
 
 #include <memory.h>
 #include <assert.h>
 #include <math.h>
 #include <stdlib.h>
 #include "FIRFilter.h"
 #include "cpu_detect.h"
 
+#ifdef _MSC_VER
+#include <malloc.h>
+#define alloca _alloca
+#endif
+
 using namespace soundtouch;
 
 /*****************************************************************************
  *
  * Implementation of the class 'FIRFilter'
  *
  *****************************************************************************/
 
@@ -162,16 +167,70 @@ uint FIRFilter::evaluateFilterMono(SAMPL
 #endif // SOUNDTOUCH_INTEGER_SAMPLES
         dest[j] = (SAMPLETYPE)sum;
         src ++;
     }
     return end;
 }
 
 
+uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
+{
+    uint i, j, end, c;
+    LONG_SAMPLETYPE *sum=(LONG_SAMPLETYPE*)alloca(numChannels*sizeof(*sum));
+#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;
+#endif
+
+    assert(length != 0);
+    assert(src != NULL);
+    assert(dest != NULL);
+    assert(filterCoeffs != NULL);
+
+    end = numChannels * (numSamples - length);
+
+    for (c = 0; c < numChannels; c ++)
+    {
+        sum[c] = 0;
+    }
+
+    for (j = 0; j < end; j += numChannels)
+    {
+        const SAMPLETYPE *ptr;
+
+        ptr = src + j;
+
+        for (i = 0; i < length; i ++)
+        {
+            SAMPLETYPE coef=filterCoeffs[i];
+            for (c = 0; c < numChannels; c ++)
+            {
+                sum[c] += ptr[0] * coef;
+                ptr ++;
+            }
+        }
+        
+        for (c = 0; c < numChannels; c ++)
+        {
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
+            sum[c] >>= resultDivFactor;
+#else
+            sum[c] *= dScaler;
+#endif // SOUNDTOUCH_INTEGER_SAMPLES
+            *dest = (SAMPLETYPE)sum[c];
+            dest++;
+            sum[c] = 0;
+        }
+    }
+    return numSamples - length;
+}
+
+
 // Set filter coeffiecients and length.
 //
 // Throws an exception if filter length isn't divisible by 8
 void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
 {
     assert(newLength > 0);
     if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
 
@@ -196,26 +255,35 @@ uint FIRFilter::getLength() const
 
 
 // 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) const
 {
-    assert(numChannels == 1 || numChannels == 2);
-
     assert(length > 0);
     assert(lengthDiv8 * 8 == length);
+
     if (numSamples < length) return 0;
-    if (numChannels == 2) 
+
+#ifndef USE_MULTICH_ALWAYS
+    if (numChannels == 1)
+    {
+        return evaluateFilterMono(dest, src, numSamples);
+    } 
+    else if (numChannels == 2)
     {
         return evaluateFilterStereo(dest, src, numSamples);
-    } else {
-        return evaluateFilterMono(dest, src, numSamples);
+    }
+    else
+#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)
--- a/media/libsoundtouch/src/FIRFilter.h
+++ b/media/libsoundtouch/src/FIRFilter.h
@@ -6,20 +6,20 @@
 /// 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$
+// Last changed  : $Date: 2013-06-12 10:24:44 -0500 (Wed, 12 Jun 2013) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: FIRFilter.h 171 2013-06-12 15:24:44Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -66,16 +66,17 @@ protected:
     SAMPLETYPE *filterCoeffs;
 
     virtual uint evaluateFilterStereo(SAMPLETYPE *dest, 
                                       const SAMPLETYPE *src, 
                                       uint numSamples) const;
     virtual uint evaluateFilterMono(SAMPLETYPE *dest, 
                                     const SAMPLETYPE *src, 
                                     uint numSamples) const;
+    virtual uint evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const;
 
 public:
     FIRFilter();
     virtual ~FIRFilter();
 
     /// Operator 'new' is overloaded so that it automatically creates a suitable instance 
     /// depending on if we've a MMX-capable CPU available or not.
     static void * operator new(size_t s);
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateCubic.cpp
@@ -0,0 +1,200 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <stddef.h>
+#include <math.h>
+#include "InterpolateCubic.h"
+#include "STTypes.h"
+
+using namespace soundtouch;
+
+// cubic interpolation coefficients
+static const float _coeffs[]= 
+{ -0.5f,  1.0f, -0.5f, 0.0f,
+   1.5f, -2.5f,  0.0f, 1.0f,
+  -1.5f,  2.0f,  0.5f, 0.0f,
+   0.5f, -0.5f,  0.0f, 0.0f};
+
+
+InterpolateCubic::InterpolateCubic()
+{
+    fract = 0;
+}
+
+
+void InterpolateCubic::resetRegisters()
+{
+    fract = 0;
+}
+
+
+/// Transpose mono audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateCubic::transposeMono(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 4;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        float out;
+        const float x3 = 1.0f;
+        const float x2 = (float)fract;    // x
+        const float x1 = x2*x2;           // x^2
+        const float x0 = x1*x2;           // x^3
+        float y0, y1, y2, y3;
+
+        assert(fract < 1.0);
+
+        y0 =  _coeffs[0] * x0 +  _coeffs[1] * x1 +  _coeffs[2] * x2 +  _coeffs[3] * x3;
+        y1 =  _coeffs[4] * x0 +  _coeffs[5] * x1 +  _coeffs[6] * x2 +  _coeffs[7] * x3;
+        y2 =  _coeffs[8] * x0 +  _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
+        y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
+
+        out = y0 * psrc[0] + y1 * psrc[1] + y2 * psrc[2] + y3 * psrc[3];
+
+        pdest[i] = (SAMPLETYPE)out;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        psrc += whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+/// Transpose stereo audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateCubic::transposeStereo(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 4;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        const float x3 = 1.0f;
+        const float x2 = (float)fract;    // x
+        const float x1 = x2*x2;           // x^2
+        const float x0 = x1*x2;           // x^3
+        float y0, y1, y2, y3;
+        float out0, out1;
+
+        assert(fract < 1.0);
+
+        y0 =  _coeffs[0] * x0 +  _coeffs[1] * x1 +  _coeffs[2] * x2 +  _coeffs[3] * x3;
+        y1 =  _coeffs[4] * x0 +  _coeffs[5] * x1 +  _coeffs[6] * x2 +  _coeffs[7] * x3;
+        y2 =  _coeffs[8] * x0 +  _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
+        y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
+
+        out0 = y0 * psrc[0] + y1 * psrc[2] + y2 * psrc[4] + y3 * psrc[6];
+        out1 = y0 * psrc[1] + y1 * psrc[3] + y2 * psrc[5] + y3 * psrc[7];
+
+        pdest[2*i]   = (SAMPLETYPE)out0;
+        pdest[2*i+1] = (SAMPLETYPE)out1;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        psrc += 2*whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+/// Transpose multi-channel audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateCubic::transposeMulti(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 4;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        const float x3 = 1.0f;
+        const float x2 = (float)fract;    // x
+        const float x1 = x2*x2;           // x^2
+        const float x0 = x1*x2;           // x^3
+        float y0, y1, y2, y3;
+
+        assert(fract < 1.0);
+
+        y0 =  _coeffs[0] * x0 +  _coeffs[1] * x1 +  _coeffs[2] * x2 +  _coeffs[3] * x3;
+        y1 =  _coeffs[4] * x0 +  _coeffs[5] * x1 +  _coeffs[6] * x2 +  _coeffs[7] * x3;
+        y2 =  _coeffs[8] * x0 +  _coeffs[9] * x1 + _coeffs[10] * x2 + _coeffs[11] * x3;
+        y3 = _coeffs[12] * x0 + _coeffs[13] * x1 + _coeffs[14] * x2 + _coeffs[15] * x3;
+
+        for (int c = 0; c < numChannels; c ++)
+        {
+            float out;
+            out = y0 * psrc[c] + y1 * psrc[c + numChannels] + y2 * psrc[c + 2 * numChannels] + y3 * psrc[c + 3 * numChannels];
+            pdest[0] = (SAMPLETYPE)out;
+            pdest ++;
+        }
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        psrc += numChannels*whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateCubic.h
@@ -0,0 +1,67 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _InterpolateCubic_H_
+#define _InterpolateCubic_H_
+
+#include "RateTransposer.h"
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+class InterpolateCubic : public TransposerBase
+{
+protected:
+    virtual void resetRegisters();
+    virtual int transposeMono(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+    virtual int transposeStereo(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+    virtual int transposeMulti(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+
+    float fract;
+
+public:
+    InterpolateCubic();
+};
+
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateLinear.cpp
@@ -0,0 +1,299 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <assert.h>
+#include <stdlib.h>
+#include "InterpolateLinear.h"
+
+using namespace soundtouch;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// InterpolateLinearInteger - integer arithmetic implementation
+// 
+
+/// fixed-point interpolation routine precision
+#define SCALE    65536
+
+
+// Constructor
+InterpolateLinearInteger::InterpolateLinearInteger() : 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);
+}
+
+
+void InterpolateLinearInteger::resetRegisters()
+{
+    iFract = 0;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation. 
+// 'Mono' version of the routine. Returns the number of samples returned in 
+// the "dest" buffer
+int InterpolateLinearInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        LONG_SAMPLETYPE temp;
+    
+        assert(iFract < SCALE);
+
+        temp = (SCALE - iFract) * src[0] + iFract * src[1];
+        dest[i] = (SAMPLETYPE)(temp / SCALE);
+        i++;
+
+        iFract += iRate;
+
+        int iWhole = iFract / SCALE;
+        iFract -= iWhole * SCALE;
+        srcCount += iWhole;
+        src += iWhole;
+    }
+    srcSamples = srcCount;
+
+    return i;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation. 
+// 'Stereo' version of the routine. Returns the number of samples returned in 
+// the "dest" buffer
+int InterpolateLinearInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        LONG_SAMPLETYPE temp0;
+        LONG_SAMPLETYPE temp1;
+    
+        assert(iFract < SCALE);
+
+        temp0 = (SCALE - iFract) * src[0] + iFract * src[2];
+        temp1 = (SCALE - iFract) * src[1] + iFract * src[3];
+        dest[0] = (SAMPLETYPE)(temp0 / SCALE);
+        dest[1] = (SAMPLETYPE)(temp1 / SCALE);
+        dest += 2;
+        i++;
+
+        iFract += iRate;
+
+        int iWhole = iFract / SCALE;
+        iFract -= iWhole * SCALE;
+        srcCount += iWhole;
+        src += 2*iWhole;
+    }
+    srcSamples = srcCount;
+
+    return i;
+}
+
+
+int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        LONG_SAMPLETYPE temp, vol1;
+    
+        assert(iFract < SCALE);
+        vol1 = (SCALE - iFract);
+        for (int c = 0; c < numChannels; c ++)
+        {
+            temp = vol1 * src[c] + iFract * src[c + numChannels];
+            dest[0] = (SAMPLETYPE)(temp / SCALE);
+            dest ++;
+        }
+        i++;
+
+        iFract += iRate;
+
+        int iWhole = iFract / SCALE;
+        iFract -= iWhole * SCALE;
+        srcCount += iWhole;
+        src += iWhole * numChannels;
+    }
+    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)
+{
+    iRate = (int)(newRate * SCALE + 0.5f);
+    TransposerBase::setRate(newRate);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// InterpolateLinearFloat - floating point arithmetic implementation
+// 
+//////////////////////////////////////////////////////////////////////////////
+
+
+// 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);
+}
+
+
+void InterpolateLinearFloat::resetRegisters()
+{
+    fract = 0;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation. 
+// 'Mono' version of the routine. Returns the number of samples returned in 
+// the "dest" buffer
+int InterpolateLinearFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        double out;
+        assert(fract < 1.0);
+
+        out = (1.0 - fract) * src[0] + fract * src[1];
+        dest[i] = (SAMPLETYPE)out;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        src += whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+// Transposes the sample rate of the given samples using linear interpolation. 
+// 'Mono' version of the routine. Returns the number of samples returned in 
+// the "dest" buffer
+int InterpolateLinearFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        double out0, out1;
+        assert(fract < 1.0);
+
+        out0 = (1.0 - fract) * src[0] + fract * src[2];
+        out1 = (1.0 - fract) * src[1] + fract * src[3];
+        dest[2*i]   = (SAMPLETYPE)out0;
+        dest[2*i+1] = (SAMPLETYPE)out1;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        src += 2*whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 1;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        float temp, vol1;
+    
+        vol1 = (1.0f- fract);
+        for (int c = 0; c < numChannels; c ++)
+        {
+            temp = vol1 * src[c] + fract * src[c + numChannels];
+            *dest = (SAMPLETYPE)temp;
+            dest ++;
+        }
+        i++;
+
+        fract += rate;
+
+        int iWhole = (int)fract;
+        fract -= iWhole;
+        srcCount += iWhole;
+        src += iWhole * numChannels;
+    }
+    srcSamples = srcCount;
+
+    return i;
+}
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateLinear.h
@@ -0,0 +1,92 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _InterpolateLinear_H_
+#define _InterpolateLinear_H_
+
+#include "RateTransposer.h"
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+/// Linear transposer class that uses integer arithmetics
+class InterpolateLinearInteger : public TransposerBase
+{
+protected:
+    int iFract;
+    int iRate;
+
+    virtual void resetRegisters();
+
+    virtual int transposeMono(SAMPLETYPE *dest, 
+                       const SAMPLETYPE *src, 
+                       int &srcSamples);
+    virtual int transposeStereo(SAMPLETYPE *dest, 
+                         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);
+};
+
+
+/// Linear transposer class that uses floating point arithmetics
+class InterpolateLinearFloat : public TransposerBase
+{
+protected:
+    float fract;
+
+    virtual void resetRegisters();
+
+    virtual int transposeMono(SAMPLETYPE *dest, 
+                       const SAMPLETYPE *src, 
+                       int &srcSamples);
+    virtual int transposeStereo(SAMPLETYPE *dest, 
+                         const SAMPLETYPE *src, 
+                         int &srcSamples);
+    virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, int &srcSamples);
+
+public:
+    InterpolateLinearFloat();
+};
+
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateShannon.cpp
@@ -0,0 +1,185 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Sample interpolation routine using 8-tap band-limited Shannon interpolation 
+/// with kaiser window.
+///
+/// Notice. This algorithm is remarkably much heavier than linear or cubic
+/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <math.h>
+#include "InterpolateShannon.h"
+#include "STTypes.h"
+
+using namespace soundtouch;
+
+
+/// Kaiser window with beta = 2.0
+/// Values scaled down by 5% to avoid overflows
+static const double _kaiser8[8] = 
+{
+   0.41778693317814,
+   0.64888025049173,
+   0.83508562409944,
+   0.93887857733412,
+   0.93887857733412,
+   0.83508562409944,
+   0.64888025049173,
+   0.41778693317814
+};
+
+
+InterpolateShannon::InterpolateShannon()
+{
+    fract = 0;
+}
+
+
+void InterpolateShannon::resetRegisters()
+{
+    fract = 0;
+}
+
+
+#define PI 3.1415926536
+#define sinc(x) (sin(PI * (x)) / (PI * (x)))
+
+/// Transpose mono audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateShannon::transposeMono(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 8;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        double out;
+        assert(fract < 1.0);
+
+        out  = psrc[0] * sinc(-3.0 - fract) * _kaiser8[0];
+        out += psrc[1] * sinc(-2.0 - fract) * _kaiser8[1];
+        out += psrc[2] * sinc(-1.0 - fract) * _kaiser8[2];
+        if (fract < 1e-6)
+        {
+            out += psrc[3] * _kaiser8[3];     // sinc(0) = 1
+        }
+        else
+        {
+            out += psrc[3] * sinc(- fract) * _kaiser8[3];
+        }
+        out += psrc[4] * sinc( 1.0 - fract) * _kaiser8[4];
+        out += psrc[5] * sinc( 2.0 - fract) * _kaiser8[5];
+        out += psrc[6] * sinc( 3.0 - fract) * _kaiser8[6];
+        out += psrc[7] * sinc( 4.0 - fract) * _kaiser8[7];
+
+        pdest[i] = (SAMPLETYPE)out;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        psrc += whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+/// Transpose stereo audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateShannon::transposeStereo(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    int i;
+    int srcSampleEnd = srcSamples - 8;
+    int srcCount = 0;
+
+    i = 0;
+    while (srcCount < srcSampleEnd)
+    {
+        double out0, out1, w;
+        assert(fract < 1.0);
+
+        w = sinc(-3.0 - fract) * _kaiser8[0];
+        out0 = psrc[0] * w; out1 = psrc[1] * w;
+        w = sinc(-2.0 - fract) * _kaiser8[1];
+        out0 += psrc[2] * w; out1 += psrc[3] * w;
+        w = sinc(-1.0 - fract) * _kaiser8[2];
+        out0 += psrc[4] * w; out1 += psrc[5] * w;
+        w = _kaiser8[3] * ((fract < 1e-5) ? 1.0 : sinc(- fract));   // sinc(0) = 1
+        out0 += psrc[6] * w; out1 += psrc[7] * w;
+        w = sinc( 1.0 - fract) * _kaiser8[4];
+        out0 += psrc[8] * w; out1 += psrc[9] * w;
+        w = sinc( 2.0 - fract) * _kaiser8[5];
+        out0 += psrc[10] * w; out1 += psrc[11] * w;
+        w = sinc( 3.0 - fract) * _kaiser8[6];
+        out0 += psrc[12] * w; out1 += psrc[13] * w;
+        w = sinc( 4.0 - fract) * _kaiser8[7];
+        out0 += psrc[14] * w; out1 += psrc[15] * w;
+
+        pdest[2*i]   = (SAMPLETYPE)out0;
+        pdest[2*i+1] = (SAMPLETYPE)out1;
+        i ++;
+
+        // update position fraction
+        fract += rate;
+        // update whole positions
+        int whole = (int)fract;
+        fract -= whole;
+        psrc += 2*whole;
+        srcCount += whole;
+    }
+    srcSamples = srcCount;
+    return i;
+}
+
+
+/// Transpose stereo audio. Returns number of produced output samples, and 
+/// updates "srcSamples" to amount of consumed source samples
+int InterpolateShannon::transposeMulti(SAMPLETYPE *pdest, 
+                    const SAMPLETYPE *psrc, 
+                    int &srcSamples)
+{
+    // not implemented
+    assert(false);
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/media/libsoundtouch/src/InterpolateShannon.h
@@ -0,0 +1,72 @@
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Sample interpolation routine using 8-tap band-limited Shannon interpolation 
+/// with kaiser window.
+///
+/// Notice. This algorithm is remarkably much heavier than linear or cubic
+/// interpolation, and not remarkably better than cubic algorithm. Thus mostly
+/// 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
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _InterpolateShannon_H_
+#define _InterpolateShannon_H_
+
+#include "RateTransposer.h"
+#include "STTypes.h"
+
+namespace soundtouch
+{
+
+class InterpolateShannon : public TransposerBase
+{
+protected:
+    void resetRegisters();
+    int transposeMono(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+    int transposeStereo(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+    int transposeMulti(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples);
+
+    float fract;
+
+public:
+    InterpolateShannon();
+};
+
+}
+
+#endif
--- a/media/libsoundtouch/src/RateTransposer.cpp
+++ b/media/libsoundtouch/src/RateTransposer.cpp
@@ -5,20 +5,20 @@
 /// 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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: RateTransposer.cpp 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -38,111 +38,43 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 #include <memory.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include "RateTransposer.h"
+#include "InterpolateLinear.h"
+#include "InterpolateCubic.h"
+#include "InterpolateShannon.h"
 #include "AAFilter.h"
 
 using namespace soundtouch;
 
-
-/// A linear samplerate transposer class that uses integer arithmetics.
-/// for the transposing.
-class RateTransposerInteger : public RateTransposer
-{
-protected:
-    int iSlopeCount;
-    int iRate;
-    SAMPLETYPE sPrevSampleL, sPrevSampleR;
-
-    virtual void resetRegisters();
-
-    virtual uint transposeStereo(SAMPLETYPE *dest, 
-                         const SAMPLETYPE *src, 
-                         uint numSamples);
-    virtual uint transposeMono(SAMPLETYPE *dest, 
-                       const SAMPLETYPE *src, 
-                       uint numSamples);
-
-public:
-    RateTransposerInteger();
-    virtual ~RateTransposerInteger();
-
-    /// Sets new target rate. Normal rate = 1.0, smaller values represent slower 
-    /// rate, larger faster rates.
-    virtual void setRate(float newRate);
-
-};
-
-
-/// A linear samplerate transposer class that uses floating point arithmetics
-/// for the transposing.
-class RateTransposerFloat : public RateTransposer
-{
-protected:
-    float fSlopeCount;
-    SAMPLETYPE sPrevSampleL, sPrevSampleR;
-
-    virtual void resetRegisters();
-
-    virtual uint transposeStereo(SAMPLETYPE *dest, 
-                         const SAMPLETYPE *src, 
-                         uint numSamples);
-    virtual uint transposeMono(SAMPLETYPE *dest, 
-                       const SAMPLETYPE *src, 
-                       uint numSamples);
-
-public:
-    RateTransposerFloat();
-    virtual ~RateTransposerFloat();
-};
-
-
-
-
-// Operator 'new' is overloaded so that it automatically creates a suitable instance 
-// depending on if we've a MMX/SSE/etc-capable CPU available or not.
-void * RateTransposer::operator new(size_t s)
-{
-    ST_THROW_RT_ERROR("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
-    return newInstance();
-}
-
-
-RateTransposer *RateTransposer::newInstance()
-{
-#ifdef SOUNDTOUCH_INTEGER_SAMPLES
-    return ::new RateTransposerInteger;
-#else
-    return ::new RateTransposerFloat;
-#endif
-}
+// Define default interpolation algorithm here
+TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
 
 
 // Constructor
 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
 {
-    numChannels = 2;
     bUseAAFilter = true;
-    fRate = 0;
 
-    // Instantiates the anti-alias filter with default tap length
-    // of 32
-    pAAFilter = new AAFilter(32);
+    // 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)
 {
     bUseAAFilter = newMode;
@@ -164,463 +96,207 @@ AAFilter *RateTransposer::getAAFilter()
 
 
 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
 // iRate, larger faster iRates.
 void RateTransposer::setRate(float newRate)
 {
     double fCutoff;
 
-    fRate = newRate;
+    pTransposer->setRate(newRate);
 
     // design a new anti-alias filter
     if (newRate > 1.0f) 
     {
         fCutoff = 0.5f / newRate;
     } 
     else 
     {
         fCutoff = 0.5f * newRate;
     }
     pAAFilter->setCutoffFreq(fCutoff);
 }
 
 
-// Outputs as many samples of the 'outputBuffer' as possible, and if there's
-// any room left, outputs also as many of the incoming samples as possible.
-// The goal is to drive the outputBuffer empty.
-//
-// It's allowed for 'output' and 'input' parameters to point to the same
-// memory position.
-/*
-void RateTransposer::flushStoreBuffer()
-{
-    if (storeBuffer.isEmpty()) return;
-
-    outputBuffer.moveSamples(storeBuffer);
-}
-*/
-
-
 // Adds 'nSamples' pcs of samples from the 'samples' memory position into
 // the input of the object.
 void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
 {
     processSamples(samples, nSamples);
 }
 
 
-
-// Transposes up the sample rate, causing the observed playback 'rate' of the
-// sound to decrease
-void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
-{
-    uint count, sizeTemp, num;
-
-    // If the parameter 'uRate' value is smaller than 'SCALE', first transpose
-    // the samples and then apply the anti-alias filter to remove aliasing.
-
-    // First check that there's enough room in 'storeBuffer' 
-    // (+16 is to reserve some slack in the destination buffer)
-    sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
-
-    // Transpose the samples, store the result into the end of "storeBuffer"
-    count = transpose(storeBuffer.ptrEnd(sizeTemp), src, nSamples);
-    storeBuffer.putSamples(count);
-
-    // Apply the anti-alias filter to samples in "store output", output the
-    // result to "dest"
-    num = storeBuffer.numSamples();
-    count = pAAFilter->evaluate(outputBuffer.ptrEnd(num), 
-        storeBuffer.ptrBegin(), num, (uint)numChannels);
-    outputBuffer.putSamples(count);
-
-    // Remove the processed samples from "storeBuffer"
-    storeBuffer.receiveSamples(count);
-}
-
-
-// Transposes down the sample rate, causing the observed playback 'rate' of the
-// sound to increase
-void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
-{
-    uint count, sizeTemp;
-
-    // If the parameter 'uRate' value is larger than 'SCALE', first apply the
-    // anti-alias filter to remove high frequencies (prevent them from folding
-    // over the lover frequencies), then transpose.
-
-    // Add the new samples to the end of the storeBuffer
-    storeBuffer.putSamples(src, nSamples);
-
-    // Anti-alias filter the samples to prevent folding and output the filtered 
-    // data to tempBuffer. Note : because of the FIR filter length, the
-    // filtering routine takes in 'filter_length' more samples than it outputs.
-    assert(tempBuffer.isEmpty());
-    sizeTemp = storeBuffer.numSamples();
-
-    count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp), 
-        storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
-
-	if (count == 0) return;
-
-    // Remove the filtered samples from 'storeBuffer'
-    storeBuffer.receiveSamples(count);
-
-    // Transpose the samples (+16 is to reserve some slack in the destination buffer)
-    sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
-    count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
-    outputBuffer.putSamples(count);
-}
-
-
 // Transposes sample rate by applying anti-alias filter to prevent folding. 
 // Returns amount of samples returned in the "dest" buffer.
 // The maximum amount of samples that can be returned at a time is set by
 // the 'set_returnBuffer_size' function.
 void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
 {
     uint count;
-    uint sizeReq;
 
     if (nSamples == 0) return;
-    assert(pAAFilter);
+
+    // Store samples to input buffer
+    inputBuffer.putSamples(src, nSamples);
 
     // If anti-alias filter is turned off, simply transpose without applying
     // the filter
     if (bUseAAFilter == false) 
     {
-        sizeReq = (uint)((float)nSamples / fRate + 1.0f);
-        count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
-        outputBuffer.putSamples(count);
+        count = pTransposer->transpose(outputBuffer, inputBuffer);
         return;
     }
 
+    assert(pAAFilter);
+
     // Transpose with anti-alias filter
-    if (fRate < 1.0f) 
+    if (pTransposer->rate < 1.0f) 
     {
-        upsample(src, nSamples);
+        // If the parameter 'Rate' value is smaller than 1, first transpose
+        // the samples and then apply the anti-alias filter to remove aliasing.
+
+        // Transpose the samples, store the result to end of "midBuffer"
+        pTransposer->transpose(midBuffer, inputBuffer);
+
+        // Apply the anti-alias filter for transposed samples in midBuffer
+        pAAFilter->evaluate(outputBuffer, midBuffer);
     } 
     else  
     {
-        downsample(src, nSamples);
-    }
-}
-
+        // If the parameter 'Rate' value is larger than 1, first apply the
+        // anti-alias filter to remove high frequencies (prevent them from folding
+        // over the lover frequencies), then transpose.
 
-// Transposes the sample rate of the given samples using linear interpolation. 
-// Returns the number of samples returned in the "dest" buffer
-inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
-{
-    if (numChannels == 2) 
-    {
-        return transposeStereo(dest, src, nSamples);
-    } 
-    else 
-    {
-        return transposeMono(dest, src, nSamples);
+        // Apply the anti-alias filter for samples in inputBuffer
+        pAAFilter->evaluate(midBuffer, inputBuffer);
+
+        // Transpose the AA-filtered samples in "midBuffer"
+        pTransposer->transpose(outputBuffer, midBuffer);
     }
 }
 
 
 // Sets the number of channels, 1 = mono, 2 = stereo
 void RateTransposer::setChannels(int nChannels)
 {
     assert(nChannels > 0);
-    if (numChannels == nChannels) return;
 
-    assert(nChannels == 1 || nChannels == 2);
-    numChannels = nChannels;
+    if (pTransposer->numChannels == nChannels) return;
+    pTransposer->setChannels(nChannels);
 
-    storeBuffer.setChannels(numChannels);
-    tempBuffer.setChannels(numChannels);
-    outputBuffer.setChannels(numChannels);
-
-    // Inits the linear interpolation registers
-    resetRegisters();
+    inputBuffer.setChannels(nChannels);
+    midBuffer.setChannels(nChannels);
+    outputBuffer.setChannels(nChannels);
 }
 
 
 // Clears all the samples in the object
 void RateTransposer::clear()
 {
     outputBuffer.clear();
-    storeBuffer.clear();
+    midBuffer.clear();
+    inputBuffer.clear();
 }
 
 
 // Returns nonzero if there aren't any samples available for outputting.
 int RateTransposer::isEmpty() const
 {
     int res;
 
     res = FIFOProcessor::isEmpty();
     if (res == 0) return 0;
-    return storeBuffer.isEmpty();
+    return inputBuffer.isEmpty();
 }
 
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// RateTransposerInteger - integer arithmetic implementation
+// TransposerBase - Base class for interpolation
 // 
 
-/// fixed-point interpolation routine precision
-#define SCALE    65536
-
-// Constructor
-RateTransposerInteger::RateTransposerInteger() : RateTransposer()
-{
-    // Notice: use local function calling syntax for sake of clarity, 
-    // to indicate the fact that C++ constructor can't call virtual functions.
-    RateTransposerInteger::resetRegisters();
-    RateTransposerInteger::setRate(1.0f);
-}
-
-
-RateTransposerInteger::~RateTransposerInteger()
-{
-}
-
-
-void RateTransposerInteger::resetRegisters()
-{
-    iSlopeCount = 0;
-    sPrevSampleL = 
-    sPrevSampleR = 0;
-}
-
-
-
-// Transposes the sample rate of the given samples using linear interpolation. 
-// 'Mono' version of the routine. Returns the number of samples returned in 
-// the "dest" buffer
-uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+// static function to set interpolation algorithm
+void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a)
 {
-    unsigned int i, used;
-    LONG_SAMPLETYPE temp, vol1;
-
-    if (nSamples == 0) return 0;  // no samples, no work
-
-	used = 0;    
-    i = 0;
-
-    // Process the last sample saved from the previous call first...
-    while (iSlopeCount <= SCALE) 
-    {
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
-        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
-        dest[i] = (SAMPLETYPE)(temp / SCALE);
-        i++;
-        iSlopeCount += iRate;
-    }
-    // now always (iSlopeCount > SCALE)
-    iSlopeCount -= SCALE;
-
-    while (1)
-    {
-        while (iSlopeCount > SCALE) 
-        {
-            iSlopeCount -= SCALE;
-            used ++;
-            if (used >= nSamples - 1) goto end;
-        }
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
-        temp = src[used] * vol1 + iSlopeCount * src[used + 1];
-        dest[i] = (SAMPLETYPE)(temp / SCALE);
-
-        i++;
-        iSlopeCount += iRate;
-    }
-end:
-    // Store the last sample for the next round
-    sPrevSampleL = src[nSamples - 1];
-
-    return i;
+    TransposerBase::algorithm = a;
 }
 
 
 // Transposes the sample rate of the given samples using linear interpolation. 
-// 'Stereo' version of the routine. Returns the number of samples returned in 
-// the "dest" buffer
-uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+// Returns the number of samples returned in the "dest" buffer
+int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src)
 {
-    unsigned int srcPos, i, used;
-    LONG_SAMPLETYPE temp, vol1;
-
-    if (nSamples == 0) return 0;  // no samples, no work
+    int numSrcSamples = src.numSamples();
+    int sizeDemand = (int)((float)numSrcSamples / rate) + 8;
+    int numOutput;
+    SAMPLETYPE *psrc = src.ptrBegin();
+    SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand);
 
-    used = 0;    
-    i = 0;
-
-    // Process the last sample saved from the sPrevSampleLious call first...
-    while (iSlopeCount <= SCALE) 
+#ifndef USE_MULTICH_ALWAYS
+    if (numChannels == 1)
     {
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
-        temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
-        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
-        temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
-        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
-        i++;
-        iSlopeCount += iRate;
+        numOutput = transposeMono(pdest, psrc, numSrcSamples);
     }
-    // now always (iSlopeCount > SCALE)
-    iSlopeCount -= SCALE;
-
-    while (1)
+    else if (numChannels == 2) 
+    {
+        numOutput = transposeStereo(pdest, psrc, numSrcSamples);
+    } 
+    else 
+#endif // USE_MULTICH_ALWAYS
     {
-        while (iSlopeCount > SCALE) 
-        {
-            iSlopeCount -= SCALE;
-            used ++;
-            if (used >= nSamples - 1) goto end;
-        }
-        srcPos = 2 * used;
-        vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
-        temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
-        dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
-        temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
-        dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
-
-        i++;
-        iSlopeCount += iRate;
+        assert(numChannels > 0);
+        numOutput = transposeMulti(pdest, psrc, numSrcSamples);
     }
-end:
-    // Store the last sample for the next round
-    sPrevSampleL = src[2 * nSamples - 2];
-    sPrevSampleR = src[2 * nSamples - 1];
-
-    return i;
+    dest.putSamples(numOutput);
+    src.receiveSamples(numSrcSamples);
+    return numOutput;
 }
 
 
-// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
-// iRate, larger faster iRates.
-void RateTransposerInteger::setRate(float newRate)
+TransposerBase::TransposerBase()
 {
-    iRate = (int)(newRate * SCALE + 0.5f);
-    RateTransposer::setRate(newRate);
+    numChannels = 0;
+    rate = 1.0f;
 }
 
 
-//////////////////////////////////////////////////////////////////////////////
-//
-// RateTransposerFloat - floating point arithmetic implementation
-// 
-//////////////////////////////////////////////////////////////////////////////
-
-// Constructor
-RateTransposerFloat::RateTransposerFloat() : RateTransposer()
-{
-    // Notice: use local function calling syntax for sake of clarity, 
-    // to indicate the fact that C++ constructor can't call virtual functions.
-    RateTransposerFloat::resetRegisters();
-    RateTransposerFloat::setRate(1.0f);
-}
-
-
-RateTransposerFloat::~RateTransposerFloat()
+TransposerBase::~TransposerBase()
 {
 }
 
 
-void RateTransposerFloat::resetRegisters()
+void TransposerBase::setChannels(int channels)
 {
-    fSlopeCount = 0;
-    sPrevSampleL = 
-    sPrevSampleR = 0;
+    numChannels = channels;
+    resetRegisters();
 }
 
 
-
-// Transposes the sample rate of the given samples using linear interpolation. 
-// 'Mono' version of the routine. Returns the number of samples returned in 
-// the "dest" buffer
-uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+void TransposerBase::setRate(float newRate)
 {
-    unsigned int i, used;
-
-    used = 0;    
-    i = 0;
-
-    // Process the last sample saved from the previous call first...
-    while (fSlopeCount <= 1.0f) 
-    {
-        dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
-        i++;
-        fSlopeCount += fRate;
-    }
-    fSlopeCount -= 1.0f;
-
-    if (nSamples > 1)
-    {
-        while (1)
-        {
-            while (fSlopeCount > 1.0f) 
-            {
-                fSlopeCount -= 1.0f;
-                used ++;
-                if (used >= nSamples - 1) goto end;
-            }
-            dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
-            i++;
-            fSlopeCount += fRate;
-        }
-    }
-end:
-    // Store the last sample for the next round
-    sPrevSampleL = src[nSamples - 1];
-
-    return i;
+    rate = newRate;
 }
 
 
-// Transposes the sample rate of the given samples using linear interpolation. 
-// 'Mono' version of the routine. Returns the number of samples returned in 
-// the "dest" buffer
-uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+// static factory function
+TransposerBase *TransposerBase::newInstance()
 {
-    unsigned int srcPos, i, used;
-
-    if (nSamples == 0) return 0;  // no samples, no work
-
-    used = 0;    
-    i = 0;
-
-    // Process the last sample saved from the sPrevSampleLious call first...
-    while (fSlopeCount <= 1.0f) 
-    {
-        dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
-        dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
-        i++;
-        fSlopeCount += fRate;
-    }
-    // now always (iSlopeCount > 1.0f)
-    fSlopeCount -= 1.0f;
-
-    if (nSamples > 1)
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
+    // Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
+    return ::new InterpolateLinearInteger;
+#else
+    switch (algorithm)
     {
-        while (1)
-        {
-            while (fSlopeCount > 1.0f) 
-            {
-                fSlopeCount -= 1.0f;
-                used ++;
-                if (used >= nSamples - 1) goto end;
-            }
-            srcPos = 2 * used;
+        case LINEAR:
+            return new InterpolateLinearFloat;
+
+        case CUBIC:
+            return new InterpolateCubic;
 
-            dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] 
-                + fSlopeCount * src[srcPos + 2]);
-            dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] 
-                + fSlopeCount * src[srcPos + 3]);
+        case SHANNON:
+            return new InterpolateShannon;
 
-            i++;
-            fSlopeCount += fRate;
-        }
+        default:
+            assert(false);
+            return NULL;
     }
-end:
-    // Store the last sample for the next round
-    sPrevSampleL = src[2 * nSamples - 2];
-    sPrevSampleR = src[2 * nSamples - 1];
-
-    return i;
+#endif
 }
--- a/media/libsoundtouch/src/RateTransposer.h
+++ b/media/libsoundtouch/src/RateTransposer.h
@@ -9,20 +9,20 @@
 /// algorithm implementation.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: RateTransposer.h 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -50,87 +50,107 @@
 #include "FIFOSamplePipe.h"
 #include "FIFOSampleBuffer.h"
 
 #include "STTypes.h"
 
 namespace soundtouch
 {
 
+/// Abstract base class for transposer implementations (linear, advanced vs integer, float etc)
+class TransposerBase
+{
+public:
+        enum ALGORITHM {
+        LINEAR = 0,
+        CUBIC,
+        SHANNON
+    };
+
+protected:
+    virtual void resetRegisters() = 0;
+
+    virtual int transposeMono(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples)  = 0;
+    virtual int transposeStereo(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples) = 0;
+    virtual int transposeMulti(SAMPLETYPE *dest, 
+                        const SAMPLETYPE *src, 
+                        int &srcSamples) = 0;
+
+    static ALGORITHM algorithm;
+
+public:
+    float rate;
+    int numChannels;
+
+    TransposerBase();
+    virtual ~TransposerBase();
+
+    virtual int transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src);
+    virtual void setRate(float newRate);
+    virtual void setChannels(int channels);
+
+    // static factory function
+    static TransposerBase *newInstance();
+
+    // static function to set interpolation algorithm
+    static void setAlgorithm(ALGORITHM a);
+};
+
+
 /// A common linear samplerate transposer class.
 ///
-/// Note: Use function "RateTransposer::newInstance()" to create a new class 
-/// instance instead of the "new" operator; that function automatically 
-/// chooses a correct implementation depending on if integer or floating 
-/// arithmetics are to be used.
 class RateTransposer : public FIFOProcessor
 {
 protected:
     /// Anti-alias filter object
     AAFilter *pAAFilter;
-
-    float fRate;
-
-    int numChannels;
+    TransposerBase *pTransposer;
 
     /// Buffer for collecting samples to feed the anti-alias filter between
     /// two batches
-    FIFOSampleBuffer storeBuffer;
+    FIFOSampleBuffer inputBuffer;
 
     /// Buffer for keeping samples between transposing & anti-alias filter
-    FIFOSampleBuffer tempBuffer;
+    FIFOSampleBuffer midBuffer;
 
     /// Output sample buffer
     FIFOSampleBuffer outputBuffer;
 
     bool bUseAAFilter;
 
-    virtual void resetRegisters() = 0;
-
-    virtual uint transposeStereo(SAMPLETYPE *dest, 
-                         const SAMPLETYPE *src, 
-                         uint numSamples) = 0;
-    virtual uint transposeMono(SAMPLETYPE *dest, 
-                       const SAMPLETYPE *src, 
-                       uint numSamples) = 0;
-    inline uint transpose(SAMPLETYPE *dest, 
-                   const SAMPLETYPE *src, 
-                   uint numSamples);
-
-    void downsample(const SAMPLETYPE *src, 
-                    uint numSamples);
-    void upsample(const SAMPLETYPE *src, 
-                 uint numSamples);
 
     /// Transposes sample rate by applying anti-alias filter to prevent folding. 
     /// Returns amount of samples returned in the "dest" buffer.
     /// The maximum amount of samples that can be returned at a time is set by
     /// 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);
+//    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();
+//    static RateTransposer *newInstance();
 
     /// Returns the output buffer object
     FIFOSamplePipe *getOutput() { return &outputBuffer; };
 
     /// Returns the store buffer object
-    FIFOSamplePipe *getStore() { return &storeBuffer; };
+//    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.
--- a/media/libsoundtouch/src/STTypes.h
+++ b/media/libsoundtouch/src/STTypes.h
@@ -3,20 +3,20 @@
 /// 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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 3 $
 //
-// $Id$
+// $Id: STTypes.h 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -68,16 +68,30 @@ typedef unsigned long   ulong;
 
 namespace soundtouch
 {
     /// 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 
+    /// the dedicated mono/stereo processing routines will result in slower 
+    /// runtime performance so recommendation is to keep this off.
+    // #define USE_MULTICH_ALWAYS
+
+    #if (defined(__SOFTFP__))
+        // For Android compilation: Force use of Integer samples in case that
+        // compilation uses soft-floating point emulation - soft-fp is way too slow
+        #undef  SOUNDTOUCH_FLOAT_SAMPLES
+        #define SOUNDTOUCH_INTEGER_SAMPLES      1
+    #endif
+
     #if !(SOUNDTOUCH_INTEGER_SAMPLES || SOUNDTOUCH_FLOAT_SAMPLES)
        
         /// Choose either 32bit floating point or 16bit integer sampletype
         /// by choosing one of the following defines, unless this selection 
         /// has already been done in some other file.
         ////
         /// Notes:
         /// - In Windows environment, choose the sample format with the
@@ -85,17 +99,17 @@ namespace soundtouch
         /// - In GNU environment, the floating point samples are used by 
         ///   default, but integer samples can be chosen by giving the 
         ///   following switch to the configure script:
         ///       ./configure --enable-integer-samples
         ///   However, if you still prefer to select the sample format here 
         ///   also in GNU environment, then please #undef the INTEGER_SAMPLE
         ///   and FLOAT_SAMPLE defines first as in comments above.
         //#define SOUNDTOUCH_INTEGER_SAMPLES     1    //< 16bit integer samples
-        #define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples 
+        #define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples
      
     #endif
 
     #if (_M_IX86 || __i386__ || __x86_64__ || _M_X64)
         /// Define this to allow X86-specific assembler/intrinsic optimizations. 
         /// Notice that library contains also usual C++ versions of each of these
         /// these routines, so if you're having difficulties getting the optimized 
         /// routines compiled for whatever reason, you may disable these optimizations 
@@ -147,17 +161,17 @@ namespace soundtouch
 
         #ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
             // Allow SSE optimizations
             #define SOUNDTOUCH_ALLOW_SSE       1
         #endif
 
     #endif  // SOUNDTOUCH_INTEGER_SAMPLES
 
-}
+};
 
 // define ST_NO_EXCEPTION_HANDLING switch to disable throwing std exceptions:
 #define ST_NO_EXCEPTION_HANDLING    1
 #ifdef ST_NO_EXCEPTION_HANDLING
     // Exceptions disabled. Throw asserts instead if enabled.
     #include <assert.h>
     #define ST_THROW_RT_ERROR(x)    {assert((const char *)x);}
 #else
--- a/media/libsoundtouch/src/SoundTouch.cpp
+++ b/media/libsoundtouch/src/SoundTouch.cpp
@@ -36,20 +36,20 @@
 ///   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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: SoundTouch.cpp 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -75,16 +75,21 @@
 #include <math.h>
 #include <stdio.h>
 
 #include "SoundTouch.h"
 #include "TDStretch.h"
 #include "RateTransposer.h"
 #include "cpu_detect.h"
 
+#ifdef _MSC_VER
+#include <malloc.h>
+#define alloca _alloca
+#endif
+
 using namespace soundtouch;
     
 /// test if two floating point numbers are equal
 #define TEST_FLOAT_EQUAL(a, b)  (fabs(a - b) < 1e-10)
 
 
 /// Print library version string for autoconf
 extern "C" void soundtouch_ac_test()
@@ -92,17 +97,17 @@ extern "C" void soundtouch_ac_test()
     printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
 } 
 
 
 SoundTouch::SoundTouch()
 {
     // Initialize rate transposer and tempo changer instances
 
-    pRateTransposer = RateTransposer::newInstance();
+    pRateTransposer = new RateTransposer();
     pTDStretch = TDStretch::newInstance();
 
     setOutPipe(pTDStretch);
 
     rate = tempo = 0;
 
     virtualPitch = 
     virtualRate = 
@@ -138,20 +143,21 @@ 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) 
+    /*if (numChannels != 1 && numChannels != 2) 
     {
-        ST_THROW_RT_ERROR("Illegal number of channels");
-    }
+        //ST_THROW_RT_ERROR("Illegal number of channels");
+		return;
+    }*/
     channels = numChannels;
     pRateTransposer->setChannels((int)numChannels);
     pTDStretch->setChannels((int)numChannels);
 }
 
 
 
 // Sets new rate control value. Normal rate = 1.0, smaller values
@@ -249,17 +255,17 @@ void SoundTouch::calcEffectiveRateAndTem
         {
             FIFOSamplePipe *tempoOut;
 
             assert(output == pRateTransposer);
             // move samples in the current output buffer to the output of pTDStretch
             tempoOut = pTDStretch->getOutput();
             tempoOut->moveSamples(*output);
             // move samples in pitch transposer's store buffer to tempo changer's input
-            pTDStretch->moveSamples(*pRateTransposer->getStore());
+            // deprecated : pTDStretch->moveSamples(*pRateTransposer->getStore());
 
             output = pTDStretch;
         }
     }
     else
 #endif
     {
         if (output != pRateTransposer) 
@@ -342,17 +348,17 @@ void SoundTouch::putSamples(const SAMPLE
 // 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[64*2];   // note: allocate 2*64 to cater 64 sample frames of stereo sound
+    SAMPLETYPE *buff=(SAMPLETYPE*)alloca(64*channels*sizeof(SAMPLETYPE));
 
     // 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);
 
     nOut = numSamples();        // ready samples currently in buffer ...
     nOut += nUnprocessed;       // ... and how many we expect there to be in the end
--- a/media/libsoundtouch/src/SoundTouch.h
+++ b/media/libsoundtouch/src/SoundTouch.h
@@ -36,20 +36,20 @@
 ///   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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: SoundTouch.h 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -74,20 +74,20 @@
 
 #include "FIFOSamplePipe.h"
 #include "STTypes.h"
 
 namespace soundtouch
 {
 
 /// Soundtouch library version string
-#define SOUNDTOUCH_VERSION          "1.7.0"
+#define SOUNDTOUCH_VERSION          "1.8.0"
 
 /// SoundTouch library version id
-#define SOUNDTOUCH_VERSION_ID       (10700)
+#define SOUNDTOUCH_VERSION_ID       (10800)
 
 //
 // 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)
--- a/media/libsoundtouch/src/TDStretch.cpp
+++ b/media/libsoundtouch/src/TDStretch.cpp
@@ -8,20 +8,20 @@
 /// file, 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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 1.12 $
 //
-// $Id$
+// $Id: TDStretch.cpp 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -46,18 +46,16 @@
 #include <assert.h>
 #include <math.h>
 #include <float.h>
 
 #include "STTypes.h"
 #include "cpu_detect.h"
 #include "TDStretch.h"
 
-#include <stdio.h>
-
 using namespace soundtouch;
 
 #define max(x, y) (((x) > (y)) ? (x) : (y))
 
 
 /*****************************************************************************
  *
  * Constant definitions
@@ -154,17 +152,16 @@ void TDStretch::setParameters(int aSampl
     }
 
     calcSeqParameters();
 
     calculateOverlapLength(overlapMs);
 
     // set tempo to recalculate 'sampleReq'
     setTempo(tempo);
-
 }
 
 
 
 /// Get routine control parameters, see setParameters() function.
 /// Any of the parameters to this function can be NULL, in such case corresponding parameter
 /// value isn't returned.
 void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
@@ -207,17 +204,17 @@ void TDStretch::overlapMono(SAMPLETYPE *
         m2 -= 1;
     }
 }
 
 
 
 void TDStretch::clearMidBuffer()
 {
-    memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
+    memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
 }
 
 
 void TDStretch::clearInput()
 {
     inputBuffer.clear();
     clearMidBuffer();
 }
@@ -260,50 +257,64 @@ int TDStretch::seekBestOverlapPosition(c
     }
 }
 
 
 // Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
 // of 'ovlPos'.
 inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
 {
-    if (channels == 2) 
+#ifndef USE_MULTICH_ALWAYS
+    if (channels == 1)
+    {
+        // mono sound.
+        overlapMono(pOutput, pInput + ovlPos);
+    }
+    else if (channels == 2)
     {
         // stereo sound
         overlapStereo(pOutput, pInput + 2 * ovlPos);
-    } else {
-        // mono sound.
-        overlapMono(pOutput, pInput + ovlPos);
+    } 
+    else 
+#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, corr;
+    double norm;
     int i;
 
     bestCorr = FLT_MIN;
     bestOffs = 0;
 
     // Scans for the best correlation value by testing each possible position
     // over the permitted range.
-    for (i = 0; i < seekLength; i ++) 
+    bestCorr = calcCrossCorr(refPos, pMidBuffer, norm);
+    for (i = 1; i < seekLength; i ++) 
     {
         // Calculates correlation value for the mixing position corresponding
-        // to 'i'
-        corr = calcCrossCorr(refPos + channels * i, pMidBuffer);
+        // to 'i'. Now call "calcCrossCorrAccumulate" that is otherwise same as
+        // "calcCrossCorr", but saves time by reusing & updating previously stored 
+        // "norm" value
+        corr = calcCrossCorrAccumulate(refPos + channels * i, pMidBuffer, norm);
+
         // heuristic rule to slightly favour values close to mid of the range
         double tmp = (double)(2 * i - seekLength) / (double)seekLength;
         corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
 
         // Checks for the highest correlation value
         if (corr > bestCorr) 
         {
             bestCorr = corr;
@@ -341,22 +352,23 @@ int TDStretch::seekBestOverlapPositionQu
     // 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 ++) 
     {
         j = 0;
         while (_scanOffsets[scanCount][j]) 
         {
+            double norm;
             tempOffset = corrOffset + _scanOffsets[scanCount][j];
             if (tempOffset >= seekLength) break;
 
             // Calculates correlation value for the mixing position corresponding
             // to 'tempOffset'
-            corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer);
+            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));
 
             // Checks for the highest correlation value
             if (corr > bestCorr) 
             {
                 bestCorr = corr;
@@ -453,21 +465,25 @@ void TDStretch::setTempo(float newTempo)
 
 
 
 // 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);
+//    assert(numChannels == 1 || numChannels == 2);
 
     channels = numChannels;
     inputBuffer.setChannels(channels);
     outputBuffer.setChannels(channels);
+
+    // re-init overlap/buffer
+    overlapLength=0;
+    setParameters(sampleRate);
 }
 
 
 // nominal tempo, no need for processing, just pass the samples through
 // to outputBuffer
 /*
 void TDStretch::processNominalTempo()
 {
@@ -493,17 +509,16 @@ void TDStretch::processNominalTempo()
         // bypass mode
     }
 
     // Simply bypass samples from input to output
     outputBuffer.moveSamples(inputBuffer);
 }
 */
 
-#include <stdio.h>
 
 // Processes as many processing frames of the samples 'inputBuffer', store
 // the result into 'outputBuffer'
 void TDStretch::processSamples()
 {
     int ovlSkip, offset;
     int temp;
 
@@ -583,17 +598,17 @@ void TDStretch::acceptNewOverlapLength(i
     assert(newOverlapLength >= 0);
     prevOvl = overlapLength;
     overlapLength = newOverlapLength;
 
     if (overlapLength > prevOvl)
     {
         delete[] pMidBufferUnaligned;
 
-        pMidBufferUnaligned = new SAMPLETYPE[overlapLength * 2 + 16 / sizeof(SAMPLETYPE)];
+        pMidBufferUnaligned = new SAMPLETYPE[overlapLength * channels + 16 / sizeof(SAMPLETYPE)];
         // ensure that 'pMidBuffer' is aligned to 16 byte boundary for efficiency
         pMidBuffer = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(pMidBufferUnaligned);
 
         clearMidBuffer();
     }
 }
 
 
@@ -663,16 +678,37 @@ void TDStretch::overlapStereo(short *pou
     {
         temp = (short)(overlapLength - i);
         cnt2 = 2 * i;
         poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp )  / overlapLength;
         poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
     }
 }
 
+
+// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Multi'
+// version of the routine.
+void TDStretch::overlapMulti(SAMPLETYPE *poutput, const SAMPLETYPE *input) const
+{
+    SAMPLETYPE m1=(SAMPLETYPE)0;
+    SAMPLETYPE m2;
+    int i=0;
+
+    for (m2 = (SAMPLETYPE)overlapLength; m2; m2 --)
+    {
+        for (int c = 0; c < channels; c ++)
+        {
+            poutput[i] = (input[i] * m1 + pMidBuffer[i] * m2)  / overlapLength;
+            i++;
+        }
+
+        m1++;
+    }
+}
+
 // Calculates the x having the closest 2^x value for the given value
 static int _getClosest2Power(double value)
 {
     return (int)(log(value) / log(2.0) + 0.5);
 }
 
 
 /// Calculates overlap period length in samples.
@@ -696,42 +732,82 @@ void TDStretch::calculateOverlapLength(i
 
     // 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) const
+double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const
 {
     long corr;
-    long norm;
+    long lnorm;
     int i;
 
-    corr = norm = 0;
+    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] +
-                 mixingPos[i + 2] * compare[i + 2] + 
+                 mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;  // notice: do intermediate division here to avoid integer overflow
+        corr += (mixingPos[i + 2] * compare[i + 2] + 
                  mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
-        norm += (mixingPos[i] * mixingPos[i] + 
-                 mixingPos[i + 1] * mixingPos[i + 1] +
-                 mixingPos[i + 2] * mixingPos[i + 2] + 
-                 mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
+        lnorm += (mixingPos[i] * mixingPos[i] + 
+                  mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits; // notice: do intermediate division here to avoid integer overflow
+        lnorm += (mixingPos[i + 2] * mixingPos[i + 2] + 
+                  mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
     }
 
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
-    if (norm == 0) norm = 1;    // to avoid div by zero
-    return (double)corr / sqrt((double)norm);
+    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
+{
+    long corr;
+    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;
+    }
+
+    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
+        corr += (mixingPos[i + 2] * compare[i + 2] + 
+                 mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
+    }
+
+    // update normalizer with last samples of this round
+    for (int j = 0; j < channels; j ++)
+    {
+        i --;
+        lnorm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits;
+    }
+    norm += (double)lnorm;
+
+    // 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.
 //
@@ -757,36 +833,64 @@ void TDStretch::overlapStereo(float *pOu
         pOutput[i + 1] = pInput[i + 1] * f1 + pMidBuffer[i + 1] * f2;
 
         f1 += fScale;
         f2 -= fScale;
     }
 }
 
 
+// Overlaps samples in 'midBuffer' with the samples in 'input'. 
+void TDStretch::overlapMulti(float *pOutput, const float *pInput) const
+{
+    int i;
+    float fScale;
+    float f1;
+    float f2;
+
+    fScale = 1.0f / (float)overlapLength;
+
+    f1 = 0;
+    f2 = 1.0f;
+
+    i=0;
+    for (int i2 = 0; i2 < overlapLength; i2 ++)
+    {
+        // note: Could optimize this slightly by taking into account that always channels > 2
+        for (int c = 0; c < channels; c ++)
+        {
+            pOutput[i] = pInput[i] * f1 + pMidBuffer[i] * f2;
+            i++;
+        }
+        f1 += fScale;
+        f2 -= fScale;
+    }
+}
+
+
 /// Calculates overlapInMsec period length in samples.
 void TDStretch::calculateOverlapLength(int overlapInMsec)
 {
     int newOvl;
 
     assert(overlapInMsec >= 0);
     newOvl = (sampleRate * overlapInMsec) / 1000;
     if (newOvl < 16) newOvl = 16;
 
     // must be divisible by 8
     newOvl -= newOvl % 8;
 
     acceptNewOverlapLength(newOvl);
 }
 
 
-double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare) const
+/// Calculate cross-correlation
+double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &norm) const
 {
     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.
     for (i = 0; i < channels * overlapLength; i += 4) 
     {
         corr += mixingPos[i] * compare[i] +
@@ -798,13 +902,48 @@ double TDStretch::calcCrossCorr(const fl
         // unroll the loop for better CPU efficiency:
         corr += mixingPos[i + 2] * compare[i + 2] +
                 mixingPos[i + 3] * compare[i + 3];
 
         norm += mixingPos[i + 2] * mixingPos[i + 2] +
                 mixingPos[i + 3] * mixingPos[i + 3];
     }
 
-    if (norm < 1e-9) norm = 1.0;    // to avoid div by zero
-    return corr / sqrt(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 corr;
+    int i;
+
+    corr = 0;
+
+    // cancel first normalizer tap from previous round
+    for (i = 1; i <= channels; i ++)
+    {
+        norm -= mixingPos[-i] * mixingPos[-i];
+    }
+
+    // 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.
+    for (i = 0; i < channels * overlapLength; i += 4) 
+    {
+        corr += mixingPos[i] * compare[i] +
+                mixingPos[i + 1] * compare[i + 1] +
+                mixingPos[i + 2] * compare[i + 2] +
+                mixingPos[i + 3] * compare[i + 3];
+    }
+
+    // update normalizer with last samples of this round
+    for (int j = 0; j < channels; j ++)
+    {
+        i --;
+        norm += mixingPos[i] * mixingPos[i];
+    }
+
+    return corr / sqrt((norm < 1e-9 ? 1.0 : norm));
+}
+
+
 #endif // SOUNDTOUCH_FLOAT_SAMPLES
--- a/media/libsoundtouch/src/TDStretch.h
+++ b/media/libsoundtouch/src/TDStretch.h
@@ -8,20 +8,20 @@
 /// '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$
+// Last changed  : $Date: 2014-04-06 10:57:21 -0500 (Sun, 06 Apr 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: TDStretch.h 195 2014-04-06 15:57:21Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -134,24 +134,26 @@ protected:
     bool bAutoSeqSetting;
     bool bAutoSeekSetting;
 
     void acceptNewOverlapLength(int newOverlapLength);
 
     virtual void clearCrossCorrState();
     void calculateOverlapLength(int overlapMs);
 
-    virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
+    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 int seekBestOverlapPositionFull(const SAMPLETYPE *refPos);
     virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos);
     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();
 
     /// Changes the tempo of the given sound samples.
     /// Returns amount of samples returned in the "output" buffer.
@@ -242,27 +244,29 @@ public:
 
 // 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) const;
+        double calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const;
+        double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const;
         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) const;
+        double calcCrossCorr(const float *mixingPos, const float *compare, double &norm) const;
+        double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const;
     };
 
 #endif /// SOUNDTOUCH_ALLOW_SSE
 
 }
 #endif  /// TDStretch_H
--- a/media/libsoundtouch/src/cpu_detect.h
+++ b/media/libsoundtouch/src/cpu_detect.h
@@ -7,20 +7,20 @@
 /// platforms, respectively.
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date$
+// Last changed  : $Date: 2008-02-10 10:26:55 -0600 (Sun, 10 Feb 2008) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
--- a/media/libsoundtouch/src/cpu_detect_x86.cpp
+++ b/media/libsoundtouch/src/cpu_detect_x86.cpp
@@ -6,20 +6,20 @@
 /// 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$
+// Last changed  : $Date: 2014-01-07 12:24:28 -0600 (Tue, 07 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: cpu_detect_x86.cpp 183 2014-01-07 18:24:28Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -37,34 +37,29 @@
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 #include "cpu_detect.h"
 #include "STTypes.h"
 
+
 #if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
-    #if defined(__GNUC__) && defined (HAVE_CPUID_H)
-        // gcc and clang
-        #include "cpuid.h"
-    #elif defined(_M_IX86)
-        // windows non-gcc
-        #include <intrin.h>
-    #endif
-    // If we still don't have the macros, define them (Windows, MacOS)
-    #ifndef bit_MMX
-        #define bit_MMX (1 << 23)
-    #endif
-    #ifndef bit_SSE
-       #define bit_SSE (1 << 25)
-    #endif
-    #ifndef bit_SSE2
-        #define bit_SSE2 (1 << 26)
-    #endif
+   #if defined(__GNUC__) && defined(HAVE_CPUID_H)
+       // gcc and clang
+       #include "cpuid.h"
+   #elif defined(_M_IX86)
+       // windows non-gcc
+       #include <intrin.h>
+   #endif
+
+   #define bit_MMX     (1 << 23)
+   #define bit_SSE     (1 << 25)
+   #define bit_SSE2    (1 << 26)
 #endif
 
 
 //////////////////////////////////////////////////////////////////////////////
 //
 // processor instructions extension detection routines
 //
 //////////////////////////////////////////////////////////////////////////////
--- a/media/libsoundtouch/src/mmx_optimized.cpp
+++ b/media/libsoundtouch/src/mmx_optimized.cpp
@@ -15,20 +15,20 @@
 /// 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$
+// Last changed  : $Date: 2014-01-07 12:25:40 -0600 (Tue, 07 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: mmx_optimized.cpp 184 2014-01-07 18:25:40Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -63,17 +63,17 @@ 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) const
+double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &dnorm) const
 {
     const __m64 *pVec1, *pVec2;
     __m64 shifter;
     __m64 accu, normaccu;
     long corr, norm;
     int i;
    
     pVec1 = (__m64*)pV1;
@@ -88,29 +88,29 @@ double TDStretchMMX::calcCrossCorr(const
     {
         __m64 temp, temp2;
 
         // dictionary of instructions:
         // _m_pmaddwd   : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
         // _mm_add_pi32 : 2*32bit add
         // _m_psrad     : 32bit right-shift
 
-        temp = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]),
-                            _mm_madd_pi16(pVec1[1], pVec2[1]));
-        temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec1[0]),
-                             _mm_madd_pi16(pVec1[1], pVec1[1]));
-        accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
-        normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
+        temp = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[1], pVec2[1]), shifter));
+        temp2 = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[0], pVec1[0]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[1], pVec1[1]), shifter));
+        accu = _mm_add_pi32(accu, temp);
+        normaccu = _mm_add_pi32(normaccu, temp2);
 
-        temp = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]),
-                            _mm_madd_pi16(pVec1[3], pVec2[3]));
-        temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec1[2]),
-                             _mm_madd_pi16(pVec1[3], pVec1[3]));
-        accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
-        normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
+        temp = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[3], pVec2[3]), shifter));
+        temp2 = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[2], pVec1[2]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[3], pVec1[3]), shifter));
+        accu = _mm_add_pi32(accu, temp);
+        normaccu = _mm_add_pi32(normaccu, temp2);
 
         pVec1 += 4;
         pVec2 += 4;
     }
 
     // copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
     // and finally store the result into the variable "corr"
 
@@ -120,24 +120,91 @@ double TDStretchMMX::calcCrossCorr(const
     normaccu = _mm_add_pi32(normaccu, _mm_srli_si64(normaccu, 32));
     norm = _m_to_int(normaccu);
 
     // Clear MMS state
     _m_empty();
 
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
-    if (norm == 0) norm = 1;    // to avoid div by zero
+    dnorm = (double)norm;
 
-    return (double)corr / sqrt((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
+{
+    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;
+    }
+
+    pVec1 = (__m64*)pV1;
+    pVec2 = (__m64*)pV2;
+
+    shifter = _m_from_int(overlapDividerBits);
+    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;
+
+        // dictionary of instructions:
+        // _m_pmaddwd   : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
+        // _mm_add_pi32 : 2*32bit add
+        // _m_psrad     : 32bit right-shift
+
+        temp = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[1], pVec2[1]), shifter));
+        accu = _mm_add_pi32(accu, temp);
+
+        temp = _mm_add_pi32(_mm_sra_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]), shifter),
+                            _mm_sra_pi32(_mm_madd_pi16(pVec1[3], pVec2[3]), shifter));
+        accu = _mm_add_pi32(accu, temp);
+
+        pVec1 += 4;
+        pVec2 += 4;
+    }
+
+    // copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
+    // and finally store the result into the variable "corr"
+
+    accu = _mm_add_pi32(accu, _mm_srli_si64(accu, 32));
+    corr = _m_to_int(accu);
+
+    // 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;
+    }
+    dnorm += (double)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;
 }
 
--- a/media/libsoundtouch/src/moz.build
+++ b/media/libsoundtouch/src/moz.build
@@ -11,16 +11,19 @@ EXPORTS.soundtouch += [
     'STTypes.h',
 ]
 
 UNIFIED_SOURCES += [
     'AAFilter.cpp',
     'cpu_detect_x86.cpp',
     'FIFOSampleBuffer.cpp',
     'FIRFilter.cpp',
+    'InterpolateCubic.cpp',
+    'InterpolateLinear.cpp',
+    'InterpolateShannon.cpp',
     'RateTransposer.cpp',
     'SoundTouch.cpp',
     'TDStretch.cpp',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
     if CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']:
         SOURCES += ['sse_optimized.cpp']
--- a/media/libsoundtouch/src/sse_optimized.cpp
+++ b/media/libsoundtouch/src/sse_optimized.cpp
@@ -18,20 +18,20 @@
 /// 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$
+// Last changed  : $Date: 2014-01-07 12:25:40 -0600 (Tue, 07 Jan 2014) $
 // File revision : $Revision: 4 $
 //
-// $Id$
+// $Id: sse_optimized.cpp 184 2014-01-07 18:25:40Z oparviai $
 //
 ////////////////////////////////////////////////////////////////////////////////
 //
 // License :
 //
 //  SoundTouch audio processing library
 //  Copyright (c) Olli Parviainen
 //
@@ -66,17 +66,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) const
+double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &norm) const
 {
     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 
@@ -136,21 +136,20 @@ double TDStretchSSE::calcCrossCorr(const
         vNorm = _mm_add_ps(vNorm, _mm_mul_ps(vTemp ,vTemp));
 
         pVec1 += 16;
         pVec2 += 4;
     }
 
     // return value = vSum[0] + vSum[1] + vSum[2] + vSum[3]
     float *pvNorm = (float*)&vNorm;
-    double norm = sqrt(pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]);
-    if (norm < 1e-9) norm = 1.0;    // to avoid div by zero
+    norm = (pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]);
 
     float *pvSum = (float*)&vSum;
-    return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / norm;
+    return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / sqrt(norm < 1e-9 ? 1.0 : norm);
 
     /* This is approximately corresponding routine in C-language yet without normalization:
     double corr, norm;
     uint i;
 
     // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
     corr = norm = 0.0;
     for (i = 0; i < channels * overlapLength / 16; i ++) 
@@ -177,16 +176,26 @@ double TDStretchSSE::calcCrossCorr(const
         pV1 += 16;
         pV2 += 16;
     }
     return corr / sqrt(norm);
     */
 }
 
 
+
+double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm) const
+{
+    // 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);
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // implementation of SSE optimized functions of class 'FIRFilter'
 //
 //////////////////////////////////////////////////////////////////////////////
 
 #include "FIRFilter.h"
 
--- a/media/libsoundtouch/update.sh
+++ b/media/libsoundtouch/update.sh
@@ -2,24 +2,30 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Usage: ./update.sh <SoundTouch_src_directory>
 #
 # Copies the needed files from a directory containing the original
 # soundtouch sources that we need for HTML5 media playback rate change.
 
-cp $1/COPYING.TXT .
+cp $1/COPYING.TXT LICENSE
 cp $1/source/SoundTouch/AAFilter.cpp src
 cp $1/source/SoundTouch/AAFilter.h src
 cp $1/source/SoundTouch/cpu_detect.h src
 cp $1/source/SoundTouch/cpu_detect_x86.cpp src
 cp $1/source/SoundTouch/FIFOSampleBuffer.cpp src
 cp $1/source/SoundTouch/FIRFilter.cpp src
 cp $1/source/SoundTouch/FIRFilter.h src
+cp $1/source/SoundTouch/InterpolateLinear.cpp src
+cp $1/source/SoundTouch/InterpolateLinear.h src
+cp $1/source/SoundTouch/InterpolateCubic.cpp src
+cp $1/source/SoundTouch/InterpolateCubic.h src
+cp $1/source/SoundTouch/InterpolateShannon.cpp src
+cp $1/source/SoundTouch/InterpolateShannon.h src
 cp $1/source/SoundTouch/mmx_optimized.cpp src
 cp $1/source/SoundTouch/RateTransposer.cpp src
 cp $1/source/SoundTouch/RateTransposer.h src
 cp $1/source/SoundTouch/SoundTouch.cpp src
 cp $1/source/SoundTouch/sse_optimized.cpp src
 cp $1/source/SoundTouch/TDStretch.cpp src
 cp $1/source/SoundTouch/TDStretch.h src
 cp $1/include/SoundTouch.h src