Sophie

Sophie

distrib > Mageia > 8 > armv7hl > by-pkgid > 786cd653798c1358e4fd401192110eb5 > files > 2

dolphin-emu-5.0.13178-3.mga8.src.rpm

From 2e96cd862bf9a54fe12a2c8124b4c3abae5e98c3 Mon Sep 17 00:00:00 2001
From: Mystro256 <alexjnewt@hotmail.com>
Date: Sun, 5 Apr 2020 10:56:07 -0400
Subject: [PATCH 1/4] soundtounch: update to 2.1.2

Note that soundtouch_config.h is a custom file.
---
 Externals/soundtouch/AAFilter.cpp           |  16 +-
 Externals/soundtouch/AAFilter.h             |   7 -
 Externals/soundtouch/BPMDetect.cpp          | 400 +++++++++----
 Externals/soundtouch/BPMDetect.h            | 241 ++++----
 Externals/soundtouch/FIFOSampleBuffer.cpp   |  15 +-
 Externals/soundtouch/FIFOSampleBuffer.h     |   9 +-
 Externals/soundtouch/FIFOSamplePipe.h       |  28 +-
 Externals/soundtouch/FIRFilter.cpp          |  20 +-
 Externals/soundtouch/FIRFilter.h            |   7 -
 Externals/soundtouch/InterpolateCubic.cpp   | 396 +++++++------
 Externals/soundtouch/InterpolateCubic.h     | 130 +++--
 Externals/soundtouch/InterpolateLinear.cpp  | 596 ++++++++++----------
 Externals/soundtouch/InterpolateLinear.h    | 180 +++---
 Externals/soundtouch/InterpolateShannon.cpp | 366 ++++++------
 Externals/soundtouch/InterpolateShannon.h   | 140 +++--
 Externals/soundtouch/PeakFinder.cpp         |  19 +-
 Externals/soundtouch/PeakFinder.h           |  11 +-
 Externals/soundtouch/RateTransposer.cpp     |  35 +-
 Externals/soundtouch/RateTransposer.h       |  22 +-
 Externals/soundtouch/STTypes.h              |  32 +-
 Externals/soundtouch/SoundTouch.cpp         | 154 ++---
 Externals/soundtouch/SoundTouch.h           |  91 ++-
 Externals/soundtouch/SoundTouch.vcxproj     |   3 +-
 Externals/soundtouch/TDStretch.cpp          | 131 +++--
 Externals/soundtouch/TDStretch.h            |  16 +-
 Externals/soundtouch/cpu_detect.h           |   7 -
 Externals/soundtouch/cpu_detect_x86.cpp     |   8 -
 Externals/soundtouch/mmx_optimized.cpp      |  21 +-
 Externals/soundtouch/soundtouch_config.h    |   2 +
 Externals/soundtouch/sse_optimized.cpp      |   7 -
 30 files changed, 1661 insertions(+), 1449 deletions(-)
 create mode 100644 Externals/soundtouch/soundtouch_config.h

