diff --git a/3rdparty/soundtouch/README.html b/3rdparty/soundtouch/README.html index 0221b0f26a..944f46be19 100644 --- a/3rdparty/soundtouch/README.html +++ b/3rdparty/soundtouch/README.html @@ -1,859 +1,874 @@ - - - - SoundTouch library README - - - - - - - -
-

SoundTouch audio processing library v1.9

-

SoundTouch library Copyright © Olli Parviainen 2001-2015

-
-

1. Introduction

-

SoundTouch is an open-source audio processing library that allows -changing the sound tempo, pitch and playback rate parameters -independently from each other, i.e.:

- -

1.1 Contact information

-

Author email: oparviai 'at' iki.fi

-

SoundTouch WWW page: http://soundtouch.surina.net

-
-

2. Compiling SoundTouch

-

Before compiling, notice that you can choose the sample data format if it's -desirable to use floating point sample data instead of 16bit integers. See -section "sample data format" for more information.

-

Also notice that SoundTouch can use OpenMP instructions for parallel -computation to accelerate the runtime processing speed in multi-core systems, -however, these improvements need to be separately enabled before compiling. See -OpenMP notes in Chapter 3 below.

-

2.1. Building in Microsoft Windows

-

Project files for Microsoft Visual C++ are supplied with the source -code package. Go to Microsoft WWW page to download - -Microsoft Visual Studio Express version for free. -

-

To build the binaries with Visual C++ compiler, either run -"make-win.bat" script, or open the appropriate project files in source -code directories with Visual Studio. The final executable will appear -under the "SoundTouch\bin" directory. If using the Visual Studio IDE -instead of the make-win.bat script, directories bin and lib may need to -be created manually to the SoundTouch package root for the final -executables. The make-win.bat script creates these directories -automatically.

-

OpenMP NOTE: If activating the OpenMP parallel computing in -the compilation, the target program will require additional vcomp dll library to -properly run. In Visual C++ 9.0 these libraries can be found in the following -folders.

- -

In Visual Studio 2008, a SP1 version may be required for these libraries. In -other VC++ versions the required library will be expectedly found in similar -"redist" location.

-

Notice that as minor demonstration of a "dll hell" phenomenon both the 32-bit -and 64-bit version of vcomp90.dll have the same filename but different contents, -thus choose the proper version to allow the program start.

-

2.2. Building in Gnu platforms

-

The SoundTouch library compiles in practically any platform -supporting GNU compiler (GCC) tools. SoundTouch requires GCC version 4.3 or later.

-

To build and install the binaries, run the following commands in -/soundtouch directory:

- - - - - - - - - - - - - - - - - - - -
-
./bootstrap  -
-
Creates "configure" file with -local autoconf/automake toolset.
-
-
./configure  -
-
-

Configures the SoundTouch package for the local environment. -Notice that "configure" file is not available before running the -"./bootstrap" command as above.
-

-
-
make         -
-
-

Builds the SoundTouch library & SoundStretch utility. You can - optionally add "-j" switch after "make" to speed up the compilation in - multi-core systems.

-
-
make install -
-
-

Installs the SoundTouch & BPM libraries to /usr/local/lib -and SoundStretch utility to /usr/local/bin. Please notice that -'root' privileges may be required to install the binaries to the -destination locations.

-
-

2.2.1 Required GNU tools 

-

Bash shell, GNU C++ compiler, libtool, autoconf and automake tools -are required for compiling the SoundTouch library. These are usually -included with the GNU/Linux distribution, but if not, install these -packages first. For example, Ubuntu Linux can acquire and install -these with the following command:

-
sudo apt-get install automake autoconf libtool build-essential
-

2.2.2 Problems with GCC compiler compatibility

-

At the release time the SoundTouch package has been tested to -compile in GNU/Linux platform. However, If you have problems getting the -SoundTouch library compiled, try disabling optimizations that are specific for -x86 processors by running ./configure script with switch -

-
--enable-x86-optimizations=no
-
- -Alternatively, if you don't use GNU Configure system, edit file "include/STTypes.h" -directly and remove the following definition:
-
#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1
-
- -

2.2.3 Compiling Shared Library / DLL version in Cygwin

-

- The GNU compilation does not automatically create a shared-library version of - SoundTouch (.so or .dll). If such is desired, then you can create it as follows - after running the usual compilation:

-
-
g++ -shared -static -DDLL_EXPORTS -I../../include -o SoundTouch.dll \
-     SoundTouchDLL.cpp ../SoundTouch/.libs/libSoundTouch.a
-sstrip SoundTouch.dll
-
- -

2.1. Building in Android

-

Android compilation instructions are within the - source code package, see file "source/Android-lib/README-SoundTouch-Android.html" - in the source code package.

-

The Android compilation automatically builds separate .so library binaries -for ARM, X86 and MIPS processor architectures. For optimal device support, -include all these .so library binaries into the Android .apk application -package, so the target Android device can automatically choose the proper -library binary version to use.

-

The source/Android-lib folder includes also an Android -example application that processes WAV audio files using SoundTouch library in -Android devices.

- -
-

3. About implementation & Usage tips

3.1. Supported sample data formats

-

The sample data format can be chosen between 16bit signed integer -and 32bit floating point values, the default is 32bit floating point.

-

In Windows environment, the sample data format is chosen in file -"STTypes.h" by choosing one of the following defines:

- -

In GNU environment, the floating sample format is used by default, -but integer sample format can be chosen by giving the following switch -to the configure script:

-
-
./configure --enable-integer-samples
-
-

The sample data can have either single (mono) or double (stereo) -audio channel. Stereo data is interleaved so that every other data -value is for left channel and every second for right channel. Notice -that while it'd be possible in theory to process stereo sound as two -separate mono channels, this isn't recommended because processing the -channels separately would result in losing the phase coherency between -the channels, which consequently would ruin the stereo effect.

-

Sample rates between 8000-48000H are supported.

-

3.2. Processing latency

-

The processing and latency constraints of the SoundTouch library are:

- -

3.3. About algorithms

-

SoundTouch provides three seemingly independent effects: tempo, -pitch and playback rate control. These three controls are implemented -as combination of two primary effects, sample rate transposing -and time-stretching.

-

Sample rate transposing affects both the audio stream -duration and pitch. It's implemented simply by converting the original -audio sample stream to the  desired duration by interpolating from -the original audio samples. In SoundTouch, linear interpolation with -anti-alias filtering is used. Theoretically a higher-order -interpolation provide better result than 1st order linear -interpolation, but in audio application linear interpolation together -with anti-alias filtering performs subjectively about as well as -higher-order filtering would.

-

Time-stretching means changing the audio stream duration -without affecting it's pitch. SoundTouch uses WSOLA-like -time-stretching routines that operate in the time domain. Compared to -sample rate transposing, time-stretching is a much heavier operation -and also requires a longer processing "window" of sound samples used by -the processing algorithm, thus increasing the algorithm input/output -latency. Typical i/o latency for the SoundTouch time-stretch algorithm -is around 100 ms.

-

Sample rate transposing and time-stretching are then used together -to produce the tempo, pitch and rate controls:

- -

3.4 Tuning the algorithm parameters

-

The time-stretch algorithm has few parameters that can be tuned to -optimize sound quality for certain application. The current default -parameters have been chosen by iterative if-then analysis (read: "trial -and error") to obtain best subjective sound quality in pop/rock music -processing, but in applications processing different kind of sound the -default parameter set may result into a sub-optimal result.

-

The time-stretch algorithm default parameter values are set by the -following #defines in file "TDStretch.h":

-
-
#define DEFAULT_SEQUENCE_MS     AUTOMATIC
#define DEFAULT_SEEKWINDOW_MS AUTOMATIC
#define DEFAULT_OVERLAP_MS 8
-
-

These parameters affect to the time-stretch algorithm as follows:

- -

Notice that these parameters can also be set during execution time -with functions "TDStretch::setParameters()" and "SoundTouch::setSetting()".

-

The table below summaries how the parameters can be adjusted for -different applications:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter nameDefault value magnitudeLarger value affects...Smaller value affects...Effect to CPU burden
-
SEQUENCE_MS
-
Default value is relatively large, chosen for -slowing down music tempoLarger value is usually better for slowing down -tempo. Growing the value decelerates the "echoing" artifact when -slowing down the tempo.Smaller value might be better for speeding up -tempo. Reducing the value accelerates the "echoing" artifact when -slowing down the tempo Increasing the parameter value reduces -computation burden
-
SEEKWINDOW_MS
-
Default value is relatively large, chosen for -slowing down music tempoLarger value eases finding a good mixing -position, but may cause a "drifting" artifactSmaller reduce possibility to find a good mixing -position, but reduce the "drifting" artifact.Increasing the parameter value increases -computation burden
-
OVERLAP_MS
-
Default value is relatively large, chosen to -suit with above parameters. If you reduce the "sequence ms" setting, you -might wish to try a smaller value.Increasing the parameter value increases -computation burden
-

3.5 Performance Optimizations

-

General optimizations:

-

The time-stretch routine has a 'quick' mode that substantially -speeds up the algorithm but may degrade the sound quality by a small -amount. This mode is activated by calling SoundTouch::setSetting() -function with parameter  id of SETTING_USE_QUICKSEEK and value -"1", i.e.

-
-

setSetting(SETTING_USE_QUICKSEEK, 1);

-
-

CPU-specific optimizations:

-

Intel x86 specific SIMD optimizations are implemented using compiler -intrinsics, providing about a 3x processing speedup for x86 compatible -processors vs. non-SIMD implementation:

- -

3.5 OpenMP parallel computation

-

SoundTouch 1.9 onwards support running the algorithms parallel in several CPU -cores. Based on benchmark the experienced multi-core processing speed-up gain -ranges between +30% (on a high-spec dual-core x86 Windows PC) to 215% (on a moderately low-spec -quad-core ARM of Raspberry Pi2).

-

The parallel computing support is implemented using OpenMP spec 3.0 -instructions. These instructions are supported by Visual C++ 2008 and later, and -GCC v4.2 and later. Compilers that do not supporting OpenMP will ignore these -optimizations and routines will still work properly. Possible warnings about -unknown #pragmas are related to OpenMP support and can be safely ignored.

-

The OpenMP improvements are disabled by default, and need to be enabled by -developer during compile-time. Reason for this is that parallel processing adds -moderate runtime overhead in managing the multi-threading, so it may not be -necessary nor desirable in all applications. For example real-time processing -that is not constrained by CPU power will not benefit of speed-up provided by -the parallel processing, in the contrary it may increase power consumption due -to the increased overhead.

-

However, applications that run on low-spec multi-core CPUs and may otherwise -have possibly constrained performance will benefit of the OpenMP improvements. -This include for example multi-core embedded devices.

-

OpenMP parallel computation can be enabled before compiling SoundTouch -library as follows:

- -
-

4. SoundStretch audio processing utility -

-

SoundStretch audio processing utility
- Copyright (c) Olli Parviainen 2002-2015

-

SoundStretch is a simple command-line application that can change -tempo, pitch and playback rates of WAV sound files. This program is -intended primarily to demonstrate how the "SoundTouch" library can be -used to process sound in your own program, but it can as well be used -for processing sound files.

-

4.1. SoundStretch Usage Instructions

-

SoundStretch Usage syntax:

-
-
soundstretch infilename outfilename [switches]
-
-

Where:

- - - - - - - - - - - - - - - -
-
"infilename"
-
Name of the input sound data file (in .WAV audio -file format). Give "stdin" as filename to use standard input pipe.
-
"outfilename"
-
Name of the output sound file where the -resulting sound is saved (in .WAV audio file format). This parameter -may be omitted if you  don't want to save the output (e.g. when -only calculating BPM rate with '-bpm' switch). Give "stdout" as -filename to use standard output pipe.
-
 [switches]
-
Are one or more control switches.
-

Available control switches are:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-tempo=n 
-
Change the sound tempo by n percents (n = -95.0 -.. +5000.0 %)
-
-pitch=n
-
Change the sound pitch by n semitones (n = -60.0 -.. + 60.0 semitones)
-
-rate=n
-
Change the sound playback rate by n percents (n -= -95.0 .. +5000.0 %)
-
-bpm=n
-
Detect the Beats-Per-Minute (BPM) rate of the -sound and adjust the tempo to meet 'n' BPMs. When this switch is -applied, the "-tempo" switch is ignored. If "=n" is omitted, i.e. -switch "-bpm" is used alone, then the BPM rate is estimated and -displayed, but tempo not adjusted according to the BPM value.
-
-quick
-
Use quicker tempo change algorithm. Gains speed -but loses sound quality.
-
-naa
-
Don't use anti-alias filtering in sample rate -transposing. Gains speed but loses sound quality.
-
-license
-
Displays the program license text (LGPL)
-

Notes:

- -

4.2. SoundStretch usage examples

-

Example 1

-

The following command increases tempo of the sound file -"originalfile.wav" by 12.5% and stores result to file -"destinationfile.wav":

-
-
soundstretch originalfile.wav destinationfile.wav -tempo=12.5
-
-

Example 2

-

The following command decreases the sound pitch (key) of the sound -file "orig.wav" by two semitones and stores the result to file -"dest.wav":

-
-
soundstretch orig.wav dest.wav -pitch=-2
-
-

Example 3

-

The following command processes the file "orig.wav" by decreasing -the sound tempo by 25.3% and increasing the sound pitch (key) by 1.5 -semitones. Resulting .wav audio data is directed to standard output -pipe:

-
-
soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5
-
-

Example 4

-

The following command detects the BPM rate of the file "orig.wav" -and adjusts the tempo to match 100 beats per minute. Result is stored -to file "dest.wav":

-
-
soundstretch orig.wav dest.wav -bpm=100
-
-

Example 5

-

The following command reads .wav sound data from standard input pipe -and estimates the BPM rate:

-
-
soundstretch stdin -bpm
-
-

Example 6

-

The following command tunes song from original 440Hz tuning to 432Hz tuning: -this corresponds to lowering the pitch by -0.318 semitones:

-
-
soundstretch original.wav output.wav -pitch=-0.318
-
-
-

5. Change History

-

5.1. SoundTouch library Change History

-

1.9:

- -

1.8.0:

- -

1.7.1:

- -

1.7.0:

- -

1.6.0:

- -

1.5.0:

- -

1.4.1:

- -

1.4.0:

- -

1.3.1:

- -

1.3.0:

- -

1.2.1:

- -

1.2.0:

- -

1.1.1:

- -

1.0.1:

- -

1.0:

- -

 

-

5.2. SoundStretch application Change History

-

1.9:

- - -

1.7.0:

- -

1.5.0:

- -

1.4.0:

- -

1.3.0:

- -

1.2.1:

- -

1.2.0:

- -

1.1.1:

- -

1.1:

- -

1.01:

- -
-

6. Acknowledgements

-

Kudos for these people who have contributed to development or -submitted bugfixes:

- -

Moral greetings to all other contributors and users also!

-
-

7. 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 version 2.1 -as published by the Free Software Foundation.

-

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

-
-

- README.html file updated in May-2015

- - + + + + SoundTouch library README + + + + + + + +
+

SoundTouch audio processing library v1.9.2

+

SoundTouch library Copyright © Olli Parviainen 2001-2015

+
+

1. Introduction

+

SoundTouch is an open-source audio processing library that allows +changing the sound tempo, pitch and playback rate parameters +independently from each other, i.e.:

+ +

1.1 Contact information

+

Author email: oparviai 'at' iki.fi

+

SoundTouch WWW page: http://soundtouch.surina.net

+
+

2. Compiling SoundTouch

+

Before compiling, notice that you can choose the sample data format if it's +desirable to use floating point sample data instead of 16bit integers. See +section "sample data format" for more information.

+

Also notice that SoundTouch can use OpenMP instructions for parallel +computation to accelerate the runtime processing speed in multi-core systems, +however, these improvements need to be separately enabled before compiling. See +OpenMP notes in Chapter 3 below.

+

2.1. Building in Microsoft Windows

+

Project files for Microsoft Visual C++ are supplied with the source +code package. Go to Microsoft WWW page to download + +Microsoft Visual Studio Express version for free. +

+

To build the binaries with Visual C++ compiler, either run +"make-win.bat" script, or open the appropriate project files in source +code directories with Visual Studio. The final executable will appear +under the "SoundTouch\bin" directory. If using the Visual Studio IDE +instead of the make-win.bat script, directories bin and lib may need to +be created manually to the SoundTouch package root for the final +executables. The make-win.bat script creates these directories +automatically.

+

OpenMP NOTE: If activating the OpenMP parallel computing in +the compilation, the target program will require additional vcomp dll library to +properly run. In Visual C++ 9.0 these libraries can be found in the following +folders.

+ +

In Visual Studio 2008, a SP1 version may be required for these libraries. In +other VC++ versions the required library will be expectedly found in similar +"redist" location.

+

Notice that as minor demonstration of a "dll hell" phenomenon both the 32-bit +and 64-bit version of vcomp90.dll have the same filename but different contents, +thus choose the proper version to allow the program start.

+

2.2. Building in Gnu platforms

+

The SoundTouch library compiles in practically any platform +supporting GNU compiler (GCC) tools. SoundTouch requires GCC version 4.3 or later.

+

To build and install the binaries, run the following commands in +/soundtouch directory:

+ + + + + + + + + + + + + + + + + + + +
+
./bootstrap  -
+
Creates "configure" file with +local autoconf/automake toolset.
+
+
./configure  -
+
+

Configures the SoundTouch package for the local environment. +Notice that "configure" file is not available before running the +"./bootstrap" command as above.
+

+
+
make         -
+
+

Builds the SoundTouch library & SoundStretch utility. You can + optionally add "-j" switch after "make" to speed up the compilation in + multi-core systems.

+
+
make install -
+
+

Installs the SoundTouch & BPM libraries to /usr/local/lib +and SoundStretch utility to /usr/local/bin. Please notice that +'root' privileges may be required to install the binaries to the +destination locations.

+
+

2.2.1 Required GNU tools 

+

Bash shell, GNU C++ compiler, libtool, autoconf and automake tools +are required for compiling the SoundTouch library. These are usually +included with the GNU/Linux distribution, but if not, install these +packages first. For example, Ubuntu Linux can acquire and install +these with the following command:

+
sudo apt-get install automake autoconf libtool build-essential
+

2.2.2 Problems with GCC compiler compatibility

+

At the release time the SoundTouch package has been tested to +compile in GNU/Linux platform. However, If you have problems getting the +SoundTouch library compiled, try disabling optimizations that are specific for +x86 processors by running ./configure script with switch +

+
--enable-x86-optimizations=no
+
+ +Alternatively, if you don't use GNU Configure system, edit file "include/STTypes.h" +directly and remove the following definition:
+
#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1
+
+ +