diff --git a/Externals/soundtouch/AAFilter.cpp b/Externals/soundtouch/AAFilter.cpp
index c69f356f686..76a3da65d40 100644
--- a/Externals/soundtouch/AAFilter.cpp
+++ b/Externals/soundtouch/AAFilter.cpp
@@ -12,13 +12,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-05 23:40:22 +0200 (Sun, 05 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: AAFilter.cpp 177 2014-01-05 21:40:22Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -49,7 +42,7 @@
 
 using namespace soundtouch;
 
-#define PI        3.141592655357989
+#define PI       3.14159265358979323846
 #define TWOPI    (2 * PI)
 
 // define this to save AA filter coefficients to a file
@@ -75,7 +68,6 @@ using namespace soundtouch;
     #define _DEBUG_SAVE_AAFIR_COEFFS(x, y)
 #endif
 
-
 /*****************************************************************************
  *
  * Implementation of the class 'AAFilter'
@@ -90,14 +82,12 @@ AAFilter::AAFilter(uint len)
 }
 
 
-
 AAFilter::~AAFilter()
 {
     delete pFIR;
 }
 
 
-
 // Sets new anti-alias filter cut-off edge frequency, scaled to
 // sampling frequency (nyquist frequency = 0.5).
 // The filter will cut frequencies higher than the given frequency.
@@ -108,7 +98,6 @@ void AAFilter::setCutoffFreq(double newCutoffFreq)
 }
 
 
-
 // Sets number of FIR filter taps
 void AAFilter::setLength(uint newLength)
 {
@@ -117,7 +106,6 @@ void AAFilter::setLength(uint newLength)
 }
 
 
-
 // Calculates coefficients for a low-pass FIR filter using Hamming window
 void AAFilter::calculateCoeffs()
 {
@@ -177,12 +165,10 @@ void AAFilter::calculateCoeffs()
     for (i = 0; i < length; i ++) 
     {
         temp = work[i] * scaleCoeff;
-//#if SOUNDTOUCH_INTEGER_SAMPLES
         // scale & round to nearest integer
         temp += (temp >= 0) ? 0.5 : -0.5;
         // ensure no overfloods
         assert(temp >= -32768 && temp <= 32767);
-//#endif
         coeffs[i] = (SAMPLETYPE)temp;
     }
 
diff --git a/Externals/soundtouch/AAFilter.h b/Externals/soundtouch/AAFilter.h
index 33e96948ec4..8e5697f7966 100644
--- a/Externals/soundtouch/AAFilter.h
+++ b/Externals/soundtouch/AAFilter.h
@@ -13,13 +13,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-07 21:41:23 +0200 (Tue, 07 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: AAFilter.h 187 2014-01-07 19:41:23Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
diff --git a/Externals/soundtouch/BPMDetect.cpp b/Externals/soundtouch/BPMDetect.cpp
index 39dae837610..5ad19269dd0 100644
--- a/Externals/soundtouch/BPMDetect.cpp
+++ b/Externals/soundtouch/BPMDetect.cpp
@@ -26,13 +26,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: BPMDetect.cpp 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -54,45 +47,62 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
+#define _USE_MATH_DEFINES
+
 #include <math.h>
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
+#include <cfloat>
 #include "FIFOSampleBuffer.h"
 #include "PeakFinder.h"
 #include "BPMDetect.h"
 
 using namespace soundtouch;
 
-#define INPUT_BLOCK_SAMPLES       2048
-#define DECIMATED_BLOCK_SAMPLES   256
+// algorithm input sample block size
+static const int INPUT_BLOCK_SIZE = 2048;
+
+// decimated sample block size
+static const int DECIMATED_BLOCK_SIZE = 256;
+
+/// Target sample rate after decimation
+static const int TARGET_SRATE = 1000;
+
+/// XCorr update sequence size, update in about 200msec chunks
+static const int XCORR_UPDATE_SEQUENCE = (int)(TARGET_SRATE / 5);
 
-/// decay constant for calculating RMS volume sliding average approximation 
-/// (time constant is about 10 sec)
-const float avgdecay = 0.99986f;
+/// Moving average N size
+static const int MOVING_AVERAGE_N = 15;
 
-/// Normalization coefficient for calculating RMS sliding average approximation.
-const float avgnorm = (1 - avgdecay);
+/// XCorr decay time constant, decay to half in 30 seconds
+/// If it's desired to have the system adapt quicker to beat rate 
+/// changes within a continuing music stream, then the 
+/// 'xcorr_decay_time_constant' value can be reduced, yet that
+/// can increase possibility of glitches in bpm detection.
+static const double XCORR_DECAY_TIME_CONSTANT = 30.0;
 
+/// Data overlap factor for beat detection algorithm
+static const int OVERLAP_FACTOR = 4;
+
+static const double TWOPI = (2 * M_PI);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // Enable following define to create bpm analysis file:
 
-// #define _CREATE_BPM_DEBUG_FILE
+//#define _CREATE_BPM_DEBUG_FILE
 
 #ifdef _CREATE_BPM_DEBUG_FILE
 
-    #define DEBUGFILE_NAME  "c:\\temp\\soundtouch-bpm-debug.txt"
-
-    static void _SaveDebugData(const float *data, int minpos, int maxpos, double coeff)
+    static void _SaveDebugData(const char *name, const float *data, int minpos, int maxpos, double coeff)
     {
-        FILE *fptr = fopen(DEBUGFILE_NAME, "wt");
+        FILE *fptr = fopen(name, "wt");
         int i;
 
         if (fptr)
         {
-            printf("\n\nWriting BPM debug data into file " DEBUGFILE_NAME "\n\n");
+            printf("\nWriting BPM debug data into file %s\n", name);
             for (i = minpos; i < maxpos; i ++)
             {
                 fprintf(fptr, "%d\t%.1lf\t%f\n", i, coeff / (double)i, data[i]);
@@ -100,42 +110,90 @@ const float avgnorm = (1 - avgdecay);
             fclose(fptr);
         }
     }
+
+    void _SaveDebugBeatPos(const char *name, const std::vector<BEAT> &beats)
+    {
+        printf("\nWriting beat detections data into file %s\n", name);
+
+        FILE *fptr = fopen(name, "wt");
+        if (fptr)
+        {
+            for (uint i = 0; i < beats.size(); i++)
+            {
+                BEAT b = beats[i];
+                fprintf(fptr, "%lf\t%lf\n", b.pos, b.strength);
+            }
+            fclose(fptr);
+        }
+    }
 #else
-    #define _SaveDebugData(a,b,c,d)
+    #define _SaveDebugData(name, a,b,c,d)
+    #define _SaveDebugBeatPos(name, b)
 #endif
 
+// Hamming window
+void hamming(float *w, int N)
+{
+    for (int i = 0; i < N; i++)
+    {
+        w[i] = (float)(0.54 - 0.46 * cos(TWOPI * i / (N - 1)));
+    }
+
+}
+
 ////////////////////////////////////////////////////////////////////////////////
+//
+// IIR2_filter - 2nd order IIR filter
+
+IIR2_filter::IIR2_filter(const double *lpf_coeffs)
+{
+    memcpy(coeffs, lpf_coeffs, 5 * sizeof(double));
+    memset(prev, 0, sizeof(prev));
+}
+
 
+float IIR2_filter::update(float x)
+{
+    prev[0] = x;
+    double y = x * coeffs[0];
+
+    for (int i = 4; i >= 1; i--)
+    {
+        y += coeffs[i] * prev[i];
+        prev[i] = prev[i - 1];
+    }
+
+    prev[3] = y;
+    return (float)y;
+}
+
+
+// IIR low-pass filter coefficients, calculated with matlab/octave cheby2(2,40,0.05)
+const double _LPF_coeffs[5] = { 0.00996655391939, -0.01944529148401, 0.00996655391939, 1.96867605796247, -0.96916387431724 };
 
-BPMDetect::BPMDetect(int numChannels, int aSampleRate)
+////////////////////////////////////////////////////////////////////////////////
+
+BPMDetect::BPMDetect(int numChannels, int aSampleRate) :
+    beat_lpf(_LPF_coeffs)
 {
+    beats.reserve(250); // initial reservation to prevent frequent reallocation
+
     this->sampleRate = aSampleRate;
     this->channels = numChannels;
 
     decimateSum = 0;
     decimateCount = 0;
 
-    envelopeAccu = 0;
-
-    // Initialize RMS volume accumulator to RMS level of 1500 (out of 32768) that's
-    // safe initial RMS signal level value for song data. This value is then adapted
-    // to the actual level during processing.
-#ifdef SOUNDTOUCH_INTEGER_SAMPLES
-    // integer samples
-    RMSVolumeAccu = (1500 * 1500) / avgnorm;
-#else
-    // float samples, scaled to range [-1..+1[
-    RMSVolumeAccu = (0.045f * 0.045f) / avgnorm;
-#endif
-
     // choose decimation factor so that result is approx. 1000 Hz
-    decimateBy = sampleRate / 1000;
-    assert(decimateBy > 0);
-    assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
+    decimateBy = sampleRate / TARGET_SRATE;
+    if ((decimateBy <= 0) || (decimateBy * DECIMATED_BLOCK_SIZE < INPUT_BLOCK_SIZE))
+    {
+        ST_THROW_RT_ERROR("Too small samplerate");
+    }
 
     // Calculate window length & starting item according to desired min & max bpms
     windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
-    windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
+    windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM_RANGE);
 
     assert(windowLen > windowStart);
 
@@ -143,23 +201,38 @@ BPMDetect::BPMDetect(int numChannels, int aSampleRate)
     xcorr = new float[windowLen];
     memset(xcorr, 0, windowLen * sizeof(float));
 
+    pos = 0;
+    peakPos = 0;
+    peakVal = 0;
+    init_scaler = 1;
+    beatcorr_ringbuffpos = 0;
+    beatcorr_ringbuff = new float[windowLen];
+    memset(beatcorr_ringbuff, 0, windowLen * sizeof(float));
+
     // allocate processing buffer
     buffer = new FIFOSampleBuffer();
     // we do processing in mono mode
     buffer->setChannels(1);
     buffer->clear();
-}
 
+    // calculate hamming windows
+    hamw = new float[XCORR_UPDATE_SEQUENCE];
+    hamming(hamw, XCORR_UPDATE_SEQUENCE);
+    hamw2 = new float[XCORR_UPDATE_SEQUENCE / 2];
+    hamming(hamw2, XCORR_UPDATE_SEQUENCE / 2);
+}
 
 
 BPMDetect::~BPMDetect()
 {
     delete[] xcorr;
+    delete[] beatcorr_ringbuff;
+    delete[] hamw;
+    delete[] hamw2;
     delete buffer;
 }
 
 
-
 /// convert to mono, low-pass filter & decimate to about 500 Hz. 
 /// return number of outputted samples.
 ///
@@ -216,7 +289,6 @@ int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
 }
 
 
-
 // Calculates autocorrelation function of the sample history buffer
 void BPMDetect::updateXCorr(int process_samples)
 {
@@ -224,72 +296,124 @@ void BPMDetect::updateXCorr(int process_samples)
     SAMPLETYPE *pBuffer;
     
     assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
+    assert(process_samples == XCORR_UPDATE_SEQUENCE);
 
     pBuffer = buffer->ptrBegin();
+
+    // calculate decay factor for xcorr filtering
+    float xcorr_decay = (float)pow(0.5, 1.0 / (XCORR_DECAY_TIME_CONSTANT * TARGET_SRATE / process_samples));
+
+    // prescale pbuffer
+    float tmp[XCORR_UPDATE_SEQUENCE];
+    for (int i = 0; i < process_samples; i++)
+    {
+        tmp[i] = hamw[i] * hamw[i] * pBuffer[i];
+    }
+
     #pragma omp parallel for
     for (offs = windowStart; offs < windowLen; offs ++) 
     {
-        LONG_SAMPLETYPE sum;
+        float sum;
         int i;
 
         sum = 0;
         for (i = 0; i < process_samples; i ++) 
         {
-            sum += pBuffer[i] * pBuffer[i + offs];    // scaling the sub-result shouldn't be necessary
+            sum += tmp[i] * pBuffer[i + offs];  // scaling the sub-result shouldn't be necessary
         }
-//        xcorr[offs] *= xcorr_decay;   // decay 'xcorr' here with suitable coefficients 
-                                        // if it's desired that the system adapts automatically to
-                                        // various bpms, e.g. in processing continouos music stream.
-                                        // The 'xcorr_decay' should be a value that's smaller than but 
-                                        // close to one, and should also depend on 'process_samples' value.
+        xcorr[offs] *= xcorr_decay;   // decay 'xcorr' here with suitable time constant.
 
-        xcorr[offs] += (float)sum;
+        xcorr[offs] += (float)fabs(sum);
     }
 }
 
 
-// Calculates envelope of the sample data
-void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples) 
+// Detect individual beat positions
+void BPMDetect::updateBeatPos(int process_samples)
 {
-    const static double decay = 0.7f;               // decay constant for smoothing the envelope
-    const static double norm = (1 - decay);
+    SAMPLETYPE *pBuffer;
 
-    int i;
-    LONG_SAMPLETYPE out;
-    double val;
+    assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
+
+    pBuffer = buffer->ptrBegin();
+    assert(process_samples == XCORR_UPDATE_SEQUENCE / 2);
+
+    //    static double thr = 0.0003;
+    double posScale = (double)this->decimateBy / (double)this->sampleRate;
+    int resetDur = (int)(0.12 / posScale + 0.5);
+
+    // prescale pbuffer
+    float tmp[XCORR_UPDATE_SEQUENCE / 2];
+    for (int i = 0; i < process_samples; i++)
+    {
+        tmp[i] = hamw2[i] * hamw2[i] * pBuffer[i];
+    }
 
-    for (i = 0; i < numsamples; i ++) 
+    #pragma omp parallel for
+    for (int offs = windowStart; offs < windowLen; offs++)
     {
-        // calc average RMS volume
-        RMSVolumeAccu *= avgdecay;
-        val = (float)fabs((float)samples[i]);
-        RMSVolumeAccu += val * val;
-
-        // cut amplitudes that are below cutoff ~2 times RMS volume
-        // (we're interested in peak values, not the silent moments)
-        if (val < 0.5 * sqrt(RMSVolumeAccu * avgnorm))
+        float sum = 0;
+        for (int i = 0; i < process_samples; i++)
         {
-            val = 0;
+            sum += tmp[i] * pBuffer[offs + i];
         }
+        beatcorr_ringbuff[(beatcorr_ringbuffpos + offs) % windowLen] += (float)((sum > 0) ? sum : 0); // accumulate only positive correlations
+    }
 
-        // smooth amplitude envelope
-        envelopeAccu *= decay;
-        envelopeAccu += val;
-        out = (LONG_SAMPLETYPE)(envelopeAccu * norm);
+    int skipstep = XCORR_UPDATE_SEQUENCE / OVERLAP_FACTOR;
 
-#ifdef SOUNDTOUCH_INTEGER_SAMPLES
-        // cut peaks (shouldn't be necessary though)
-        if (out > 32767) out = 32767;
-#endif // SOUNDTOUCH_INTEGER_SAMPLES
-        samples[i] = (SAMPLETYPE)out;
+    // compensate empty buffer at beginning by scaling coefficient
+    float scale = (float)windowLen / (float)(skipstep * init_scaler);
+    if (scale > 1.0f)
+    {
+        init_scaler++;
+    }
+    else
+    {
+        scale = 1.0f;
+    }
+
+    // detect beats
+    for (int i = 0; i < skipstep; i++)
+    {
+        LONG_SAMPLETYPE max = 0;
+
+        float sum = beatcorr_ringbuff[beatcorr_ringbuffpos];
+        sum -= beat_lpf.update(sum);
+
+        if (sum > peakVal)
+        {
+            // found new local largest value
+            peakVal = sum;
+            peakPos = pos;
+        }
+        if (pos > peakPos + resetDur)
+        {
+            // largest value not updated for 200msec => accept as beat
+            peakPos += skipstep;
+            if (peakVal > 0)
+            {
+                // add detected beat to end of "beats" vector
+                BEAT temp = { (float)(peakPos * posScale), (float)(peakVal * scale) };
+                beats.push_back(temp);
+            }
+
+            peakVal = 0;
+            peakPos = pos;
+        }
+
+        beatcorr_ringbuff[beatcorr_ringbuffpos] = 0;
+        pos++;
+        beatcorr_ringbuffpos = (beatcorr_ringbuffpos + 1) % windowLen;
     }
 }
 
 
+#define max(x,y) ((x) > (y) ? (x) : (y))
 
 void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
 {
-    SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
+    SAMPLETYPE decimated[DECIMATED_BLOCK_SIZE];
 
     // iterate so that max INPUT_BLOCK_SAMPLES processed per iteration
     while (numSamples > 0)
@@ -297,48 +421,70 @@ void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
         int block;
         int decSamples;
 
-        block = (numSamples > INPUT_BLOCK_SAMPLES) ? INPUT_BLOCK_SAMPLES : numSamples;
+        block = (numSamples > INPUT_BLOCK_SIZE) ? INPUT_BLOCK_SIZE : numSamples;
 
         // decimate. note that converts to mono at the same time
         decSamples = decimate(decimated, samples, block);
         samples += block * channels;
         numSamples -= block;
 
-        // envelope new samples and add them to buffer
-        calcEnvelope(decimated, decSamples);
         buffer->putSamples(decimated, decSamples);
     }
 
-    // when the buffer has enought samples for processing...
-    if ((int)buffer->numSamples() > windowLen) 
+    // when the buffer has enough samples for processing...
+    int req = max(windowLen + XCORR_UPDATE_SEQUENCE, 2 * XCORR_UPDATE_SEQUENCE);
+    while ((int)buffer->numSamples() >= req) 
     {
-        int processLength;
-
-        // how many samples are processed
-        processLength = (int)buffer->numSamples() - windowLen;
-
-        // ... calculate autocorrelations for oldest samples...
-        updateXCorr(processLength);
-        // ... and remove them from the buffer
-        buffer->receiveSamples(processLength);
+        // ... update autocorrelations...
+        updateXCorr(XCORR_UPDATE_SEQUENCE);
+        // ...update beat position calculation...
+        updateBeatPos(XCORR_UPDATE_SEQUENCE / 2);
+        // ... and remove proceessed samples from the buffer
+        int n = XCORR_UPDATE_SEQUENCE / OVERLAP_FACTOR;
+        buffer->receiveSamples(n);
     }
 }
 
 
-
 void BPMDetect::removeBias()
 {
     int i;
-    float minval = 1e12f;   // arbitrary large number
 
+    // Remove linear bias: calculate linear regression coefficient
+    // 1. calc mean of 'xcorr' and 'i'
+    double mean_i = 0;
+    double mean_x = 0;
+    for (i = windowStart; i < windowLen; i++)
+    {
+        mean_x += xcorr[i];
+    }
+    mean_x /= (windowLen - windowStart);
+    mean_i = 0.5 * (windowLen - 1 + windowStart);
+
+    // 2. calculate linear regression coefficient
+    double b = 0;
+    double div = 0;
+    for (i = windowStart; i < windowLen; i++)
+    {
+        double xt = xcorr[i] - mean_x;
+        double xi = i - mean_i;
+        b += xt * xi;
+        div += xi * xi;
+    }
+    b /= div;
+
+    // subtract linear regression and resolve min. value bias
+    float minval = FLT_MAX;   // arbitrary large number
     for (i = windowStart; i < windowLen; i ++)
     {
+        xcorr[i] -= (float)(b * i);
         if (xcorr[i] < minval)
         {
             minval = xcorr[i];
         }
     }
 
+    // subtract min.value
     for (i = windowStart; i < windowLen; i ++)
     {
         xcorr[i] -= minval;
@@ -346,26 +492,82 @@ void BPMDetect::removeBias()
 }
 
 
+// Calculate N-point moving average for "source" values
+void MAFilter(float *dest, const float *source, int start, int end, int N)
+{
+    for (int i = start; i < end; i++)
+    {
+        int i1 = i - N / 2;
+        int i2 = i + N / 2 + 1;
+        if (i1 < start) i1 = start;
+        if (i2 > end)   i2 = end;
+
+        double sum = 0;
+        for (int j = i1; j < i2; j ++)
+        { 
+            sum += source[j];
+        }
+        dest[i] = (float)(sum / (i2 - i1));
+    }
+}
+
+
 float BPMDetect::getBpm()
 {
     double peakPos;
     double coeff;
     PeakFinder peakFinder;
 
+    // remove bias from xcorr data
+    removeBias();
+
     coeff = 60.0 * ((double)sampleRate / (double)decimateBy);
 
-    // save bpm debug analysis data if debug data enabled
-    _SaveDebugData(xcorr, windowStart, windowLen, coeff);
+    // save bpm debug data if debug data writing enabled
+    _SaveDebugData("soundtouch-bpm-xcorr.txt", xcorr, windowStart, windowLen, coeff);
 
-    // remove bias from xcorr data
-    removeBias();
+    // Smoothen by N-point moving-average
+    float *data = new float[windowLen];
+    memset(data, 0, sizeof(float) * windowLen);
+    MAFilter(data, xcorr, windowStart, windowLen, MOVING_AVERAGE_N);
 
     // find peak position
-    peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen);
+    peakPos = peakFinder.detectPeak(data, windowStart, windowLen);
+
+    // save bpm debug data if debug data writing enabled
+    _SaveDebugData("soundtouch-bpm-smoothed.txt", data, windowStart, windowLen, coeff);
+
+    delete[] data;
 
     assert(decimateBy != 0);
     if (peakPos < 1e-9) return 0.0; // detection failed.
 
+    _SaveDebugBeatPos("soundtouch-detected-beats.txt", beats);
+
     // calculate BPM
-    return (float) (coeff / peakPos);
+    float bpm = (float)(coeff / peakPos);
+    return (bpm >= MIN_BPM && bpm <= MAX_BPM_VALID) ? bpm : 0;
+}
+
+
+/// Get beat position arrays. Note: The array includes also really low beat detection values 
+/// in absence of clear strong beats. Consumer may wish to filter low values away.
+/// - "pos" receive array of beat positions
+/// - "values" receive array of beat detection strengths
+/// - max_num indicates max.size of "pos" and "values" array.  
+///
+/// You can query a suitable array sized by calling this with NULL in "pos" & "values".
+///
+/// \return number of beats in the arrays.
+int BPMDetect::getBeats(float *pos, float *values, int max_num)
+{
+    int num = beats.size();
+    if ((!pos) || (!values)) return num;    // pos or values NULL, return just size
+
+    for (int i = 0; (i < num) && (i < max_num); i++)
+    {
+        pos[i] = beats[i].pos;
+        values[i] = beats[i].strength;
+    }
+    return num;
 }
diff --git a/Externals/soundtouch/BPMDetect.h b/Externals/soundtouch/BPMDetect.h
index 69d98143a7f..8ece78448db 100644
--- a/Externals/soundtouch/BPMDetect.h
+++ b/Externals/soundtouch/BPMDetect.h
@@ -26,13 +26,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2012-08-30 22:53:44 +0300 (Thu, 30 Aug 2012) $
-// File revision : $Revision: 4 $
-//
-// $Id: BPMDetect.h 150 2012-08-30 19:53:44Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -57,108 +50,156 @@
 #ifndef _BPMDetect_H_
 #define _BPMDetect_H_
 
+#include <vector>
 #include "STTypes.h"
 #include "FIFOSampleBuffer.h"
 
 namespace soundtouch
 {
 
-/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
-#define MIN_BPM 29
+    /// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
+    #define MIN_BPM 45
 
-/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
-#define MAX_BPM 200
+    /// Maximum allowed BPM rate range. Used for calculating algorithm parametrs
+    #define MAX_BPM_RANGE 200
 
+    /// Maximum allowed BPM rate range. Used to restrict accepted result below a reasonable limit.
+    #define MAX_BPM_VALID 190
 
-/// Class for calculating BPM rate for audio data.
-class BPMDetect
-{
-protected:
-    /// Auto-correlation accumulator bins.
-    float *xcorr;
-    
-    /// Amplitude envelope sliding average approximation level accumulator
-    double envelopeAccu;
-
-    /// RMS volume sliding average approximation level accumulator
-    double RMSVolumeAccu;
-
-    /// Sample average counter.
-    int decimateCount;
-
-    /// Sample average accumulator for FIFO-like decimation.
-    soundtouch::LONG_SAMPLETYPE decimateSum;
-
-    /// Decimate sound by this coefficient to reach approx. 500 Hz.
-    int decimateBy;
-
-    /// Auto-correlation window length
-    int windowLen;
-
-    /// Number of channels (1 = mono, 2 = stereo)
-    int channels;
-
-    /// sample rate
-    int sampleRate;
-
-    /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
-    /// the first these many correlation bins.
-    int windowStart;
- 
-    /// FIFO-buffer for decimated processing samples.
-    soundtouch::FIFOSampleBuffer *buffer;
-
-    /// Updates auto-correlation function for given number of decimated samples that 
-    /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe 
-    /// though).
-    void updateXCorr(int process_samples      /// How many samples are processed.
-                     );
-
-    /// Decimates samples to approx. 500 Hz.
-    ///
-    /// \return Number of output samples.
-    int decimate(soundtouch::SAMPLETYPE *dest,      ///< Destination buffer
-                 const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
-                 int numsamples                     ///< Number of source samples.
-                 );
-
-    /// Calculates amplitude envelope for the buffer of samples.
-    /// Result is output to 'samples'.
-    void calcEnvelope(soundtouch::SAMPLETYPE *samples,  ///< Pointer to input/output data buffer
-                      int numsamples                    ///< Number of samples in buffer
-                      );
-
-    /// remove constant bias from xcorr data
-    void removeBias();
-
-public:
-    /// Constructor.
-    BPMDetect(int numChannels,  ///< Number of channels in sample data.
-              int sampleRate    ///< Sample rate in Hz.
-              );
-
-    /// Destructor.
-    virtual ~BPMDetect();
-
-    /// Inputs a block of samples for analyzing: Envelopes the samples and then
-    /// updates the autocorrelation estimation. When whole song data has been input
-    /// in smaller blocks using this function, read the resulting bpm with 'getBpm' 
-    /// function. 
-    /// 
-    /// Notice that data in 'samples' array can be disrupted in processing.
-    void inputSamples(const soundtouch::SAMPLETYPE *samples,    ///< Pointer to input/working data buffer
-                      int numSamples                            ///< Number of samples in buffer
-                      );
-
-
-    /// Analyzes the results and returns the BPM rate. Use this function to read result
-    /// after whole song data has been input to the class by consecutive calls of
-    /// 'inputSamples' function.
-    ///
-    /// \return Beats-per-minute rate, or zero if detection failed.
-    float getBpm();
-};
+////////////////////////////////////////////////////////////////////////////////
 
-}
+    typedef struct
+    {
+        float pos;
+        float strength;
+    } BEAT;
 
+
+    class IIR2_filter
+    {
+        double coeffs[5];
+        double prev[5];
+
+    public:
+        IIR2_filter(const double *lpf_coeffs);
+        float update(float x);
+    };
+
+
+    /// Class for calculating BPM rate for audio data.
+    class BPMDetect
+    {
+    protected:
+        /// Auto-correlation accumulator bins.
+        float *xcorr;
+
+        /// Sample average counter.
+        int decimateCount;
+
+        /// Sample average accumulator for FIFO-like decimation.
+        soundtouch::LONG_SAMPLETYPE decimateSum;
+
+        /// Decimate sound by this coefficient to reach approx. 500 Hz.
+        int decimateBy;
+
+        /// Auto-correlation window length
+        int windowLen;
+
+        /// Number of channels (1 = mono, 2 = stereo)
+        int channels;
+
+        /// sample rate
+        int sampleRate;
+
+        /// Beginning of auto-correlation window: Autocorrelation isn't being updated for
+        /// the first these many correlation bins.
+        int windowStart;
+
+        /// window functions for data preconditioning
+        float *hamw;
+        float *hamw2;
+
+        // beat detection variables
+        int pos;
+        int peakPos;
+        int beatcorr_ringbuffpos;
+        int init_scaler;
+        float peakVal;
+        float *beatcorr_ringbuff;
+
+        /// FIFO-buffer for decimated processing samples.
+        soundtouch::FIFOSampleBuffer *buffer;
+
+        /// Collection of detected beat positions
+        //BeatCollection beats;
+        std::vector<BEAT> beats;
+
+        // 2nd order low-pass-filter
+        IIR2_filter beat_lpf;
+
+        /// Updates auto-correlation function for given number of decimated samples that 
+        /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe 
+        /// though).
+        void updateXCorr(int process_samples      /// How many samples are processed.
+        );
+
+        /// Decimates samples to approx. 500 Hz.
+        ///
+        /// \return Number of output samples.
+        int decimate(soundtouch::SAMPLETYPE *dest,      ///< Destination buffer
+            const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
+            int numsamples                     ///< Number of source samples.
+        );
+
+        /// Calculates amplitude envelope for the buffer of samples.
+        /// Result is output to 'samples'.
+        void calcEnvelope(soundtouch::SAMPLETYPE *samples,  ///< Pointer to input/output data buffer
+            int numsamples                    ///< Number of samples in buffer
+        );
+
+        /// remove constant bias from xcorr data
+        void removeBias();
+
+        // Detect individual beat positions
+        void updateBeatPos(int process_samples);
+
+
+    public:
+        /// Constructor.
+        BPMDetect(int numChannels,  ///< Number of channels in sample data.
+            int sampleRate    ///< Sample rate in Hz.
+        );
+
+        /// Destructor.
+        virtual ~BPMDetect();
+
+        /// Inputs a block of samples for analyzing: Envelopes the samples and then
+        /// updates the autocorrelation estimation. When whole song data has been input
+        /// in smaller blocks using this function, read the resulting bpm with 'getBpm' 
+        /// function. 
+        /// 
+        /// Notice that data in 'samples' array can be disrupted in processing.
+        void inputSamples(const soundtouch::SAMPLETYPE *samples,    ///< Pointer to input/working data buffer
+            int numSamples                            ///< Number of samples in buffer
+        );
+
+        /// Analyzes the results and returns the BPM rate. Use this function to read result
+        /// after whole song data has been input to the class by consecutive calls of
+        /// 'inputSamples' function.
+        ///
+        /// \return Beats-per-minute rate, or zero if detection failed.
+        float getBpm();
+
+        /// Get beat position arrays. Note: The array includes also really low beat detection values 
+        /// in absence of clear strong beats. Consumer may wish to filter low values away.
+        /// - "pos" receive array of beat positions
+        /// - "values" receive array of beat detection strengths
+        /// - max_num indicates max.size of "pos" and "values" array.  
+        ///
+        /// You can query a suitable array sized by calling this with NULL in "pos" & "values".
+        ///
+        /// \return number of beats in the arrays.
+        int getBeats(float *pos, float *strength, int max_num);
+    };
+}
 #endif // _BPMDetect_H_
diff --git a/Externals/soundtouch/FIFOSampleBuffer.cpp b/Externals/soundtouch/FIFOSampleBuffer.cpp
index 5f5ec4b7db0..8341163a608 100644
--- a/Externals/soundtouch/FIFOSampleBuffer.cpp
+++ b/Externals/soundtouch/FIFOSampleBuffer.cpp
@@ -15,13 +15,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2012-11-08 20:53:01 +0200 (Thu, 08 Nov 2012) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -80,7 +73,8 @@ void FIFOSampleBuffer::setChannels(int numChannels)
 {
     uint usedBytes;
 
-    assert(numChannels > 0);
+    if (!verifyNumberOfChannels(numChannels)) return;
+
     usedBytes = channels * samplesInBuffer;
     channels = (uint)numChannels;
     samplesInBuffer = usedBytes / channels;
@@ -131,7 +125,7 @@ void FIFOSampleBuffer::putSamples(uint nSamples)
 //
 // Parameter 'slackCapacity' tells the function how much free capacity (in
 // terms of samples) there _at least_ should be, in order to the caller to
-// succesfully insert all the required samples to the buffer. When necessary, 
+// successfully insert all the required samples to the buffer. When necessary, 
 // the function grows the buffer size to comply with this requirement.
 //
 // When using this function as means for inserting new samples, also remember 
@@ -158,7 +152,7 @@ SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
 }
 
 
-// Ensures that the buffer has enought capacity, i.e. space for _at least_
+// Ensures that the buffer has enough capacity, i.e. space for _at least_
 // 'capacityRequirement' number of samples. The buffer is grown in steps of
 // 4 kilobytes to eliminate the need for frequently growing up the buffer,
 // as well as to round the buffer size up to the virtual memory page size.
@@ -271,4 +265,3 @@ uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
     }
     return samplesInBuffer;
 }
-
diff --git a/Externals/soundtouch/FIFOSampleBuffer.h b/Externals/soundtouch/FIFOSampleBuffer.h
index 6f33df3daaa..de298dd82ba 100644
--- a/Externals/soundtouch/FIFOSampleBuffer.h
+++ b/Externals/soundtouch/FIFOSampleBuffer.h
@@ -15,13 +15,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-05 23:40:22 +0200 (Sun, 05 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -119,7 +112,7 @@ class FIFOSampleBuffer : public FIFOSamplePipe
     /// 'putSamples(numSamples)' function.
     SAMPLETYPE *ptrEnd(
                 uint slackCapacity   ///< How much free capacity (in samples) there _at least_ 
-                                     ///< should be so that the caller can succesfully insert the 
+                                     ///< should be so that the caller can successfully insert the 
                                      ///< desired samples to the buffer. If necessary, the function 
                                      ///< grows the buffer size to comply with this requirement.
                 );
diff --git a/Externals/soundtouch/FIFOSamplePipe.h b/Externals/soundtouch/FIFOSamplePipe.h
index 6e3105970ba..38ef31a5c24 100644
--- a/Externals/soundtouch/FIFOSamplePipe.h
+++ b/Externals/soundtouch/FIFOSamplePipe.h
@@ -17,13 +17,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2012-06-13 22:29:53 +0300 (Wed, 13 Jun 2012) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -58,6 +51,18 @@ namespace soundtouch
 /// Abstract base class for FIFO (first-in-first-out) sample processing classes.
 class FIFOSamplePipe
 {
+protected:
+
+    bool verifyNumberOfChannels(int nChannels) const
+    {
+        if ((nChannels > 0) && (nChannels <= SOUNDTOUCH_MAX_CHANNELS))
+        {
+            return true;
+        }
+        ST_THROW_RT_ERROR("Error: Illegal number of channels");
+        return false;
+    }
+
 public:
     // virtual default destructor
     virtual ~FIFOSamplePipe() {}
@@ -122,7 +127,6 @@ class FIFOSamplePipe
 };
 
 
-
 /// Base-class for sound processing routines working in FIFO principle. With this base 
 /// class it's easy to implement sound processing stages that can be chained together,
 /// so that samples that are fed into beginning of the pipe automatically go through 
@@ -145,7 +149,6 @@ class FIFOProcessor :public FIFOSamplePipe
         output = pOutput;
     }
 
-
     /// Constructor. Doesn't define output pipe; it has to be set be 
     /// 'setOutPipe' function.
     FIFOProcessor()
@@ -153,7 +156,6 @@ class FIFOProcessor :public FIFOSamplePipe
         output = NULL;
     }
 
-
     /// Constructor. Configures output pipe.
     FIFOProcessor(FIFOSamplePipe *pOutput   ///< Output pipe.
                  )
@@ -161,13 +163,11 @@ class FIFOProcessor :public FIFOSamplePipe
         output = pOutput;
     }
 
-
     /// Destructor.
     virtual ~FIFOProcessor()
     {
     }
 
-
     /// Returns a pointer to the beginning of the output samples. 
     /// This function is provided for accessing the output samples directly. 
     /// Please be careful for not to corrupt the book-keeping!
@@ -194,7 +194,6 @@ class FIFOProcessor :public FIFOSamplePipe
         return output->receiveSamples(outBuffer, maxSamples);
     }
 
-
     /// Adjusts book-keeping so that given number of samples are removed from beginning of the 
     /// sample buffer without copying them anywhere. 
     ///
@@ -206,14 +205,12 @@ class FIFOProcessor :public FIFOSamplePipe
         return output->receiveSamples(maxSamples);
     }
 
-
     /// Returns number of samples currently available.
     virtual uint numSamples() const
     {
         return output->numSamples();
     }
 
-
     /// Returns nonzero if there aren't any samples available for outputting.
     virtual int isEmpty() const
     {
@@ -226,7 +223,6 @@ class FIFOProcessor :public FIFOSamplePipe
     {
         return output->adjustAmountOfSamples(numSamples);
     }
-
 };
 
 }
diff --git a/Externals/soundtouch/FIRFilter.cpp b/Externals/soundtouch/FIRFilter.cpp
index e56969b0537..218e50ef5a7 100644
--- a/Externals/soundtouch/FIRFilter.cpp
+++ b/Externals/soundtouch/FIRFilter.cpp
@@ -2,22 +2,21 @@
 ///
 /// General FIR digital filter routines with MMX optimization. 
 ///
-/// Note : MMX optimized functions reside in a separate, platform-specific file, 
+/// Notes : MMX optimized functions reside in a separate, platform-specific file, 
 /// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
 ///
+/// This source file contains OpenMP optimizations that allow speeding up the
+/// corss-correlation algorithm by executing it in several threads / CPU cores 
+/// in parallel. See the following article link for more detailed discussion 
+/// about SoundTouch OpenMP optimizations:
+/// http://www.softwarecoven.com/parallel-computing-in-embedded-mobile-devices
+///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
 /// SoundTouch WWW: http://www.surina.net/soundtouch
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIRFilter.cpp 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -69,6 +68,7 @@ FIRFilter::~FIRFilter()
     delete[] filterCoeffs;
 }
 
+
 // Usual C-version of the filter routine for stereo sound
 uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
 {
@@ -127,8 +127,6 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
 }
 
 
-
-
 // Usual C-version of the filter routine for mono sound
 uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
 {
@@ -254,7 +252,6 @@ 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' 
@@ -284,7 +281,6 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample
 }
 
 
-
 // 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)
diff --git a/Externals/soundtouch/FIRFilter.h b/Externals/soundtouch/FIRFilter.h
index 6b14238ce86..297b0f81ecc 100644
--- a/Externals/soundtouch/FIRFilter.h
+++ b/Externals/soundtouch/FIRFilter.h
@@ -11,13 +11,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: FIRFilter.h 202 2015-02-21 21:24:29Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
diff --git a/Externals/soundtouch/InterpolateCubic.cpp b/Externals/soundtouch/InterpolateCubic.cpp
index 8aa7374c743..fe49684817f 100644
--- a/Externals/soundtouch/InterpolateCubic.cpp
+++ b/Externals/soundtouch/InterpolateCubic.cpp
@@ -1,200 +1,196 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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;
-}
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Cubic interpolation routine.
+///
+/// Author        : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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;
+}
diff --git a/Externals/soundtouch/InterpolateCubic.h b/Externals/soundtouch/InterpolateCubic.h
index f98e701d7be..457821033f9 100644
--- a/Externals/soundtouch/InterpolateCubic.h
+++ b/Externals/soundtouch/InterpolateCubic.h
@@ -1,67 +1,63 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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 225 2015-07-26 14:45:48Z 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);
-
-    double fract;
-
-public:
-    InterpolateCubic();
-};
-
-}
-
-#endif
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Cubic interpolation routine.
+///
+/// Author        : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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);
+
+    double fract;
+
+public:
+    InterpolateCubic();
+};
+
+}
+
+#endif
diff --git a/Externals/soundtouch/InterpolateLinear.cpp b/Externals/soundtouch/InterpolateLinear.cpp
index 81198138578..c3aa1994cfa 100644
--- a/Externals/soundtouch/InterpolateLinear.cpp
+++ b/Externals/soundtouch/InterpolateLinear.cpp
@@ -1,300 +1,296 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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 225 2015-07-26 14:45:48Z 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(double newRate)
-{
-    iRate = (int)(newRate * SCALE + 0.5);
-    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.0);
-}
-
-
-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, fract_float;
-    
-        vol1 = (float)(1.0 - fract);
-		fract_float = (float)fract;
-        for (int c = 0; c < numChannels; c ++)
-        {
-			temp = vol1 * src[c] + fract_float * 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;
-}
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Linear interpolation algorithm.
+///
+/// Author        : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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(double newRate)
+{
+    iRate = (int)(newRate * SCALE + 0.5);
+    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.0);
+}
+
+
+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, fract_float;
+    
+        vol1 = (float)(1.0 - fract);
+		fract_float = (float)fract;
+        for (int c = 0; c < numChannels; c ++)
+        {
+			temp = vol1 * src[c] + fract_float * 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;
+}
diff --git a/Externals/soundtouch/InterpolateLinear.h b/Externals/soundtouch/InterpolateLinear.h
index 6a7e11d18bc..faa2e2c5a58 100644
--- a/Externals/soundtouch/InterpolateLinear.h
+++ b/Externals/soundtouch/InterpolateLinear.h
@@ -1,92 +1,88 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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 225 2015-07-26 14:45:48Z 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(double newRate);
-};
-
-
-/// Linear transposer class that uses floating point arithmetics
-class InterpolateLinearFloat : public TransposerBase
-{
-protected:
-    double 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
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// Linear interpolation routine.
+///
+/// Author        : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 arithmetic
+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(double newRate);
+};
+
+
+/// Linear transposer class that uses floating point arithmetic
+class InterpolateLinearFloat : public TransposerBase
+{
+protected:
+    double 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
diff --git a/Externals/soundtouch/InterpolateShannon.cpp b/Externals/soundtouch/InterpolateShannon.cpp
index 1085fd14cb1..1d69a2e8840 100644
--- a/Externals/soundtouch/InterpolateShannon.cpp
+++ b/Externals/soundtouch/InterpolateShannon.cpp
@@ -1,185 +1,181 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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;
-}
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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;
+}
diff --git a/Externals/soundtouch/InterpolateShannon.h b/Externals/soundtouch/InterpolateShannon.h
index 54703d98082..c621cf1e1d7 100644
--- a/Externals/soundtouch/InterpolateShannon.h
+++ b/Externals/soundtouch/InterpolateShannon.h
@@ -1,72 +1,68 @@
-////////////////////////////////////////////////////////////////////////////////
-/// 
-/// 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 225 2015-07-26 14:45:48Z 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);
-
-    double fract;
-
-public:
-    InterpolateShannon();
-};
-
-}
-
-#endif
+////////////////////////////////////////////////////////////////////////////////
+/// 
+/// 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
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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);
+
+    double fract;
+
+public:
+    InterpolateShannon();
+};
+
+}
+
+#endif
diff --git a/Externals/soundtouch/PeakFinder.cpp b/Externals/soundtouch/PeakFinder.cpp
index b1e2205c3f8..34db39bc23b 100644
--- a/Externals/soundtouch/PeakFinder.cpp
+++ b/Externals/soundtouch/PeakFinder.cpp
@@ -11,13 +11,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-05-18 18:22:02 +0300 (Mon, 18 May 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: PeakFinder.cpp 213 2015-05-18 15:22:02Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -64,7 +57,7 @@ int PeakFinder::findTop(const float *data, int peakpos) const
 
     refvalue = data[peakpos];
 
-    // seek within ±10 points
+    // seek within �10 points
     start = peakpos - 10;
     if (start < minPos) start = minPos;
     end = peakpos + 10;
@@ -149,7 +142,7 @@ int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, i
     peaklevel = data[peakpos];
     assert(peaklevel >= level);
     pos = peakpos;
-    while ((pos >= minPos) && (pos < maxPos))
+    while ((pos >= minPos) && (pos + direction < maxPos))
     {
         if (data[pos + direction] < level) return pos;   // crossing found
         pos += direction;
@@ -178,7 +171,6 @@ double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos)
 }
 
 
-
 /// get exact center of peak near given position by calculating local mass of center
 double PeakFinder::getPeakCenter(const float *data, int peakpos) const
 {
@@ -218,7 +210,6 @@ double PeakFinder::getPeakCenter(const float *data, int peakpos) const
 }
 
 
-
 double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos) 
 {
 
@@ -249,12 +240,12 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
     // - sometimes the highest peak can be Nth harmonic of the true base peak yet 
     // just a slightly higher than the true base
 
-    for (i = 3; i < 10; i ++)
+    for (i = 1; i < 3; i ++)
     {
         double peaktmp, harmonic;
         int i1,i2;
 
-        harmonic = (double)i * 0.5;
+        harmonic = (double)pow(2.0, i);
         peakpos = (int)(highPeak / harmonic + 0.5f);
         if (peakpos < minPos) break;
         peakpos = findTop(data, peakpos);   // seek true local maximum index
@@ -265,7 +256,7 @@ double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
 
         // accept harmonic peak if 
         // (a) it is found
-        // (b) is within ±4% of the expected harmonic interval
+        // (b) is within �4% of the expected harmonic interval
         // (c) has at least half x-corr value of the max. peak
 
         double diff = harmonic * peaktmp / highPeak;
diff --git a/Externals/soundtouch/PeakFinder.h b/Externals/soundtouch/PeakFinder.h
index 594f2308826..9fe66adac5f 100644
--- a/Externals/soundtouch/PeakFinder.h
+++ b/Externals/soundtouch/PeakFinder.h
@@ -9,13 +9,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2011-12-30 22:33:46 +0200 (Fri, 30 Dec 2011) $
-// File revision : $Revision: 4 $
-//
-// $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -51,8 +44,8 @@ class PeakFinder
 
     /// Calculates the mass center between given vector items.
     double calcMassCenter(const float *data, ///< Data vector.
-                         int firstPos,      ///< Index of first vector item beloging to the peak.
-                         int lastPos        ///< Index of last vector item beloging to the peak.
+                         int firstPos,      ///< Index of first vector item belonging to the peak.
+                         int lastPos        ///< Index of last vector item belonging to the peak.
                          ) const;
 
     /// Finds the data vector index where the monotoniously decreasing signal crosses the
diff --git a/Externals/soundtouch/RateTransposer.cpp b/Externals/soundtouch/RateTransposer.cpp
index 95b9437a246..2efaf0424df 100644
--- a/Externals/soundtouch/RateTransposer.cpp
+++ b/Externals/soundtouch/RateTransposer.cpp
@@ -10,13 +10,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: RateTransposer.cpp 225 2015-07-26 14:45:48Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -57,7 +50,13 @@ TransposerBase::ALGORITHM TransposerBase::algorithm = TransposerBase::CUBIC;
 // Constructor
 RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
 {
-    bUseAAFilter = true;
+    bUseAAFilter = 
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+        true;
+#else
+        // Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
+        false;
+#endif
 
     // Instantiates the anti-alias filter
     pAAFilter = new AAFilter(64);
@@ -65,7 +64,6 @@ RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
 }
 
 
-
 RateTransposer::~RateTransposer()
 {
     delete pAAFilter;
@@ -73,11 +71,13 @@ RateTransposer::~RateTransposer()
 }
 
 
-
 /// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
 void RateTransposer::enableAAFilter(bool newMode)
 {
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+    // Disable Anti-alias filter if desirable to avoid click at rate change zero value crossover
     bUseAAFilter = newMode;
+#endif
 }
 
 
@@ -94,7 +94,6 @@ AAFilter *RateTransposer::getAAFilter()
 }
 
 
-
 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower 
 // iRate, larger faster iRates.
 void RateTransposer::setRate(double newRate)
@@ -177,11 +176,10 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
 // Sets the number of channels, 1 = mono, 2 = stereo
 void RateTransposer::setChannels(int nChannels)
 {
-    assert(nChannels > 0);
+    if (!verifyNumberOfChannels(nChannels) ||
+        (pTransposer->numChannels == nChannels)) return;
 
-    if (pTransposer->numChannels == nChannels) return;
     pTransposer->setChannels(nChannels);
-
     inputBuffer.setChannels(nChannels);
     midBuffer.setChannels(nChannels);
     outputBuffer.setChannels(nChannels);
@@ -208,6 +206,13 @@ int RateTransposer::isEmpty() const
 }
 
 
+/// Return approximate initial input-output latency
+int RateTransposer::getLatency() const
+{
+    return (bUseAAFilter) ? pAAFilter->getLength() : 0;
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // TransposerBase - Base class for interpolation
@@ -280,7 +285,7 @@ void TransposerBase::setRate(double newRate)
 TransposerBase *TransposerBase::newInstance()
 {
 #ifdef SOUNDTOUCH_INTEGER_SAMPLES
-    // Notice: For integer arithmetics support only linear algorithm (due to simplest calculus)
+    // Notice: For integer arithmetic support only linear algorithm (due to simplest calculus)
     return ::new InterpolateLinearInteger;
 #else
     switch (algorithm)
diff --git a/Externals/soundtouch/RateTransposer.h b/Externals/soundtouch/RateTransposer.h
index e9cedfac9c8..52b7441b89e 100644
--- a/Externals/soundtouch/RateTransposer.h
+++ b/Externals/soundtouch/RateTransposer.h
@@ -14,13 +14,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: RateTransposer.h 225 2015-07-26 14:45:48Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -132,21 +125,9 @@ class RateTransposer : public FIFOProcessor
     RateTransposer();
     virtual ~RateTransposer();
 
-    /// Operator 'new' is overloaded so that it automatically creates a suitable instance 
-    /// depending on if we're to use integer or floating point arithmetics.
-//    static void *operator new(size_t s);
-
-    /// Use this function instead of "new" operator to create a new instance of this class. 
-    /// This function automatically chooses a correct implementation, depending on if 
-    /// integer ot floating point arithmetics are to be used.
-//    static RateTransposer *newInstance();
-
     /// Returns the output buffer object
     FIFOSamplePipe *getOutput() { return &outputBuffer; };
 
-    /// Returns the store buffer object
-//    FIFOSamplePipe *getStore() { return &storeBuffer; };
-
     /// Return anti-alias filter object
     AAFilter *getAAFilter();
 
@@ -172,6 +153,9 @@ class RateTransposer : public FIFOProcessor
 
     /// Returns nonzero if there aren't any samples available for outputting.
     int isEmpty() const;
+
+    /// Return approximate initial input-output latency
+    int getLatency() const;
 };
 
 }
diff --git a/Externals/soundtouch/STTypes.h b/Externals/soundtouch/STTypes.h
index a07bc3dcea2..862505e7691 100644
--- a/Externals/soundtouch/STTypes.h
+++ b/Externals/soundtouch/STTypes.h
@@ -8,13 +8,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-05-18 18:25:07 +0300 (Mon, 18 May 2015) $
-// File revision : $Revision: 3 $
-//
-// $Id: STTypes.h 215 2015-05-18 15:25:07Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -57,16 +50,19 @@ typedef unsigned long   ulong;
 #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"
+    #include "soundtouch_config.h"
 #endif
 
 
 namespace soundtouch
 {
+    /// Max allowed number of channels
+    #define SOUNDTOUCH_MAX_CHANNELS     16
+
     /// Activate these undef's to overrule the possible sampletype 
     /// setting inherited from some other header file:
-    #undef SOUNDTOUCH_INTEGER_SAMPLES
-    #undef SOUNDTOUCH_FLOAT_SAMPLES
+    //#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 
@@ -75,7 +71,7 @@ namespace soundtouch
     /// runtime performance so recommendation is to keep this off.
     // #define USE_MULTICH_ALWAYS
 
-    #if (defined(__SOFTFP__))
+    #if (defined(__SOFTFP__) && defined(ANDROID))
         // 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
@@ -98,8 +94,8 @@ namespace soundtouch
         ///   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_INTEGER_SAMPLES     1    //< 16bit integer samples
+        #define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples
      
     #endif
 
@@ -110,7 +106,7 @@ namespace soundtouch
         /// routines compiled for whatever reason, you may disable these optimizations 
         /// to make the library compile.
 
-        //#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS     1
+        #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS     1
 
         /// In GNU environment, allow the user to override this setting by
         /// giving the following switch to the configure script:
@@ -143,8 +139,10 @@ namespace soundtouch
         #endif // SOUNDTOUCH_FLOAT_SAMPLES
 
         #ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
-            // Allow MMX optimizations
-            #define SOUNDTOUCH_ALLOW_MMX   1
+            // Allow MMX optimizations (not available in X64 mode)
+            #if (!_M_X64)
+                #define SOUNDTOUCH_ALLOW_MMX   1
+            #endif
         #endif
 
     #else
@@ -164,7 +162,7 @@ namespace soundtouch
 };
 
 // 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>
diff --git a/Externals/soundtouch/SoundTouch.cpp b/Externals/soundtouch/SoundTouch.cpp
index edccce238da..1618884cf51 100644
--- a/Externals/soundtouch/SoundTouch.cpp
+++ b/Externals/soundtouch/SoundTouch.cpp
@@ -41,13 +41,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: SoundTouch.cpp 225 2015-07-26 14:45:48Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -110,15 +103,14 @@ SoundTouch::SoundTouch()
 
     calcEffectiveRateAndTempo();
 
-	samplesExpectedOut = 0;
-	samplesOutput = 0;
+    samplesExpectedOut = 0;
+    samplesOutput = 0;
 
     channels = 0;
     bSrateSet = false;
 }
 
 
-
 SoundTouch::~SoundTouch()
 {
     delete pRateTransposer;
@@ -126,7 +118,6 @@ SoundTouch::~SoundTouch()
 }
 
 
-
 /// Get SoundTouch library version string
 const char *SoundTouch::getVersionString()
 {
@@ -146,18 +137,14 @@ uint SoundTouch::getVersionId()
 // Sets the number of channels, 1 = mono, 2 = stereo
 void SoundTouch::setChannels(uint numChannels)
 {
-    /*if (numChannels != 1 && numChannels != 2) 
-    {
-        //ST_THROW_RT_ERROR("Illegal number of channels");
-		return;
-    }*/
+    if (!verifyNumberOfChannels(numChannels)) return;
+
     channels = numChannels;
     pRateTransposer->setChannels((int)numChannels);
     pTDStretch->setChannels((int)numChannels);
 }
 
 
-
 // Sets new rate control value. Normal rate = 1.0, smaller values
 // represent slower rate, larger faster rates.
 void SoundTouch::setRate(double newRate)
@@ -167,7 +154,6 @@ void SoundTouch::setRate(double newRate)
 }
 
 
-
 // Sets new rate control value as a difference in percents compared
 // to the original rate (-50 .. +100 %)
 void SoundTouch::setRateChange(double newRate)
@@ -177,7 +163,6 @@ void SoundTouch::setRateChange(double newRate)
 }
 
 
-
 // Sets new tempo control value. Normal tempo = 1.0, smaller values
 // represent slower tempo, larger faster tempo.
 void SoundTouch::setTempo(double newTempo)
@@ -187,7 +172,6 @@ void SoundTouch::setTempo(double newTempo)
 }
 
 
-
 // Sets new tempo control value as a difference in percents compared
 // to the original tempo (-50 .. +100 %)
 void SoundTouch::setTempoChange(double newTempo)
@@ -197,7 +181,6 @@ void SoundTouch::setTempoChange(double newTempo)
 }
 
 
-
 // Sets new pitch control value. Original pitch = 1.0, smaller values
 // represent lower pitches, larger values higher pitch.
 void SoundTouch::setPitch(double newPitch)
@@ -207,7 +190,6 @@ void SoundTouch::setPitch(double newPitch)
 }
 
 