2.2.3 Compiling Shared Library / DLL version in Cygwin

+

+ The GNU compilation does not automatically create a shared-library version of + SoundTouch (.so or .dll). If such is desired, then you can create it as follows + after running the usual compilation:

+
+
g++ -shared -static -DDLL_EXPORTS -I../../include -o SoundTouch.dll \
+     SoundTouchDLL.cpp ../SoundTouch/.libs/libSoundTouch.a
+sstrip SoundTouch.dll
+
+ +

2.1. Building in Android

+

Android compilation instructions are within the + source code package, see file "source/Android-lib/README-SoundTouch-Android.html" + in the source code package.

+

The Android compilation automatically builds separate .so library binaries +for ARM, X86 and MIPS processor architectures. For optimal device support, +include all these .so library binaries into the Android .apk application +package, so the target Android device can automatically choose the proper +library binary version to use.

+

The source/Android-lib folder includes also an Android +example application that processes WAV audio files using SoundTouch library in +Android devices.

+ +
+

3. About implementation & Usage tips

3.1. Supported sample data formats

+

The sample data format can be chosen between 16bit signed integer +and 32bit floating point values. The default is 32bit floating point format, +which will also provide slightly better sound quality over the integer format.

+

In Windows environment, the sample data format is chosen in file +"STTypes.h" by choosing one of the following defines:

+ +

In GNU environment, the floating sample format is used by default, +but integer sample format can be chosen by giving the following switch +to the configure script:

+
+
./configure --enable-integer-samples
+
+

The sample data can have either single (mono) or double (stereo) +audio channel. Stereo data is interleaved so that every other data +value is for left channel and every second for right channel. Notice +that while it'd be possible in theory to process stereo sound as two +separate mono channels, this isn't recommended because processing the +channels separately would result in losing the phase coherency between +the channels, which consequently would ruin the stereo effect.

+

Sample rates between 8000-48000H are supported.

+

3.2. Processing latency

+

The processing and latency constraints of the SoundTouch library are:

+ +

3.3. About algorithms

+

SoundTouch provides three seemingly independent effects: tempo, +pitch and playback rate control. These three controls are implemented +as combination of two primary effects, sample rate transposing +and time-stretching.

+

Sample rate transposing affects both the audio stream +duration and pitch. It's implemented simply by converting the original +audio sample stream to the  desired duration by interpolating from +the original audio samples. In SoundTouch, linear interpolation with +anti-alias filtering is used. Theoretically a higher-order +interpolation provide better result than 1st order linear +interpolation, but in audio application linear interpolation together +with anti-alias filtering performs subjectively about as well as +higher-order filtering would.

+

Time-stretching means changing the audio stream duration +without affecting it's pitch. SoundTouch uses WSOLA-like +time-stretching routines that operate in the time domain. Compared to +sample rate transposing, time-stretching is a much heavier operation +and also requires a longer processing "window" of sound samples used by +the processing algorithm, thus increasing the algorithm input/output +latency. Typical i/o latency for the SoundTouch time-stretch algorithm +is around 100 ms.

+

Sample rate transposing and time-stretching are then used together +to produce the tempo, pitch and rate controls:

+ +

3.4 Tuning the algorithm parameters

+

The time-stretch algorithm has few parameters that can be tuned to +optimize sound quality for certain application. The current default +parameters have been chosen by iterative if-then analysis (read: "trial +and error") to obtain best subjective sound quality in pop/rock music +processing, but in applications processing different kind of sound the +default parameter set may result into a sub-optimal result.

+

The time-stretch algorithm default parameter values are set by the +following #defines in file "TDStretch.h":

+
+
#define DEFAULT_SEQUENCE_MS     AUTOMATIC
#define DEFAULT_SEEKWINDOW_MS AUTOMATIC
#define DEFAULT_OVERLAP_MS 8
+
+

These parameters affect to the time-stretch algorithm as follows:

+ +

Notice that these parameters can also be set during execution time +with functions "TDStretch::setParameters()" and "SoundTouch::setSetting()".

+

The table below summaries how the parameters can be adjusted for +different applications:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault value magnitudeLarger value affects...Smaller value affects...Effect to CPU burden
+
SEQUENCE_MS
+
Default value is relatively large, chosen for +slowing down music tempoLarger value is usually better for slowing down +tempo. Growing the value decelerates the "echoing" artifact when +slowing down the tempo.Smaller value might be better for speeding up +tempo. Reducing the value accelerates the "echoing" artifact when +slowing down the tempo Increasing the parameter value reduces +computation burden
+
SEEKWINDOW_MS
+
Default value is relatively large, chosen for +slowing down music tempoLarger value eases finding a good mixing +position, but may cause a "drifting" artifactSmaller reduce possibility to find a good mixing +position, but reduce the "drifting" artifact.Increasing the parameter value increases +computation burden
+
OVERLAP_MS
+
Default value is relatively large, chosen to +suit with above parameters. If you reduce the "sequence ms" setting, you +might wish to try a smaller value.Increasing the parameter value increases +computation burden
+

3.5 Performance Optimizations

+

General optimizations:

+

The time-stretch routine has a 'quick' mode that substantially +speeds up the algorithm but may slightly compromise the sound quality. +This mode is activated by calling SoundTouch::setSetting() +function with parameter  id of SETTING_USE_QUICKSEEK and value +"1", i.e.

+
+

setSetting(SETTING_USE_QUICKSEEK, 1);

+
+

CPU-specific optimizations:

+

Intel x86 specific SIMD optimizations are implemented using compiler +intrinsics, providing about a 3x processing speedup for x86 compatible +processors vs. non-SIMD implementation:

+ +

3.5 OpenMP parallel computation

+

SoundTouch 1.9 onwards support running the algorithms parallel in several CPU +cores. Based on benchmark the experienced multi-core processing speed-up gain +ranges between +30% (on a high-spec dual-core x86 Windows PC) to 215% (on a moderately low-spec +quad-core ARM of Raspberry Pi2).

+

The parallel computing support is implemented using OpenMP spec 3.0 +instructions. These instructions are supported by Visual C++ 2008 and later, and +GCC v4.2 and later. Compilers that do not supporting OpenMP will ignore these +optimizations and routines will still work properly. Possible warnings about +unknown #pragmas are related to OpenMP support and can be safely ignored.

+

The OpenMP improvements are disabled by default, and need to be enabled by +developer during compile-time. Reason for this is that parallel processing adds +moderate runtime overhead in managing the multi-threading, so it may not be +necessary nor desirable in all applications. For example real-time processing +that is not constrained by CPU power will not benefit of speed-up provided by +the parallel processing, in the contrary it may increase power consumption due +to the increased overhead.

+

However, applications that run on low-spec multi-core CPUs and may otherwise +have possibly constrained performance will benefit of the OpenMP improvements. +This include for example multi-core embedded devices.

+

OpenMP parallel computation can be enabled before compiling SoundTouch +library as follows:

+ +
+

4. SoundStretch audio processing utility +

+

SoundStretch audio processing utility
+ Copyright (c) Olli Parviainen 2002-2015

+

SoundStretch is a simple command-line application that can change +tempo, pitch and playback rates of WAV sound files. This program is +intended primarily to demonstrate how the "SoundTouch" library can be +used to process sound in your own program, but it can as well be used +for processing sound files.

+

4.1. SoundStretch Usage Instructions

+

SoundStretch Usage syntax:

+
+
soundstretch infilename outfilename [switches]
+
+

Where:

+ + + + + + + + + + + + + + + +
+
"infilename"
+
Name of the input sound data file (in .WAV audio +file format). Give "stdin" as filename to use standard input pipe.
+
"outfilename"
+
Name of the output sound file where the +resulting sound is saved (in .WAV audio file format). This parameter +may be omitted if you  don't want to save the output (e.g. when +only calculating BPM rate with '-bpm' switch). Give "stdout" as +filename to use standard output pipe.
+
 [switches]
+
Are one or more control switches.
+

Available control switches are:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
-tempo=n 
+
Change the sound tempo by n percents (n = -95.0 +.. +5000.0 %)
+
-pitch=n
+
Change the sound pitch by n semitones (n = -60.0 +.. + 60.0 semitones)
+
-rate=n
+
Change the sound playback rate by n percents (n += -95.0 .. +5000.0 %)
+
-bpm=n
+
Detect the Beats-Per-Minute (BPM) rate of the +sound and adjust the tempo to meet 'n' BPMs. When this switch is +applied, the "-tempo" switch is ignored. If "=n" is omitted, i.e. +switch "-bpm" is used alone, then the BPM rate is estimated and +displayed, but tempo not adjusted according to the BPM value.
+
-quick
+
Use quicker tempo change algorithm. Gains speed +but loses sound quality.
+
-naa
+
Don't use anti-alias filtering in sample rate +transposing. Gains speed but loses sound quality.
+
-license
+
Displays the program license text (LGPL)
+

Notes:

+ +

4.2. SoundStretch usage examples

+

Example 1

+

The following command increases tempo of the sound file +"originalfile.wav" by 12.5% and stores result to file +"destinationfile.wav":

+
+
soundstretch originalfile.wav destinationfile.wav -tempo=12.5
+
+

Example 2

+

The following command decreases the sound pitch (key) of the sound +file "orig.wav" by two semitones and stores the result to file +"dest.wav":

+
+
soundstretch orig.wav dest.wav -pitch=-2
+
+

Example 3

+

The following command processes the file "orig.wav" by decreasing +the sound tempo by 25.3% and increasing the sound pitch (key) by 1.5 +semitones. Resulting .wav audio data is directed to standard output +pipe:

+
+
soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5
+
+

Example 4

+

The following command detects the BPM rate of the file "orig.wav" +and adjusts the tempo to match 100 beats per minute. Result is stored +to file "dest.wav":

+
+
soundstretch orig.wav dest.wav -bpm=100
+
+

Example 5

+

The following command reads .wav sound data from standard input pipe +and estimates the BPM rate:

+
+
soundstretch stdin -bpm
+
+

Example 6

+

The following command tunes song from original 440Hz tuning to 432Hz tuning: +this corresponds to lowering the pitch by -0.318 semitones:

+
+
soundstretch original.wav output.wav -pitch=-0.318
+
+
+

5. Change History

+

5.1. SoundTouch library Change History

+

1.9.2:

+ +

1.9.1:

+ +

1.9:

+ +

1.8.0:

+ +

1.7.1:

+ +

1.7.0:

+ +

1.6.0:

+ +

1.5.0:

+ +

1.4.1:

+ +

1.4.0:

+ +

1.3.1:

+ +

1.3.0:

+ +

1.2.1:

+ +

1.2.0:

+ +

1.1.1:

+ +

1.0.1:

+ +

1.0:

+ +

 

+

5.2. SoundStretch application Change History

+

1.9:

+ + +

1.7.0:

+ +

1.5.0:

+ +

1.4.0:

+ +

1.3.0:

+ +

1.2.1:

+ +

1.2.0:

+ +

1.1.1:

+ +

1.1:

+ +

1.01:

+ +
+

6. Acknowledgements

+

Kudos for these people who have contributed to development or +submitted bugfixes:

+ +

Moral greetings to all other contributors and users also!

+
+

7. 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 version 2.1 +as published by the Free Software Foundation.

+

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

+
+

+ README.html file updated in Sep-2015