-
 // Sets pitch change in octaves compared to the original pitch
 // (-1.00 .. +1.00)
 void SoundTouch::setPitchOctaves(double newPitch)
@@ -217,7 +199,6 @@ void SoundTouch::setPitchOctaves(double newPitch)
 }
 
 
-
 // Sets pitch change in semi-tones compared to the original pitch
 // (-12 .. +12)
 void SoundTouch::setPitchSemiTones(int newPitch)
@@ -226,7 +207,6 @@ void SoundTouch::setPitchSemiTones(int newPitch)
 }
 
 
-
 void SoundTouch::setPitchSemiTones(double newPitch)
 {
     setPitchOctaves(newPitch / 12.0);
@@ -240,11 +220,11 @@ void SoundTouch::calcEffectiveRateAndTempo()
     double oldTempo = tempo;
     double oldRate = rate;
 
-	tempo = virtualTempo / virtualPitch;
-	rate = virtualPitch * virtualRate;
+    tempo = virtualTempo / virtualPitch;
+    rate = virtualPitch * virtualRate;
 
     if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
-	if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
+    if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
 
 #ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
     if (rate <= 1.0f) 
@@ -286,9 +266,9 @@ void SoundTouch::calcEffectiveRateAndTempo()
 // Sets sample rate.
 void SoundTouch::setSampleRate(uint srate)
 {
-    bSrateSet = true;
     // set sample rate, leave other tempo changer parameters as they are.
     pTDStretch->setParameters((int)srate);
+    bSrateSet = true;
 }
 
 
@@ -305,25 +285,9 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
         ST_THROW_RT_ERROR("SoundTouch : Number of channels not defined");
     }
 
-    // Transpose the rate of the new samples if necessary
-    /* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
-    if (rate == 1.0f) 
-    {
-        // The rate value is same as the original, simply evaluate the tempo changer. 
-        assert(output == pTDStretch);
-        if (pRateTransposer->isEmpty() == 0) 
-        {
-            // yet flush the last samples in the pitch transposer buffer
-            // (may happen if 'rate' changes from a non-zero value to zero)
-            pTDStretch->moveSamples(*pRateTransposer);
-        }
-        pTDStretch->putSamples(samples, nSamples);
-    } 
-    */
-
-	// accumulate how many samples are expected out from processing, given the current 
-	// processing setting
-	samplesExpectedOut += (double)nSamples / ((double)rate * (double)tempo);
+    // accumulate how many samples are expected out from processing, given the current 
+    // processing setting
+    samplesExpectedOut += (double)nSamples / ((double)rate * (double)tempo);
 
 #ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
     if (rate <= 1.0f) 
@@ -354,28 +318,28 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
 void SoundTouch::flush()
 {
     int i;
-	int numStillExpected;
+    int numStillExpected;
     SAMPLETYPE *buff = new SAMPLETYPE[128 * channels];
 
-	// how many samples are still expected to output
-	numStillExpected = (int)((long)(samplesExpectedOut + 0.5) - samplesOutput);
+    // how many samples are still expected to output
+    numStillExpected = (int)((long)(samplesExpectedOut + 0.5) - samplesOutput);
+    if (numStillExpected < 0) numStillExpected = 0;
 
     memset(buff, 0, 128 * channels * sizeof(SAMPLETYPE));
     // "Push" the last active samples out from the processing pipeline by
     // feeding blank samples into the processing pipeline until new, 
     // processed samples appear in the output (not however, more than 
     // 24ksamples in any case)
-	for (i = 0; (numStillExpected > (int)numSamples()) && (i < 200); i ++)
-	{
-		putSamples(buff, 128);
-	}
+    for (i = 0; (numStillExpected > (int)numSamples()) && (i < 200); i ++)
+    {
+        putSamples(buff, 128);
+    }
 
-	adjustAmountOfSamples(numStillExpected);
+    adjustAmountOfSamples(numStillExpected);
 
     delete[] buff;
 
     // Clear input buffers
- //   pRateTransposer->clearInput();
     pTDStretch->clearInput();
     // yet leave the output intouched as that's where the
     // flushed samples are!
@@ -446,7 +410,7 @@ int SoundTouch::getSetting(int settingId) const
             return pRateTransposer->getAAFilter()->getLength();
 
         case SETTING_USE_QUICKSEEK :
-            return (uint)   pTDStretch->isQuickSeekEnabled();
+            return (uint)pTDStretch->isQuickSeekEnabled();
 
         case SETTING_SEQUENCE_MS:
             pTDStretch->getParameters(NULL, &temp, NULL, NULL);
@@ -460,13 +424,53 @@ int SoundTouch::getSetting(int settingId) const
             pTDStretch->getParameters(NULL, NULL, NULL, &temp);
             return temp;
 
-		case SETTING_NOMINAL_INPUT_SEQUENCE :
-			return pTDStretch->getInputSampleReq();
+        case SETTING_NOMINAL_INPUT_SEQUENCE :
+        {
+            int size = pTDStretch->getInputSampleReq();
+
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+            if (rate <= 1.0)
+            {
+                // transposing done before timestretch, which impacts latency
+                return (int)(size * rate + 0.5);
+            }
+#endif
+            return size;
+        }
+
+        case SETTING_NOMINAL_OUTPUT_SEQUENCE :
+        {
+            int size = pTDStretch->getOutputBatchSize();
+
+            if (rate > 1.0)
+            {
+                // transposing done after timestretch, which impacts latency
+                return (int)(size / rate + 0.5);
+            }
+            return size;
+        }
+
+        case SETTING_INITIAL_LATENCY:
+        {
+            double latency = pTDStretch->getLatency();
+            int latency_tr = pRateTransposer->getLatency();
+
+#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
+            if (rate <= 1.0)
+            {
+                // transposing done before timestretch, which impacts latency
+                latency = (latency + latency_tr) * rate;
+            }
+            else
+#endif
+            {
+                latency += (double)latency_tr / rate;
+            }
 
-		case SETTING_NOMINAL_OUTPUT_SEQUENCE :
-			return pTDStretch->getOutputBatchSize();
+            return (int)(latency + 0.5);
+        }
 
-		default :
+        default :
             return 0;
     }
 }