+ + diff --git a/3rdparty/soundtouch/soundtouch/BPMDetect.h b/3rdparty/soundtouch/soundtouch/BPMDetect.h index 35ec5b6115..72489894bd 100644 --- a/3rdparty/soundtouch/soundtouch/BPMDetect.h +++ b/3rdparty/soundtouch/soundtouch/BPMDetect.h @@ -26,7 +26,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2012-08-30 19:53:44 +0000 (Thu, 30 Aug 2012) $ +// 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 $ diff --git a/3rdparty/soundtouch/soundtouch/FIFOSampleBuffer.h b/3rdparty/soundtouch/soundtouch/FIFOSampleBuffer.h index 6d2fd59f65..4b22a51e35 100644 --- a/3rdparty/soundtouch/soundtouch/FIFOSampleBuffer.h +++ b/3rdparty/soundtouch/soundtouch/FIFOSampleBuffer.h @@ -15,7 +15,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-01-05 21:40:22 +0000 (Sun, 05 Jan 2014) $ +// 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 $ diff --git a/3rdparty/soundtouch/soundtouch/FIFOSamplePipe.h b/3rdparty/soundtouch/soundtouch/FIFOSamplePipe.h index cd3191c1af..f26c57b0b2 100644 --- a/3rdparty/soundtouch/soundtouch/FIFOSamplePipe.h +++ b/3rdparty/soundtouch/soundtouch/FIFOSamplePipe.h @@ -17,7 +17,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2012-06-13 19:29:53 +0000 (Wed, 13 Jun 2012) $ +// 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 $ diff --git a/3rdparty/soundtouch/soundtouch/STTypes.h b/3rdparty/soundtouch/soundtouch/STTypes.h index 3f95947f5d..f3b405af01 100644 --- a/3rdparty/soundtouch/soundtouch/STTypes.h +++ b/3rdparty/soundtouch/soundtouch/STTypes.h @@ -8,7 +8,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-05-18 15:25:07 +0000 (Mon, 18 May 2015) $ +// 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 $ diff --git a/3rdparty/soundtouch/soundtouch/SoundTouch.h b/3rdparty/soundtouch/soundtouch/SoundTouch.h index f15c65c0e3..b03855eea7 100644 --- a/3rdparty/soundtouch/soundtouch/SoundTouch.h +++ b/3rdparty/soundtouch/soundtouch/SoundTouch.h @@ -41,10 +41,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-05-18 15:28:41 +0000 (Mon, 18 May 2015) $ +// Last changed : $Date: 2015-09-20 10:38:32 +0300 (Sun, 20 Sep 2015) $ // File revision : $Revision: 4 $ // -// $Id: SoundTouch.h 216 2015-05-18 15:28:41Z oparviai $ +// $Id: SoundTouch.h 230 2015-09-20 07:38:32Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -79,10 +79,10 @@ namespace soundtouch { /// Soundtouch library version string -#define SOUNDTOUCH_VERSION "1.9.0" +#define SOUNDTOUCH_VERSION "1.9.2" /// SoundTouch library version id -#define SOUNDTOUCH_VERSION_ID (10900) +#define SOUNDTOUCH_VERSION_ID (10902) // // Available setting IDs for the 'setSetting' & 'get_setting' functions: @@ -151,17 +151,24 @@ private: class TDStretch *pTDStretch; /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters. - float virtualRate; + double virtualRate; /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters. - float virtualTempo; + double virtualTempo; /// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters. - float virtualPitch; + double virtualPitch; /// Flag: Has sample rate been set? bool bSrateSet; + /// Accumulator for how many samples in total will be expected as output vs. samples put in, + /// considering current processing settings. + double samplesExpectedOut; + + /// Accumulator for how many samples in total have been read out from the processing so far + long samplesOutput; + /// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and /// 'virtualPitch' parameters. void calcEffectiveRateAndTempo(); @@ -171,10 +178,10 @@ protected : uint channels; /// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch' - float rate; + double rate; /// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch' - float tempo; + double tempo; public: SoundTouch(); @@ -188,32 +195,32 @@ public: /// Sets new rate control value. Normal rate = 1.0, smaller values /// represent slower rate, larger faster rates. - void setRate(float newRate); + void setRate(double newRate); /// Sets new tempo control value. Normal tempo = 1.0, smaller values /// represent slower tempo, larger faster tempo. - void setTempo(float newTempo); + void setTempo(double newTempo); /// Sets new rate control value as a difference in percents compared /// to the original rate (-50 .. +100 %) - void setRateChange(float newRate); + void setRateChange(double newRate); /// Sets new tempo control value as a difference in percents compared /// to the original tempo (-50 .. +100 %) - void setTempoChange(float newTempo); + void setTempoChange(double newTempo); /// Sets new pitch control value. Original pitch = 1.0, smaller values /// represent lower pitches, larger values higher pitch. - void setPitch(float newPitch); + void setPitch(double newPitch); /// Sets pitch change in octaves compared to the original pitch /// (-1.00 .. +1.00) - void setPitchOctaves(float newPitch); + void setPitchOctaves(double newPitch); /// Sets pitch change in semi-tones compared to the original pitch /// (-12 .. +12) void setPitchSemiTones(int newPitch); - void setPitchSemiTones(float newPitch); + void setPitchSemiTones(double newPitch); /// Sets the number of channels, 1 = mono, 2 = stereo void setChannels(uint numChannels); @@ -240,6 +247,23 @@ public: ///< contains data for both channels. ); + /// Output samples from beginning of the sample buffer. Copies requested samples to + /// output buffer and removes them from the sample buffer. If there are less than + /// 'numsample' samples in the buffer, returns all that available. + /// + /// \return Number of samples returned. + virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples. + uint maxSamples ///< How many samples to receive at max. + ); + + /// Adjusts book-keeping so that given number of samples are removed from beginning of the + /// sample buffer without copying them anywhere. + /// + /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly + /// with 'ptrBegin' function. + virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe. + ); + /// Clears all the samples in the object's output and internal processing /// buffers. virtual void clear(); diff --git a/3rdparty/soundtouch/source/SoundStretch/WavFile.cpp b/3rdparty/soundtouch/source/SoundStretch/WavFile.cpp index 22fbaf1b1b..da42ed37f5 100644 --- a/3rdparty/soundtouch/source/SoundStretch/WavFile.cpp +++ b/3rdparty/soundtouch/source/SoundStretch/WavFile.cpp @@ -17,7 +17,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-10-05 16:20:24 +0000 (Sun, 05 Oct 2014) $ +// Last changed : $Date: 2014-10-05 19:20:24 +0300 (Sun, 05 Oct 2014) $ // File revision : $Revision: 4 $ // // $Id: WavFile.cpp 200 2014-10-05 16:20:24Z oparviai $ diff --git a/3rdparty/soundtouch/source/SoundStretch/WavFile.h b/3rdparty/soundtouch/source/SoundStretch/WavFile.h index 2670e9ef4b..4ce9e9f498 100644 --- a/3rdparty/soundtouch/source/SoundStretch/WavFile.h +++ b/3rdparty/soundtouch/source/SoundStretch/WavFile.h @@ -16,7 +16,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-10-05 16:20:24 +0000 (Sun, 05 Oct 2014) $ +// Last changed : $Date: 2014-10-05 19:20:24 +0300 (Sun, 05 Oct 2014) $ // File revision : $Revision: 4 $ // // $Id: WavFile.h 200 2014-10-05 16:20:24Z oparviai $ diff --git a/3rdparty/soundtouch/source/SoundTouch/AAFilter.cpp b/3rdparty/soundtouch/source/SoundTouch/AAFilter.cpp index ac4ec20e14..a254300761 100644 --- a/3rdparty/soundtouch/source/SoundTouch/AAFilter.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/AAFilter.cpp @@ -12,7 +12,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-01-05 21:40:22 +0000 (Sun, 05 Jan 2014) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/AAFilter.h b/3rdparty/soundtouch/source/SoundTouch/AAFilter.h index f1b5f2a554..8c34b6b201 100644 --- a/3rdparty/soundtouch/source/SoundTouch/AAFilter.h +++ b/3rdparty/soundtouch/source/SoundTouch/AAFilter.h @@ -13,7 +13,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-01-07 19:41:23 +0000 (Tue, 07 Jan 2014) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/BPMDetect.cpp b/3rdparty/soundtouch/source/SoundTouch/BPMDetect.cpp index c17884266c..7e6fd9c4a4 100644 --- a/3rdparty/soundtouch/source/SoundTouch/BPMDetect.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/BPMDetect.cpp @@ -26,7 +26,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp b/3rdparty/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp index 4e75c8a433..4d9740ae6d 100644 --- a/3rdparty/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/FIFOSampleBuffer.cpp @@ -15,7 +15,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2012-11-08 18:53:01 +0000 (Thu, 08 Nov 2012) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/FIRFilter.cpp b/3rdparty/soundtouch/source/SoundTouch/FIRFilter.cpp index 4a1c23fdd2..456418a58c 100644 --- a/3rdparty/soundtouch/source/SoundTouch/FIRFilter.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/FIRFilter.cpp @@ -11,7 +11,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/FIRFilter.h b/3rdparty/soundtouch/source/SoundTouch/FIRFilter.h index 70ba97cfe5..158cdd2709 100644 --- a/3rdparty/soundtouch/source/SoundTouch/FIRFilter.h +++ b/3rdparty/soundtouch/source/SoundTouch/FIRFilter.h @@ -11,7 +11,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/InterpolateCubic.h b/3rdparty/soundtouch/source/SoundTouch/InterpolateCubic.h index e0e302b233..f98e701d7b 100644 --- a/3rdparty/soundtouch/source/SoundTouch/InterpolateCubic.h +++ b/3rdparty/soundtouch/source/SoundTouch/InterpolateCubic.h @@ -8,7 +8,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// $Id: InterpolateCubic.h 179 2014-01-06 18:41:42Z oparviai $ +// $Id: InterpolateCubic.h 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -56,7 +56,7 @@ protected: const SAMPLETYPE *src, int &srcSamples); - float fract; + double fract; public: InterpolateCubic(); diff --git a/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.cpp b/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.cpp index ae26e69a1e..8119813857 100644 --- a/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.cpp @@ -8,7 +8,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// $Id: InterpolateLinear.cpp 180 2014-01-06 19:16:02Z oparviai $ +// $Id: InterpolateLinear.cpp 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -170,9 +170,9 @@ int InterpolateLinearInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower // iRate, larger faster iRates. -void InterpolateLinearInteger::setRate(float newRate) +void InterpolateLinearInteger::setRate(double newRate) { - iRate = (int)(newRate * SCALE + 0.5f); + iRate = (int)(newRate * SCALE + 0.5); TransposerBase::setRate(newRate); } @@ -190,7 +190,7 @@ InterpolateLinearFloat::InterpolateLinearFloat() : TransposerBase() // Notice: use local function calling syntax for sake of clarity, // to indicate the fact that C++ constructor can't call virtual functions. resetRegisters(); - setRate(1.0f); + setRate(1.0); } @@ -275,12 +275,13 @@ int InterpolateLinearFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *s i = 0; while (srcCount < srcSampleEnd) { - float temp, vol1; + float temp, vol1, fract_float; - vol1 = (1.0f- fract); + vol1 = (float)(1.0 - fract); + fract_float = (float)fract; for (int c = 0; c < numChannels; c ++) { - temp = vol1 * src[c] + fract * src[c + numChannels]; + temp = vol1 * src[c] + fract_float * src[c + numChannels]; *dest = (SAMPLETYPE)temp; dest ++; } diff --git a/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.h b/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.h index b76299f889..6a7e11d18b 100644 --- a/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.h +++ b/3rdparty/soundtouch/source/SoundTouch/InterpolateLinear.h @@ -8,7 +8,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// $Id: InterpolateLinear.h 179 2014-01-06 18:41:42Z oparviai $ +// $Id: InterpolateLinear.h 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -63,7 +63,7 @@ public: /// Sets new target rate. Normal rate = 1.0, smaller values represent slower /// rate, larger faster rates. - virtual void setRate(float newRate); + virtual void setRate(double newRate); }; @@ -71,7 +71,7 @@ public: class InterpolateLinearFloat : public TransposerBase { protected: - float fract; + double fract; virtual void resetRegisters(); diff --git a/3rdparty/soundtouch/source/SoundTouch/InterpolateShannon.h b/3rdparty/soundtouch/source/SoundTouch/InterpolateShannon.h index 701640f7db..54703d9808 100644 --- a/3rdparty/soundtouch/source/SoundTouch/InterpolateShannon.h +++ b/3rdparty/soundtouch/source/SoundTouch/InterpolateShannon.h @@ -13,7 +13,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// $Id: InterpolateShannon.h 179 2014-01-06 18:41:42Z oparviai $ +// $Id: InterpolateShannon.h 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -61,7 +61,7 @@ protected: const SAMPLETYPE *src, int &srcSamples); - float fract; + double fract; public: InterpolateShannon(); diff --git a/3rdparty/soundtouch/source/SoundTouch/PeakFinder.cpp b/3rdparty/soundtouch/source/SoundTouch/PeakFinder.cpp index 3c4c1f518f..1a7290b0f1 100644 --- a/3rdparty/soundtouch/source/SoundTouch/PeakFinder.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/PeakFinder.cpp @@ -11,7 +11,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-05-18 15:22:02 +0000 (Mon, 18 May 2015) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/PeakFinder.h b/3rdparty/soundtouch/source/SoundTouch/PeakFinder.h index 0bd448fe70..d170b1c58b 100644 --- a/3rdparty/soundtouch/source/SoundTouch/PeakFinder.h +++ b/3rdparty/soundtouch/source/SoundTouch/PeakFinder.h @@ -9,7 +9,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2011-12-30 20:33:46 +0000 (Fri, 30 Dec 2011) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/RateTransposer.cpp b/3rdparty/soundtouch/source/SoundTouch/RateTransposer.cpp index f1e3fd043b..19e810131e 100644 --- a/3rdparty/soundtouch/source/SoundTouch/RateTransposer.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/RateTransposer.cpp @@ -10,10 +10,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $ +// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $ // File revision : $Revision: 4 $ // -// $Id: RateTransposer.cpp 195 2014-04-06 15:57:21Z oparviai $ +// $Id: RateTransposer.cpp 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -97,20 +97,20 @@ AAFilter *RateTransposer::getAAFilter() // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower // iRate, larger faster iRates. -void RateTransposer::setRate(float newRate) +void RateTransposer::setRate(double newRate) { double fCutoff; pTransposer->setRate(newRate); // design a new anti-alias filter - if (newRate > 1.0f) + if (newRate > 1.0) { - fCutoff = 0.5f / newRate; + fCutoff = 0.5 / newRate; } else { - fCutoff = 0.5f * newRate; + fCutoff = 0.5 * newRate; } pAAFilter->setCutoffFreq(fCutoff); } @@ -225,7 +225,7 @@ void TransposerBase::setAlgorithm(TransposerBase::ALGORITHM a) int TransposerBase::transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src) { int numSrcSamples = src.numSamples(); - int sizeDemand = (int)((float)numSrcSamples / rate) + 8; + int sizeDemand = (int)((double)numSrcSamples / rate) + 8; int numOutput; SAMPLETYPE *psrc = src.ptrBegin(); SAMPLETYPE *pdest = dest.ptrEnd(sizeDemand); @@ -270,7 +270,7 @@ void TransposerBase::setChannels(int channels) } -void TransposerBase::setRate(float newRate) +void TransposerBase::setRate(double newRate) { rate = newRate; } diff --git a/3rdparty/soundtouch/source/SoundTouch/RateTransposer.h b/3rdparty/soundtouch/source/SoundTouch/RateTransposer.h index fad6d65718..8d0eab82f0 100644 --- a/3rdparty/soundtouch/source/SoundTouch/RateTransposer.h +++ b/3rdparty/soundtouch/source/SoundTouch/RateTransposer.h @@ -14,10 +14,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $ +// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $ // File revision : $Revision: 4 $ // -// $Id: RateTransposer.h 195 2014-04-06 15:57:21Z oparviai $ +// $Id: RateTransposer.h 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -81,14 +81,14 @@ protected: static ALGORITHM algorithm; public: - float rate; + double rate; int numChannels; TransposerBase(); virtual ~TransposerBase(); virtual int transpose(FIFOSampleBuffer &dest, FIFOSampleBuffer &src); - virtual void setRate(float newRate); + virtual void setRate(double newRate); virtual void setChannels(int channels); // static factory function @@ -158,7 +158,7 @@ public: /// Sets new target rate. Normal rate = 1.0, smaller values represent slower /// rate, larger faster rates. - virtual void setRate(float newRate); + virtual void setRate(double newRate); /// Sets the number of channels, 1 = mono, 2 = stereo void setChannels(int channels); diff --git a/3rdparty/soundtouch/source/SoundTouch/SoundTouch.cpp b/3rdparty/soundtouch/source/SoundTouch/SoundTouch.cpp index a9d23fc3c3..2c715e20a1 100644 --- a/3rdparty/soundtouch/source/SoundTouch/SoundTouch.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/SoundTouch.cpp @@ -41,10 +41,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-10-08 15:26:57 +0000 (Wed, 08 Oct 2014) $ +// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $ // File revision : $Revision: 4 $ // -// $Id: SoundTouch.cpp 201 2014-10-08 15:26:57Z oparviai $ +// $Id: SoundTouch.cpp 225 2015-07-26 14:45:48Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -110,6 +110,9 @@ SoundTouch::SoundTouch() calcEffectiveRateAndTempo(); + samplesExpectedOut = 0; + samplesOutput = 0; + channels = 0; bSrateSet = false; } @@ -157,7 +160,7 @@ void SoundTouch::setChannels(uint numChannels) // Sets new rate control value. Normal rate = 1.0, smaller values // represent slower rate, larger faster rates. -void SoundTouch::setRate(float newRate) +void SoundTouch::setRate(double newRate) { virtualRate = newRate; calcEffectiveRateAndTempo(); @@ -167,9 +170,9 @@ void SoundTouch::setRate(float newRate) // Sets new rate control value as a difference in percents compared // to the original rate (-50 .. +100 %) -void SoundTouch::setRateChange(float newRate) +void SoundTouch::setRateChange(double newRate) { - virtualRate = 1.0f + 0.01f * newRate; + virtualRate = 1.0 + 0.01 * newRate; calcEffectiveRateAndTempo(); } @@ -177,7 +180,7 @@ void SoundTouch::setRateChange(float newRate) // Sets new tempo control value. Normal tempo = 1.0, smaller values // represent slower tempo, larger faster tempo. -void SoundTouch::setTempo(float newTempo) +void SoundTouch::setTempo(double newTempo) { virtualTempo = newTempo; calcEffectiveRateAndTempo(); @@ -187,9 +190,9 @@ void SoundTouch::setTempo(float newTempo) // Sets new tempo control value as a difference in percents compared // to the original tempo (-50 .. +100 %) -void SoundTouch::setTempoChange(float newTempo) +void SoundTouch::setTempoChange(double newTempo) { - virtualTempo = 1.0f + 0.01f * newTempo; + virtualTempo = 1.0 + 0.01 * newTempo; calcEffectiveRateAndTempo(); } @@ -197,7 +200,7 @@ void SoundTouch::setTempoChange(float newTempo) // Sets new pitch control value. Original pitch = 1.0, smaller values // represent lower pitches, larger values higher pitch. -void SoundTouch::setPitch(float newPitch) +void SoundTouch::setPitch(double newPitch) { virtualPitch = newPitch; calcEffectiveRateAndTempo(); @@ -207,9 +210,9 @@ void SoundTouch::setPitch(float newPitch) // Sets pitch change in octaves compared to the original pitch // (-1.00 .. +1.00) -void SoundTouch::setPitchOctaves(float newPitch) +void SoundTouch::setPitchOctaves(double newPitch) { - virtualPitch = (float)exp(0.69314718056f * newPitch); + virtualPitch = exp(0.69314718056 * newPitch); calcEffectiveRateAndTempo(); } @@ -219,14 +222,14 @@ void SoundTouch::setPitchOctaves(float newPitch) // (-12 .. +12) void SoundTouch::setPitchSemiTones(int newPitch) { - setPitchOctaves((float)newPitch / 12.0f); + setPitchOctaves((double)newPitch / 12.0); } -void SoundTouch::setPitchSemiTones(float newPitch) +void SoundTouch::setPitchSemiTones(double newPitch) { - setPitchOctaves(newPitch / 12.0f); + setPitchOctaves(newPitch / 12.0); } @@ -234,14 +237,14 @@ void SoundTouch::setPitchSemiTones(float newPitch) // nominal control values. void SoundTouch::calcEffectiveRateAndTempo() { - float oldTempo = tempo; - float oldRate = rate; + 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) @@ -317,8 +320,13 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples) pTDStretch->putSamples(samples, nSamples); } */ + + // accumulate how many samples are expected out from processing, given the current + // processing setting + samplesExpectedOut += (double)nSamples / ((double)rate * (double)tempo); + #ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER - else if (rate <= 1.0f) + if (rate <= 1.0f) { // transpose the rate down, output the transposed sound to tempo changer buffer assert(output == pTDStretch); @@ -346,44 +354,30 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples) void SoundTouch::flush() { int i; - int nUnprocessed; - int nOut; - SAMPLETYPE *buff = new SAMPLETYPE[64 * channels]; - - // check how many samples still await processing, and scale - // that by tempo & rate to get expected output sample count - nUnprocessed = numUnprocessedSamples(); - nUnprocessed = (int)((double)nUnprocessed / (tempo * rate) + 0.5); + int numStillExpected; + SAMPLETYPE *buff = new SAMPLETYPE[128 * channels]; - nOut = numSamples(); // ready samples currently in buffer ... - nOut += nUnprocessed; // ... and how many we expect there to be in the end - - memset(buff, 0, 64 * channels * sizeof(SAMPLETYPE)); + // how many samples are still expected to output + numStillExpected = (int)((long)(samplesExpectedOut + 0.5) - samplesOutput); + + memset(buff, 0, 128 * channels * sizeof(SAMPLETYPE)); // "Push" the last active samples out from the processing pipeline by // feeding blank samples into the processing pipeline until new, // processed samples appear in the output (not however, more than - // 8ksamples in any case) - for (i = 0; i < 128; i ++) - { - putSamples(buff, 64); - if ((int)numSamples() >= nOut) - { - // Enough new samples have appeared into the output! - // As samples come from processing with bigger chunks, now truncate it - // back to maximum "nOut" samples to improve duration accuracy - adjustAmountOfSamples(nOut); + // 24ksamples in any case) + for (i = 0; (numStillExpected > (int)numSamples()) && (i < 200); i ++) + { + putSamples(buff, 128); + } - // finish - break; - } - } + adjustAmountOfSamples(numStillExpected); delete[] buff; - // Clear working buffers - pRateTransposer->clear(); + // Clear input buffers + // pRateTransposer->clearInput(); pTDStretch->clearInput(); - // yet leave the 'tempoChanger' output intouched as that's where the + // yet leave the output intouched as that's where the // flushed samples are! } @@ -482,6 +476,7 @@ int SoundTouch::getSetting(int settingId) const // buffers. void SoundTouch::clear() { + samplesExpectedOut = 0; pRateTransposer->clear(); pTDStretch->clear(); } @@ -502,3 +497,30 @@ uint SoundTouch::numUnprocessedSamples() const } return 0; } + + + +/// Output samples from beginning of the sample buffer. Copies requested samples to +/// output buffer and removes them from the sample buffer. If there are less than +/// 'numsample' samples in the buffer, returns all that available. +/// +/// \return Number of samples returned. +uint SoundTouch::receiveSamples(SAMPLETYPE *output, uint maxSamples) +{ + uint ret = FIFOProcessor::receiveSamples(output, maxSamples); + samplesOutput += (long)ret; + return ret; +} + + +/// Adjusts book-keeping so that given number of samples are removed from beginning of the +/// sample buffer without copying them anywhere. +/// +/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly +/// with 'ptrBegin' function. +uint SoundTouch::receiveSamples(uint maxSamples) +{ + uint ret = FIFOProcessor::receiveSamples(maxSamples); + samplesOutput += (long)ret; + return ret; +} diff --git a/3rdparty/soundtouch/source/SoundTouch/TDStretch.cpp b/3rdparty/soundtouch/source/SoundTouch/TDStretch.cpp index aa26e538ed..d030558b4c 100644 --- a/3rdparty/soundtouch/source/SoundTouch/TDStretch.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/TDStretch.cpp @@ -13,10 +13,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-22 15:07:12 +0000 (Sun, 22 Feb 2015) $ +// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $ // File revision : $Revision: 1.12 $ // -// $Id: TDStretch.cpp 205 2015-02-22 15:07:12Z oparviai $ +// $Id: TDStretch.cpp 226 2015-08-08 21:00:15Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -63,7 +63,7 @@ using namespace soundtouch; *****************************************************************************/ // Table for the hierarchical mixing position seeking algorithm -static const short _scanOffsets[5][24]={ +const short _scanOffsets[5][24]={ { 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806, 868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0}, {-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0, @@ -94,7 +94,9 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer) bAutoSeqSetting = true; bAutoSeekSetting = true; -// outDebt = 0; + maxnorm = 0; + maxnormf = 1e8; + skipFract = 0; tempo = 1.0f; @@ -250,7 +252,7 @@ int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) if (bQuickSeek) { return seekBestOverlapPositionQuick(refPos); - } + } else { return seekBestOverlapPositionFull(refPos); @@ -282,7 +284,6 @@ inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, ui } - // Seeks for the optimal overlap-mixing position. The 'stereo' version of the // routine // @@ -336,6 +337,11 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos) } } } + +#ifdef SOUNDTOUCH_INTEGER_SAMPLES + adaptNormalizer(); +#endif + // clear cross correlation routine state if necessary (is so e.g. in MMX routines). clearCrossCorrState(); @@ -343,64 +349,161 @@ int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos) } -// Seeks for the optimal overlap-mixing position. The 'stereo' version of the -// routine +// Quick seek algorithm for improved runtime-performance: First roughly scans through the +// correlation area, and then scan surroundings of two best preliminary correlation candidates +// with improved precision // -// The best position is determined as the position where the two overlapped -// sample sequences are 'most alike', in terms of the highest cross-correlation -// value over the overlapping period -int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos) +// Based on testing: +// - This algorithm gives on average 99% as good match as the full algorith +// - this quick seek algorithm finds the best match on ~90% of cases +// - on those 10% of cases when this algorithm doesn't find best match, +// it still finds on average ~90% match vs. the best possible match +int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos) { - int j; +#define _MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define SCANSTEP 16 +#define SCANWIND 8 + int bestOffs; - double bestCorr, corr; - int scanCount, corrOffset, tempOffset; + int i; + int bestOffs2; + float bestCorr, corr; + float bestCorr2; + double norm; + + // note: 'float' types used in this function in case that the platform would need to use software-fp bestCorr = FLT_MIN; - bestOffs = _scanOffsets[0][0]; - corrOffset = 0; - tempOffset = 0; + bestOffs = SCANWIND; + bestCorr2 = FLT_MIN; + bestOffs2 = 0; - // Scans for the best correlation value using four-pass hierarchical search. + int best = 0; + + // Scans for the best correlation value by testing each possible position + // over the permitted range. Look for two best matches on the first pass to + // increase possibility of ideal match. // - // The look-up table 'scans' has hierarchical position adjusting steps. - // In first pass the routine searhes for the highest correlation with - // relatively coarse steps, then rescans the neighbourhood of the highest - // correlation with better resolution and so on. - for (scanCount = 0;scanCount < 4; scanCount ++) + // Begin from "SCANSTEP" instead of SCANWIND to make the calculation + // catch the 'middlepoint' of seekLength vector as that's the a-priori + // expected best match position + // + // Roughly: + // - 15% of cases find best result directly on the first round, + // - 75% cases find better match on 2nd round around the best match from 1st round + // - 10% cases find better match on 2nd round around the 2nd-best-match from 1st round + for (i = SCANSTEP; i < seekLength - SCANWIND - 1; i += SCANSTEP) { - j = 0; - while (_scanOffsets[scanCount][j]) + // Calculates correlation value for the mixing position corresponding + // to 'i' + corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm); + // heuristic rule to slightly favour values close to mid of the seek range + float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength; + corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp)); + + // Checks for the highest correlation value + if (corr > bestCorr) { - double norm; - tempOffset = corrOffset + _scanOffsets[scanCount][j]; - if (tempOffset >= seekLength) break; - - // Calculates correlation value for the mixing position corresponding - // to 'tempOffset' - corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer, norm); - // heuristic rule to slightly favour values close to mid of the range - double tmp = (double)(2 * tempOffset - seekLength) / seekLength; - corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp)); - - // Checks for the highest correlation value - if (corr > bestCorr) - { - bestCorr = corr; - bestOffs = tempOffset; - } - j ++; + // found new best match. keep the previous best as 2nd best match + bestCorr2 = bestCorr; + bestOffs2 = bestOffs; + bestCorr = corr; + bestOffs = i; + } + else if (corr > bestCorr2) + { + // not new best, but still new 2nd best match + bestCorr2 = corr; + bestOffs2 = i; } - corrOffset = bestOffs; } + + // Scans surroundings of the found best match with small stepping + int end = _MIN(bestOffs + SCANWIND + 1, seekLength); + for (i = bestOffs - SCANWIND; i < end; i++) + { + if (i == bestOffs) continue; // this offset already calculated, thus skip + + // Calculates correlation value for the mixing position corresponding + // to 'i' + corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm); + // heuristic rule to slightly favour values close to mid of the range + float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength; + corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp)); + + // Checks for the highest correlation value + if (corr > bestCorr) + { + bestCorr = corr; + bestOffs = i; + best = 1; + } + } + + // Scans surroundings of the 2nd best match with small stepping + end = _MIN(bestOffs2 + SCANWIND + 1, seekLength); + for (i = bestOffs2 - SCANWIND; i < end; i++) + { + if (i == bestOffs2) continue; // this offset already calculated, thus skip + + // Calculates correlation value for the mixing position corresponding + // to 'i' + corr = (float)calcCrossCorr(refPos + channels*i, pMidBuffer, norm); + // heuristic rule to slightly favour values close to mid of the range + float tmp = (float)(2 * i - seekLength - 1) / (float)seekLength; + corr = ((corr + 0.1f) * (1.0f - 0.25f * tmp * tmp)); + + // Checks for the highest correlation value + if (corr > bestCorr) + { + bestCorr = corr; + bestOffs = i; + best = 2; + } + } + // clear cross correlation routine state if necessary (is so e.g. in MMX routines). clearCrossCorrState(); +#ifdef SOUNDTOUCH_INTEGER_SAMPLES + adaptNormalizer(); +#endif + return bestOffs; } + +/// For integer algorithm: adapt normalization factor divider with music so that +/// it'll not be pessimistically restrictive that can degrade quality on quieter sections +/// yet won't cause integer overflows either +void TDStretch::adaptNormalizer() +{ + // Do not adapt normalizer over too silent sequences to avoid averaging filter depleting to + // too low values during pauses in music + if ((maxnorm > 1000) || (maxnormf > 40000000)) + { + //norm averaging filter + maxnormf = 0.9f * maxnormf + 0.1f * (float)maxnorm; + + if ((maxnorm > 800000000) && (overlapDividerBitsNorm < 16)) + { + // large values, so increase divider + overlapDividerBitsNorm++; + if (maxnorm > 1600000000) overlapDividerBitsNorm++; // extra large value => extra increase + } + else if ((maxnormf < 1000000) && (overlapDividerBitsNorm > 0)) + { + // extra small values, decrease divider + overlapDividerBitsNorm--; + } + } + + maxnorm = 0; +} + + /// clear cross correlation routine state if necessary void TDStretch::clearCrossCorrState() { @@ -422,7 +525,7 @@ void TDStretch::calcSeqParameters() #define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) #define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW)) - // seek-window-ms setting values at above low & top tempo + // seek-window-ms setting values at above low & top tempoq #define AUTOSEEK_AT_MIN 25.0 #define AUTOSEEK_AT_MAX 15.0 #define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW)) @@ -459,7 +562,7 @@ void TDStretch::calcSeqParameters() // Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower // tempo, larger faster tempo. -void TDStretch::setTempo(float newTempo) +void TDStretch::setTempo(double newTempo) { int intskip; @@ -470,7 +573,7 @@ void TDStretch::setTempo(float newTempo) // Calculate ideal skip length (according to tempo value) nominalSkip = tempo * (seekWindowLength - overlapLength); - intskip = (int)(nominalSkip + 0.5f); + intskip = (int)(nominalSkip + 0.5); // Calculate how many samples are needed in the 'inputBuffer' to // process another batch of samples @@ -736,13 +839,15 @@ void TDStretch::calculateOverlapLength(int aoverlapMs) // calculate overlap length so that it's power of 2 - thus it's easy to do // integer division by right-shifting. Term "-1" at end is to account for // the extra most significatnt bit left unused in result by signed multiplication - overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1; - if (overlapDividerBits > 9) overlapDividerBits = 9; - if (overlapDividerBits < 3) overlapDividerBits = 3; - newOvl = (int)pow(2.0, (int)overlapDividerBits + 1); // +1 => account for -1 above + overlapDividerBitsPure = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1; + if (overlapDividerBitsPure > 9) overlapDividerBitsPure = 9; + if (overlapDividerBitsPure < 3) overlapDividerBitsPure = 3; + newOvl = (int)pow(2.0, (int)overlapDividerBitsPure + 1); // +1 => account for -1 above acceptNewOverlapLength(newOvl); + overlapDividerBitsNorm = overlapDividerBitsPure; + // calculate sloping divider so that crosscorrelation operation won't // overflow 32-bit register. Max. sum of the crosscorrelation sum without // divider would be 2^30*(N^3-N)/3, where N = overlap length @@ -750,10 +855,10 @@ void TDStretch::calculateOverlapLength(int aoverlapMs) } -double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const +double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, double &norm) { long corr; - long lnorm; + unsigned long lnorm; int i; corr = lnorm = 0; @@ -763,15 +868,19 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do for (i = 0; i < channels * overlapLength; i += 4) { corr += (mixingPos[i] * compare[i] + - mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits; // notice: do intermediate division here to avoid integer overflow + mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow corr += (mixingPos[i + 2] * compare[i + 2] + - mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits; + mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm; lnorm += (mixingPos[i] * mixingPos[i] + - mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits; // notice: do intermediate division here to avoid integer overflow + mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow lnorm += (mixingPos[i + 2] * mixingPos[i + 2] + - mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits; + mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBitsNorm; } + if (lnorm > maxnorm) + { + maxnorm = lnorm; + } // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation norm = (double)lnorm; @@ -780,17 +889,17 @@ double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare, do /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value -double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const +double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) { long corr; - long lnorm; + unsigned long lnorm; int i; // cancel first normalizer tap from previous round lnorm = 0; for (i = 1; i <= channels; i ++) { - lnorm -= (mixingPos[-i] * mixingPos[-i]) >> overlapDividerBits; + lnorm -= (mixingPos[-i] * mixingPos[-i]) >> overlapDividerBitsNorm; } corr = 0; @@ -800,18 +909,23 @@ double TDStretch::calcCrossCorrAccumulate(const short *mixingPos, const short *c for (i = 0; i < channels * overlapLength; i += 4) { corr += (mixingPos[i] * compare[i] + - mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits; // notice: do intermediate division here to avoid integer overflow + mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBitsNorm; // notice: do intermediate division here to avoid integer overflow corr += (mixingPos[i + 2] * compare[i + 2] + - mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits; + mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBitsNorm; } // update normalizer with last samples of this round for (int j = 0; j < channels; j ++) { i --; - lnorm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits; + lnorm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBitsNorm; } + norm += (double)lnorm; + if (norm > maxnorm) + { + maxnorm = (unsigned long)norm; + } // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation @@ -896,7 +1010,7 @@ void TDStretch::calculateOverlapLength(int overlapInMsec) /// Calculate cross-correlation -double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &anorm) const +double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, double &anorm) { double corr; double norm; @@ -927,7 +1041,7 @@ double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare, do /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value -double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const +double TDStretch::calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) { double corr; int i; diff --git a/3rdparty/soundtouch/source/SoundTouch/TDStretch.h b/3rdparty/soundtouch/source/SoundTouch/TDStretch.h index b390736913..e6d75aac10 100644 --- a/3rdparty/soundtouch/source/SoundTouch/TDStretch.h +++ b/3rdparty/soundtouch/source/SoundTouch/TDStretch.h @@ -13,10 +13,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-04-06 15:57:21 +0000 (Sun, 06 Apr 2014) $ +// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $ // File revision : $Revision: 4 $ // -// $Id: TDStretch.h 195 2014-04-06 15:57:21Z oparviai $ +// $Id: TDStretch.h 226 2015-08-08 21:00:15Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -112,39 +112,46 @@ class TDStretch : public FIFOProcessor protected: int channels; int sampleReq; - float tempo; - SAMPLETYPE *pMidBuffer; - SAMPLETYPE *pMidBufferUnaligned; int overlapLength; int seekLength; int seekWindowLength; - int overlapDividerBits; + int overlapDividerBitsNorm; + int overlapDividerBitsPure; int slopingDivider; - float nominalSkip; - float skipFract; - FIFOSampleBuffer outputBuffer; - FIFOSampleBuffer inputBuffer; - bool bQuickSeek; - int sampleRate; int sequenceMs; int seekWindowMs; int overlapMs; + + unsigned long maxnorm; + float maxnormf; + + double tempo; + double nominalSkip; + double skipFract; + + bool bQuickSeek; bool bAutoSeqSetting; bool bAutoSeekSetting; + SAMPLETYPE *pMidBuffer; + SAMPLETYPE *pMidBufferUnaligned; + + FIFOSampleBuffer outputBuffer; + FIFOSampleBuffer inputBuffer; + void acceptNewOverlapLength(int newOverlapLength); virtual void clearCrossCorrState(); void calculateOverlapLength(int overlapMs); - virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const; - virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm) const; + virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm); + virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm); virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos); virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos); - int seekBestOverlapPosition(const SAMPLETYPE *refPos); + virtual int seekBestOverlapPosition(const SAMPLETYPE *refPos); virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; @@ -154,6 +161,8 @@ protected: void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; void calcSeqParameters(); + void adaptNormalizer(); + /// Changes the tempo of the given sound samples. /// Returns amount of samples returned in the "output" buffer. @@ -182,7 +191,7 @@ public: /// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower /// tempo, larger faster tempo. - void setTempo(float newTempo); + void setTempo(double newTempo); /// Returns nonzero if there aren't any samples available for outputting. virtual void clear(); @@ -249,8 +258,8 @@ public: class TDStretchMMX : public TDStretch { protected: - double calcCrossCorr(const short *mixingPos, const short *compare, double &norm) const; - double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm) const; + double calcCrossCorr(const short *mixingPos, const short *compare, double &norm); + double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm); virtual void overlapStereo(short *output, const short *input) const; virtual void clearCrossCorrState(); }; @@ -262,8 +271,8 @@ public: class TDStretchSSE : public TDStretch { protected: - double calcCrossCorr(const float *mixingPos, const float *compare, double &norm) const; - double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm) const; + double calcCrossCorr(const float *mixingPos, const float *compare, double &norm); + double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm); }; #endif /// SOUNDTOUCH_ALLOW_SSE diff --git a/3rdparty/soundtouch/source/SoundTouch/cpu_detect.h b/3rdparty/soundtouch/source/SoundTouch/cpu_detect.h index e7582e8da3..7859ffb55d 100644 --- a/3rdparty/soundtouch/source/SoundTouch/cpu_detect.h +++ b/3rdparty/soundtouch/source/SoundTouch/cpu_detect.h @@ -12,7 +12,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2008-02-10 16:26:55 +0000 (Sun, 10 Feb 2008) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/cpu_detect_x86.cpp b/3rdparty/soundtouch/source/SoundTouch/cpu_detect_x86.cpp index e9a0e20041..00f22ab274 100644 --- a/3rdparty/soundtouch/source/SoundTouch/cpu_detect_x86.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/cpu_detect_x86.cpp @@ -11,7 +11,7 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2014-01-07 18:24:28 +0000 (Tue, 07 Jan 2014) $ +// 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 $ diff --git a/3rdparty/soundtouch/source/SoundTouch/mmx_optimized.cpp b/3rdparty/soundtouch/source/SoundTouch/mmx_optimized.cpp index 9062026399..5c34b9adc0 100644 --- a/3rdparty/soundtouch/source/SoundTouch/mmx_optimized.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/mmx_optimized.cpp @@ -20,10 +20,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-22 15:10:38 +0000 (Sun, 22 Feb 2015) $ +// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $ // File revision : $Revision: 4 $ // -// $Id: mmx_optimized.cpp 206 2015-02-22 15:10:38Z oparviai $ +// $Id: mmx_optimized.cpp 226 2015-08-08 21:00:15Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -68,7 +68,7 @@ using namespace soundtouch; // Calculates cross correlation of two buffers -double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &dnorm) const +double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &dnorm) { const __m64 *pVec1, *pVec2; __m64 shifter; @@ -79,7 +79,7 @@ double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &d pVec1 = (__m64*)pV1; pVec2 = (__m64*)pV2; - shifter = _m_from_int(overlapDividerBits); + shifter = _m_from_int(overlapDividerBitsNorm); normaccu = accu = _mm_setzero_si64(); // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples @@ -123,6 +123,11 @@ double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &d // Clear MMS state _m_empty(); + if (norm > (long)maxnorm) + { + maxnorm = norm; + } + // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation dnorm = (double)norm; @@ -134,7 +139,7 @@ double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2, double &d /// Update cross-correlation by accumulating "norm" coefficient by previously calculated value -double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, double &dnorm) const +double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, double &dnorm) { const __m64 *pVec1, *pVec2; __m64 shifter; @@ -146,13 +151,13 @@ double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, lnorm = 0; for (i = 1; i <= channels; i ++) { - lnorm -= (pV1[-i] * pV1[-i]) >> overlapDividerBits; + lnorm -= (pV1[-i] * pV1[-i]) >> overlapDividerBitsNorm; } pVec1 = (__m64*)pV1; pVec2 = (__m64*)pV2; - shifter = _m_from_int(overlapDividerBits); + shifter = _m_from_int(overlapDividerBitsNorm); accu = _mm_setzero_si64(); // Process 4 parallel sets of 2 * stereo samples or 4 * mono samples @@ -191,10 +196,15 @@ double TDStretchMMX::calcCrossCorrAccumulate(const short *pV1, const short *pV2, pV1 = (short *)pVec1; for (int j = 1; j <= channels; j ++) { - lnorm += (pV1[-j] * pV1[-j]) >> overlapDividerBits; + lnorm += (pV1[-j] * pV1[-j]) >> overlapDividerBitsNorm; } dnorm += (double)lnorm; + if (lnorm > (long)maxnorm) + { + maxnorm = lnorm; + } + // Normalize result by dividing by sqrt(norm) - this step is easiest // done using floating point operation return (double)corr / sqrt((dnorm < 1e-9) ? 1.0 : dnorm); @@ -233,7 +243,7 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const // Overlaplength-division by shifter. "+1" is to account for "-1" deduced in // overlapDividerBits calculation earlier. - shifter = _m_from_int(overlapDividerBits + 1); + shifter = _m_from_int(overlapDividerBitsPure + 1); for (i = 0; i < overlapLength / 4; i ++) { diff --git a/3rdparty/soundtouch/source/SoundTouch/sse_optimized.cpp b/3rdparty/soundtouch/source/SoundTouch/sse_optimized.cpp index fa622efa55..b6bb4cc223 100644 --- a/3rdparty/soundtouch/source/SoundTouch/sse_optimized.cpp +++ b/3rdparty/soundtouch/source/SoundTouch/sse_optimized.cpp @@ -23,10 +23,10 @@ /// //////////////////////////////////////////////////////////////////////////////// // -// Last changed : $Date: 2015-02-21 21:24:29 +0000 (Sat, 21 Feb 2015) $ +// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $ // File revision : $Revision: 4 $ // -// $Id: sse_optimized.cpp 202 2015-02-21 21:24:29Z oparviai $ +// $Id: sse_optimized.cpp 226 2015-08-08 21:00:15Z oparviai $ // //////////////////////////////////////////////////////////////////////////////// // @@ -71,7 +71,7 @@ using namespace soundtouch; #include // Calculates cross correlation of two buffers -double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &anorm) const +double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &anorm) { int i; const float *pVec1; @@ -183,7 +183,7 @@ double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &a -double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm) const +double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm) { // call usual calcCrossCorr function because SSE does not show big benefit of // accumulating "norm" value, and also the "norm" rolling algorithm would get