@@ -476,13 +480,13 @@ int SoundTouch::getSetting(int settingId) const
 // buffers.
 void SoundTouch::clear()
 {
-	samplesExpectedOut = 0;
+    samplesExpectedOut = 0;
+    samplesOutput = 0;
     pRateTransposer->clear();
     pTDStretch->clear();
 }
 
 
-
 /// Returns number of samples currently unprocessed.
 uint SoundTouch::numUnprocessedSamples() const
 {
@@ -499,7 +503,6 @@ uint SoundTouch::numUnprocessedSamples() const
 }
 
 
-
 /// Output samples from beginning of the sample buffer. Copies requested samples to 
 /// output buffer and removes them from the sample buffer. If there are less than 
 /// 'numsample' samples in the buffer, returns all that available.
@@ -507,9 +510,9 @@ uint SoundTouch::numUnprocessedSamples() const
 /// \return Number of samples returned.
 uint SoundTouch::receiveSamples(SAMPLETYPE *output, uint maxSamples)
 {
-	uint ret = FIFOProcessor::receiveSamples(output, maxSamples);
-	samplesOutput += (long)ret;
-	return ret;
+    uint ret = FIFOProcessor::receiveSamples(output, maxSamples);
+    samplesOutput += (long)ret;
+    return ret;
 }
 
 
@@ -520,7 +523,16 @@ uint SoundTouch::receiveSamples(SAMPLETYPE *output, uint maxSamples)
 /// with 'ptrBegin' function.
 uint SoundTouch::receiveSamples(uint maxSamples)
 {
-	uint ret = FIFOProcessor::receiveSamples(maxSamples);
-	samplesOutput += (long)ret;
-	return ret;
+    uint ret = FIFOProcessor::receiveSamples(maxSamples);
+    samplesOutput += (long)ret;
+    return ret;
+}
+
+
+/// Get ratio between input and output audio durations, useful for calculating
+/// processed output duration: if you'll process a stream of N samples, then 
+/// you can expect to get out N * getInputOutputSampleRatio() samples.
+double SoundTouch::getInputOutputSampleRatio()
+{
+    return 1.0 / (tempo * rate);
 }
diff --git a/Externals/soundtouch/SoundTouch.h b/Externals/soundtouch/SoundTouch.h
index 24e8716e049..e963ddfde80 100644
--- a/Externals/soundtouch/SoundTouch.h
+++ b/Externals/soundtouch/SoundTouch.h
@@ -41,13 +41,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-09-20 10:38:32 +0300 (Sun, 20 Sep 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: SoundTouch.h 230 2015-09-20 07:38:32Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -79,10 +72,10 @@ namespace soundtouch
 {
 
 /// Soundtouch library version string
-#define SOUNDTOUCH_VERSION          "1.9.2"
+#define SOUNDTOUCH_VERSION          "2.1.3"
 
 /// SoundTouch library version id
-#define SOUNDTOUCH_VERSION_ID       (10902)
+#define SOUNDTOUCH_VERSION_ID       (20103)
 
 //
 // Available setting IDs for the 'setSetting' & 'get_setting' functions:
@@ -116,30 +109,61 @@ namespace soundtouch
 #define SETTING_OVERLAP_MS          5
 
 
-/// Call "getSetting" with this ID to query nominal average processing sequence
-/// size in samples. This value tells approcimate value how many input samples 
-/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
+/// Call "getSetting" with this ID to query processing sequence size in samples. 
+/// This value gives approximate value of how many input samples you'll need to 
+/// feed into SoundTouch after initial buffering to get out a new batch of
+/// output samples. 
+///
+/// This value does not include initial buffering at beginning of a new processing 
+/// stream, use SETTING_INITIAL_LATENCY to get the initial buffering size.
 ///
 /// Notices: 
 /// - This is read-only parameter, i.e. setSetting ignores this parameter
-/// - Returned value is approximate average value, exact processing batch
-///   size may wary from time to time
-/// - This parameter value is not constant but may change depending on 
+/// - This parameter value is not constant but change depending on 
 ///   tempo/pitch/rate/samplerate settings.
-#define SETTING_NOMINAL_INPUT_SEQUENCE		6
+#define SETTING_NOMINAL_INPUT_SEQUENCE      6
 
 
 /// Call "getSetting" with this ID to query nominal average processing output 
 /// size in samples. This value tells approcimate value how many output samples 
 /// SoundTouch outputs once it does DSP processing run for a batch of input samples.
-///	
+///
 /// Notices: 
 /// - This is read-only parameter, i.e. setSetting ignores this parameter
-/// - Returned value is approximate average value, exact processing batch
-///   size may wary from time to time
-/// - This parameter value is not constant but may change depending on 
+/// - This parameter value is not constant but change depending on 
 ///   tempo/pitch/rate/samplerate settings.
-#define SETTING_NOMINAL_OUTPUT_SEQUENCE		7
+#define SETTING_NOMINAL_OUTPUT_SEQUENCE     7
+
+
+/// Call "getSetting" with this ID to query initial processing latency, i.e.
+/// approx. how many samples you'll need to enter to SoundTouch pipeline before 
+/// you can expect to get first batch of ready output samples out. 
+///
+/// After the first output batch, you can then expect to get approx. 
+/// SETTING_NOMINAL_OUTPUT_SEQUENCE ready samples out for every
+/// SETTING_NOMINAL_INPUT_SEQUENCE samples that you enter into SoundTouch.
+///
+/// Example:
+///     processing with parameter -tempo=5
+///     => initial latency = 5509 samples
+///        input sequence  = 4167 samples
+///        output sequence = 3969 samples
+///
+/// Accordingly, you can expect to feed in approx. 5509 samples at beginning of 
+/// the stream, and then you'll get out the first 3969 samples. After that, for 
+/// every approx. 4167 samples that you'll put in, you'll receive again approx. 
+/// 3969 samples out.
+///
+/// This also means that average latency during stream processing is 
+/// INITIAL_LATENCY-OUTPUT_SEQUENCE/2, in the above example case 5509-3969/2 
+/// = 3524 samples
+/// 
+/// Notices: 
+/// - This is read-only parameter, i.e. setSetting ignores this parameter
+/// - This parameter value is not constant but change depending on 
+///   tempo/pitch/rate/samplerate settings.
+#define SETTING_INITIAL_LATENCY             8
+
 
 class SoundTouch : public FIFOProcessor
 {
@@ -228,6 +252,24 @@ protected :
     /// Sets sample rate.
     void setSampleRate(uint srate);
 
+    /// Get ratio between input and output audio durations, useful for calculating
+    /// processed output duration: if you'll process a stream of N samples, then 
+    /// you can expect to get out N * getInputOutputSampleRatio() samples.
+    ///
+    /// This ratio will give accurate target duration ratio for a full audio track, 
+    /// given that the the whole track is processed with same processing parameters.
+    /// 
+    /// If this ratio is applied to calculate intermediate offsets inside a processing
+    /// stream, then this ratio is approximate and can deviate +- some tens of milliseconds 
+    /// from ideal offset, yet by end of the audio stream the duration ratio will become
+    /// exact.
+    ///
+    /// Example: if processing with parameters "-tempo=15 -pitch=-3", the function
+    /// will return value 0.8695652... Now, if processing an audio stream whose duration
+    /// is exactly one million audio samples, then you can expect the processed 
+    /// output duration  be 0.869565 * 1000000 = 869565 samples.
+    double getInputOutputSampleRatio();
+
     /// Flushes the last samples from the processing pipeline to the output.
     /// Clears also the internal processing buffers.
     //
@@ -271,7 +313,7 @@ protected :
     /// Changes a setting controlling the processing system behaviour. See the
     /// 'SETTING_...' defines for available setting ID's.
     /// 
-    /// \return 'true' if the setting was succesfully changed
+    /// \return 'true' if the setting was successfully changed
     bool setSetting(int settingId,   ///< Setting ID number. see SETTING_... defines.
                     int value        ///< New setting value.
                     );
@@ -286,6 +328,11 @@ protected :
     /// Returns number of samples currently unprocessed.
     virtual uint numUnprocessedSamples() const;
 
+    /// Return number of channels
+    uint numChannels() const
+    {
+        return channels;
+    }
 
     /// Other handy functions that are implemented in the ancestor classes (see
     /// classes 'FIFOProcessor' and 'FIFOSamplePipe')
diff --git a/Externals/soundtouch/SoundTouch.vcxproj b/Externals/soundtouch/SoundTouch.vcxproj
index c29234fada9..8ea3563cdf4 100644
--- a/Externals/soundtouch/SoundTouch.vcxproj
+++ b/Externals/soundtouch/SoundTouch.vcxproj
@@ -44,6 +44,7 @@
     <ClInclude Include="PeakFinder.h" />
     <ClInclude Include="RateTransposer.h" />
     <ClInclude Include="SoundTouch.h" />
+    <ClInclude Include="soundtouch_config.h" />
     <ClInclude Include="STTypes.h" />
     <ClInclude Include="TDStretch.h" />
   </ItemGroup>
@@ -53,4 +54,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/Externals/soundtouch/TDStretch.cpp b/Externals/soundtouch/TDStretch.cpp
index bb473a9f633..ce49310900f 100644
--- a/Externals/soundtouch/TDStretch.cpp
+++ b/Externals/soundtouch/TDStretch.cpp
@@ -4,8 +4,14 @@
 /// while maintaining the original pitch by using a time domain WSOLA-like 
 /// method with several performance-increasing tweaks.
 ///
-/// Note : MMX optimized functions reside in a separate, platform-specific 
-/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
+/// Notes : MMX optimized functions reside in a separate, platform-specific 
+/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'.
+///
+/// This source file contains OpenMP optimizations that allow speeding up the
+/// corss-correlation algorithm by executing it in several threads / CPU cores 
+/// in parallel. See the following article link for more detailed discussion 
+/// about SoundTouch OpenMP optimizations:
+/// http://www.softwarecoven.com/parallel-computing-in-embedded-mobile-devices
 ///
 /// Author        : Copyright (c) Olli Parviainen
 /// Author e-mail : oparviai 'at' iki.fi
@@ -13,13 +19,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
-// File revision : $Revision: 1.12 $
-//
-// $Id: TDStretch.cpp 226 2015-08-08 21:00:15Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -128,8 +127,13 @@ void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
                               int aSeekWindowMS, int aOverlapMS)
 {
     // accept only positive parameter values - if zero or negative, use old values instead
-    if (aSampleRate > 0)   this->sampleRate = aSampleRate;
-    if (aOverlapMS > 0)    this->overlapMs = aOverlapMS;
+    if (aSampleRate > 0)
+    {
+        if (aSampleRate > 192000) ST_THROW_RT_ERROR("Error: Excessive samplerate");
+        this->sampleRate = aSampleRate;
+    }
+
+    if (aOverlapMS > 0) this->overlapMs = aOverlapMS;
 
     if (aSequenceMS > 0)
     {
@@ -219,6 +223,7 @@ void TDStretch::clearInput()
 {
     inputBuffer.clear();
     clearMidBuffer();
+    isBeginning = true;
 }
 
 
@@ -297,12 +302,13 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
     int i;
     double norm;
 
-    bestCorr = FLT_MIN;
+    bestCorr = -FLT_MAX;
     bestOffs = 0;
 
     // Scans for the best correlation value by testing each possible position
     // over the permitted range.
     bestCorr = calcCrossCorr(refPos, pMidBuffer, norm);
+    bestCorr = (bestCorr + 0.1) * 0.75;
 
     #pragma omp parallel for
     for (i = 1; i < seekLength; i ++) 
@@ -354,7 +360,7 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
 // with improved precision
 //
 // Based on testing:
-// - This algorithm gives on average 99% as good match as the full algorith
+// - This algorithm gives on average 99% as good match as the full algorithm
 // - this quick seek algorithm finds the best match on ~90% of cases
 // - on those 10% of cases when this algorithm doesn't find best match, 
 //   it still finds on average ~90% match vs. the best possible match
@@ -373,12 +379,10 @@ int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
 
     // note: 'float' types used in this function in case that the platform would need to use software-fp
 
-    bestCorr = FLT_MIN;
-    bestOffs = SCANWIND;
-    bestCorr2 = FLT_MIN;
-    bestOffs2 = 0;
-
-    int best = 0;
+    bestCorr =
+    bestCorr2 = -FLT_MAX;
+    bestOffs = 
+    bestOffs2 = SCANWIND;
 
     // Scans for the best correlation value by testing each possible position
     // over the permitted range. Look for two best matches on the first pass to
@@ -436,7 +440,6 @@ int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
         {
             bestCorr = corr;
             bestOffs = i;
-            best = 1;
         }
     }
 
@@ -458,7 +461,6 @@ int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
         {
             bestCorr = corr;
             bestOffs = i;
-            best = 2;
         }
     }
 
@@ -515,18 +517,18 @@ void TDStretch::clearCrossCorrState()
 void TDStretch::calcSeqParameters()
 {
     // Adjust tempo param according to tempo, so that variating processing sequence length is used
-    // at varius tempo settings, between the given low...top limits
+    // at various tempo settings, between the given low...top limits
     #define AUTOSEQ_TEMPO_LOW   0.5     // auto setting low tempo range (-50%)
     #define AUTOSEQ_TEMPO_TOP   2.0     // auto setting top tempo range (+100%)
 
     // sequence-ms setting values at above low & top tempo
-    #define AUTOSEQ_AT_MIN      125.0
-    #define AUTOSEQ_AT_MAX      50.0
+    #define AUTOSEQ_AT_MIN      90.0
+    #define AUTOSEQ_AT_MAX      40.0
     #define AUTOSEQ_K           ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
     #define AUTOSEQ_C           (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW))
 
     // seek-window-ms setting values at above low & top tempoq
-    #define AUTOSEEK_AT_MIN     25.0
+    #define AUTOSEEK_AT_MIN     20.0
     #define AUTOSEEK_AT_MAX     15.0
     #define AUTOSEEK_K          ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
     #define AUTOSEEK_C          (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
@@ -586,9 +588,8 @@ void TDStretch::setTempo(double 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);
+    if (!verifyNumberOfChannels(numChannels) ||
+        (channels == numChannels)) return;
 
     channels = numChannels;
     inputBuffer.setChannels(channels);
@@ -637,7 +638,8 @@ void TDStretch::processNominalTempo()
 // the result into 'outputBuffer'
 void TDStretch::processSamples()
 {
-    int ovlSkip, offset;
+    int ovlSkip;
+    int offset = 0;
     int temp;
 
     /* Removed this small optimization - can introduce a click to sound when tempo setting
@@ -654,35 +656,61 @@ void TDStretch::processSamples()
     // to form a processing frame.
     while ((int)inputBuffer.numSamples() >= sampleReq) 
     {
-        // If tempo differs from the normal ('SCALE'), scan for the best overlapping
-        // position
-        offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
-
-        // Mix the samples in the 'inputBuffer' at position of 'offset' with the 
-        // samples in 'midBuffer' using sliding overlapping
-        // ... first partially overlap with the end of the previous sequence
-        // (that's in 'midBuffer')
-        overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
-        outputBuffer.putSamples((uint)overlapLength);
+        if (isBeginning == false)
+        {
+            // apart from the very beginning of the track, 
+            // scan for the best overlapping position & do overlap-add
+            offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
+
+            // Mix the samples in the 'inputBuffer' at position of 'offset' with the 
+            // samples in 'midBuffer' using sliding overlapping
+            // ... first partially overlap with the end of the previous sequence
+            // (that's in 'midBuffer')
+            overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
+            outputBuffer.putSamples((uint)overlapLength);
+            offset += overlapLength;
+        }
+        else
+        {
+            // Adjust processing offset at beginning of track by not perform initial overlapping
+            // and compensating that in the 'input buffer skip' calculation
+            isBeginning = false;
+            int skip = (int)(tempo * overlapLength + 0.5);
+
+            #ifdef SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
+                #ifdef SOUNDTOUCH_ALLOW_SSE
+                // if SSE mode, round the skip amount to value corresponding to aligned memory address
+                if (channels == 1)
+                {
+                    skip &= -4;
+                }
+                else if (channels == 2)
+                {
+                    skip &= -2;
+                }
+                #endif
+            #endif
+            skipFract -= skip;
+            assert(nominalSkip >= -skipFract);
+        }
 
         // ... then copy sequence samples from 'inputBuffer' to output:
 
-        // length of sequence
-        temp = (seekWindowLength - 2 * overlapLength);
-
         // crosscheck that we don't have buffer overflow...
-        if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
+        if ((int)inputBuffer.numSamples() < (offset + seekWindowLength - overlapLength))
         {
             continue;    // just in case, shouldn't really happen
         }
 
-        outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
+        // length of sequence
+        temp = (seekWindowLength - 2 * overlapLength);
+        outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * offset, (uint)temp);
 
         // Copies the end of the current sequence from 'inputBuffer' to 
         // 'midBuffer' for being mixed with the beginning of the next 
         // processing sequence and so on
-        assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
-        memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength), 
+        assert((offset + temp + overlapLength) <= (int)inputBuffer.numSamples());
+        memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp), 
             channels * sizeof(SAMPLETYPE) * overlapLength);
 
         // Remove the processed samples from the input buffer. Update
@@ -776,7 +804,7 @@ TDStretch * TDStretch::newInstance()
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// Integer arithmetics specific algorithm implementations.
+// Integer arithmetic specific algorithm implementations.
 //
 //////////////////////////////////////////////////////////////////////////////
 
@@ -879,7 +907,12 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do
 
     if (lnorm > maxnorm)
     {
-        maxnorm = lnorm;
+        // modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
+        #pragma omp critical
+        if (lnorm > maxnorm)
+        {
+            maxnorm = lnorm;
+        }
     }
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
     // done using floating point operation
@@ -936,7 +969,7 @@ double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *c
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// Floating point arithmetics specific algorithm implementations.
+// Floating point arithmetic specific algorithm implementations.
 //
 
 #ifdef SOUNDTOUCH_FLOAT_SAMPLES
diff --git a/Externals/soundtouch/TDStretch.h b/Externals/soundtouch/TDStretch.h
index 213304c982e..4118f9f474c 100644
--- a/Externals/soundtouch/TDStretch.h
+++ b/Externals/soundtouch/TDStretch.h
@@ -13,13 +13,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: TDStretch.h 226 2015-08-08 21:00:15Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -134,6 +127,7 @@ class TDStretch : public FIFOProcessor
     bool bQuickSeek;
     bool bAutoSeqSetting;
     bool bAutoSeekSetting;
+    bool isBeginning;
 
     SAMPLETYPE *pMidBuffer;
     SAMPLETYPE *pMidBufferUnaligned;
@@ -163,7 +157,6 @@ class TDStretch : public FIFOProcessor
     void calcSeqParameters();
     void adaptNormalizer();
 
-
     /// Changes the tempo of the given sound samples.
     /// Returns amount of samples returned in the "output" buffer.
     /// The maximum amount of samples that can be returned at a time is set by
@@ -247,8 +240,13 @@ class TDStretch : public FIFOProcessor
     {
         return seekWindowLength - overlapLength;
     }
-};
 
+	/// return approximate initial input-output latency
+	int getLatency() const
+	{
+		return sampleReq;
+	}
+};
 
 
 // Implementation-specific class declarations:
diff --git a/Externals/soundtouch/cpu_detect.h b/Externals/soundtouch/cpu_detect.h
index 025781dae1c..0cdc22356f9 100644
--- a/Externals/soundtouch/cpu_detect.h
+++ b/Externals/soundtouch/cpu_detect.h
@@ -12,13 +12,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
-// File revision : $Revision: 4 $
-//
-// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
diff --git a/Externals/soundtouch/cpu_detect_x86.cpp b/Externals/soundtouch/cpu_detect_x86.cpp
index 5ef0246216d..b1286106ebc 100644
--- a/Externals/soundtouch/cpu_detect_x86.cpp
+++ b/Externals/soundtouch/cpu_detect_x86.cpp
@@ -11,13 +11,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2014-01-07 20:24:28 +0200 (Tue, 07 Jan 2014) $
-// File revision : $Revision: 4 $
-//
-// $Id: cpu_detect_x86.cpp 183 2014-01-07 18:24:28Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -75,7 +68,6 @@ void disableExtensions(uint dwDisableMask)
 }
 
 
-
 /// Checks which instruction set extensions are supported by the CPU.
 uint detectCPUextensions(void)
 {
diff --git a/Externals/soundtouch/mmx_optimized.cpp b/Externals/soundtouch/mmx_optimized.cpp
index 8ad2811b9a1..741ba4f22e5 100644
--- a/Externals/soundtouch/mmx_optimized.cpp
+++ b/Externals/soundtouch/mmx_optimized.cpp
@@ -20,13 +20,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: mmx_optimized.cpp 226 2015-08-08 21:00:15Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library
@@ -125,7 +118,12 @@ double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &d
 
     if (norm > (long)maxnorm)
     {
-        maxnorm = norm;
+        // modify 'maxnorm' inside critical section to avoid multi-access conflict if in OpenMP mode
+        #pragma omp critical
+        if (norm > (long)maxnorm)
+        {
+            maxnorm = norm;
+        }
     }
 
     // Normalize result by dividing by sqrt(norm) - this step is easiest 
@@ -219,7 +217,6 @@ void TDStretchMMX::clearCrossCorrState()
 }
 
 
-
 // MMX-optimized version of the function overlapStereo
 void TDStretchMMX::overlapStereo(short *output, const short *input) const
 {
@@ -335,7 +332,6 @@ void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uRe
 }
 
 
-
 // mmx-optimized version of the filter routine for stereo sound
 uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numSamples) const
 {
@@ -392,4 +388,9 @@ uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numS
     return (numSamples & 0xfffffffe) - length;
 }
 
+#else
+
+// workaround to not complain about empty module
+bool _dontcomplain_mmx_empty;
+
 #endif  // SOUNDTOUCH_ALLOW_MMX
diff --git a/Externals/soundtouch/soundtouch_config.h b/Externals/soundtouch/soundtouch_config.h
new file mode 100644
index 00000000000..950e3353e25
--- /dev/null
+++ b/Externals/soundtouch/soundtouch_config.h
@@ -0,0 +1,2 @@
+#define SOUNDTOUCH_INTEGER_SAMPLES     1    //< 16bit integer samples
+//#define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples
diff --git a/Externals/soundtouch/sse_optimized.cpp b/Externals/soundtouch/sse_optimized.cpp
index 490d0d20809..0dc637015f9 100644
--- a/Externals/soundtouch/sse_optimized.cpp
+++ b/Externals/soundtouch/sse_optimized.cpp
@@ -23,13 +23,6 @@
 ///
 ////////////////////////////////////////////////////////////////////////////////
 //
-// Last changed  : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
-// File revision : $Revision: 4 $
-//
-// $Id: sse_optimized.cpp 226 2015-08-08 21:00:15Z oparviai $
-//
-////////////////////////////////////////////////////////////////////////////////
-//
 // License :
 //
 //  SoundTouch audio processing library

From 91a79d1b6302921fcb0de4bd33991a7570761572 Mon Sep 17 00:00:00 2001
From: Mystro256 <alexjnewt@hotmail.com>
Date: Sun, 5 Apr 2020 11:03:31 -0400
Subject: [PATCH 2/4] soundtouch: Use shorts instead of floats for samples

This reapplies commit 8ff26a6 after the soundtouch 2.1.2 update.
---
 Externals/soundtouch/STTypes.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Externals/soundtouch/STTypes.h b/Externals/soundtouch/STTypes.h
index 862505e7691..0f98c889fb6 100644
--- a/Externals/soundtouch/STTypes.h
+++ b/Externals/soundtouch/STTypes.h
@@ -94,8 +94,8 @@ namespace soundtouch
         ///   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_INTEGER_SAMPLES     1    //< 16bit integer samples
+        //#define SOUNDTOUCH_FLOAT_SAMPLES       1    //< 32bit float samples
      
     #endif
 
@@ -106,7 +106,7 @@ namespace soundtouch
         /// routines compiled for whatever reason, you may disable these optimizations 
         /// to make the library compile.
 
-        #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS     1
+        //#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS     1
 
         /// In GNU environment, allow the user to override this setting by
         /// giving the following switch to the configure script:

From a774373952b1da4b4758f8d816453fcb619da6d1 Mon Sep 17 00:00:00 2001
From: Mystro256 <alexjnewt@hotmail.com>
Date: Sun, 5 Apr 2020 17:46:52 -0400
Subject: [PATCH 3/4] soundtounch: disable exceptions

---
 Externals/soundtouch/STTypes.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Externals/soundtouch/STTypes.h b/Externals/soundtouch/STTypes.h
index 0f98c889fb6..d5440c3b74b 100644
--- a/Externals/soundtouch/STTypes.h
+++ b/Externals/soundtouch/STTypes.h
@@ -162,7 +162,7 @@ namespace soundtouch
 };
 
 // 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>

From 32d3506561ee3d9cd74fe2d2d280f0eddc7cdc34 Mon Sep 17 00:00:00 2001
From: Mystro256 <alexjnewt@hotmail.com>
Date: Thu, 17 Dec 2020 14:06:38 -0500
Subject: [PATCH 4/4] Fix soundtouch warning

See upstream fix:
https://gitlab.com/soundtouch/soundtouch/-/merge_requests/7/
---
 Externals/soundtouch/BPMDetect.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Externals/soundtouch/BPMDetect.cpp b/Externals/soundtouch/BPMDetect.cpp
index 5ad19269dd0..72a9498faf4 100644
--- a/Externals/soundtouch/BPMDetect.cpp
+++ b/Externals/soundtouch/BPMDetect.cpp
@@ -561,7 +561,7 @@ float BPMDetect::getBpm()
 /// \return number of beats in the arrays.
 int BPMDetect::getBeats(float *pos, float *values, int max_num)
 {
-    int num = beats.size();
+    int num = (int)beats.size();
     if ((!pos) || (!values)) return num;    // pos or values NULL, return just size
 
     for (int i = 0; (i < num) && (i < max_num); i++)