diff --git a/.gitignore b/.gitignore index 9def793..4269200 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,12 @@ source/SoundTouchDll/Win32/ source/SoundTouchDll/x64/ source/SoundTouchDll/DllTest/Win32/ source/SoundTouchDll/DllTest/x64/ + +# Files generated by Android Studio +source/android-lib/.gradle +source/android-lib/.idea +**/*.iml +source/android-lib/local.properties +source/android-lib/build +source/android-lib/.externalNativeBuild + diff --git a/README.html b/README.html index 6dc3d71..36447ed 100644 --- a/README.html +++ b/README.html @@ -1,913 +1,912 @@ - - - - SoundTouch library README - - - - - - - -
-

SoundTouch audio processing library v2.1pre

-

SoundTouch library Copyright � Olli Parviainen 2001-2018

-
-

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.

-

C# example: The source code package includes also a C# example - application for Windows that shows how to invoke SoundTouch.dll - dynamic-load library for processing mp3 audio. -

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.3. 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).

-

See an external blog article with more detailed discussion about the - -SoundTouch OpenMP optimization.

-

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

-

2.1pre:

- -

2.0:

- -

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

-

---

-

commercial license alternative also available, contact author for details.

-
-

README.html file updated in May-2018

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

SoundTouch audio processing library v2.1

+

SoundTouch library Copyright © Olli Parviainen 2001-2018

+
+

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

+

SoundTouch git repository: https://gitlab.com/soundtouch/soundtouch.git

+
+

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.

+

C# example: The source code package includes also a C# example + application for Windows that shows how to invoke SoundTouch.dll + dynamic-load library for processing mp3 audio. +

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.3. 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).

+

See an external blog article with more detailed discussion about the + +SoundTouch OpenMP optimization.

+

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

+

2.1:

+ +

2.0:

+ +

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

+

---

+

commercial license alternative also available, contact author for details.

+
+

README.html file updated in September-2018

+ + diff --git a/bin/run_test.cmd b/bin/run_test.cmd index 0af8672..6686eb0 100644 --- a/bin/run_test.cmd +++ b/bin/run_test.cmd @@ -1,8 +1,8 @@ -set SOUND_DIR=d:\dev\test_sounds +set SOUND_DIR=c:\dev\test_sounds set OUT_DIR=. set TEST_NAME=semmari set OUT_NAME=out -set SS=soundstretch +set SS=soundstretch_x64 set TEST_PARAM=-pitch=-3 -bpm call %SS% %SOUND_DIR%\%TEST_NAME%-8b1.wav %OUT_DIR%\%OUT_NAME%-8b1.wav %TEST_PARAM% diff --git a/include/SoundTouch.h b/include/SoundTouch.h index 7b65fa9..f2addc1 100644 --- a/include/SoundTouch.h +++ b/include/SoundTouch.h @@ -72,10 +72,10 @@ namespace soundtouch { /// Soundtouch library version string -#define SOUNDTOUCH_VERSION "2.1pre" +#define SOUNDTOUCH_VERSION "2.1" /// SoundTouch library version id -#define SOUNDTOUCH_VERSION_ID (20009) +#define SOUNDTOUCH_VERSION_ID (20100) // // Available setting IDs for the 'setSetting' & 'get_setting' functions: diff --git a/readme.md b/readme.md index d6f8ef0..9516dfe 100644 --- a/readme.md +++ b/readme.md @@ -9,6 +9,8 @@ same time Visit [SoundTouch website](https://www.surina.net/soundtouch) and see the [README file](README.html) for more information and audio examples. +### The latest stable release is 2.1, tagged in git as 2.1.0 + ## Example Use SoundStretch example app for modifying wav audio files, for example as follows: diff --git a/source/Android-lib/README-SoundTouch-Android.html b/source/Android-lib/README-SoundTouch-Android.html index 4a2c809..48bd4f8 100644 --- a/source/Android-lib/README-SoundTouch-Android.html +++ b/source/Android-lib/README-SoundTouch-Android.html @@ -103,6 +103,7 @@ in the soundtouch-jni.cpp source code file for more details.

+
  • Android-lib/build.gradle: Top level build script file for Android Studio 3.1.4+
  • Feel free to examine and extend the provided cpp/java source code example file pair to diff --git a/source/Android-lib/build.gradle b/source/Android-lib/build.gradle new file mode 100644 index 0000000..42994a9 --- /dev/null +++ b/source/Android-lib/build.gradle @@ -0,0 +1,55 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + jcenter() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.4' + } +} + +allprojects { + repositories { + jcenter() + google() + } +} + +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + + defaultConfig { + applicationId "net.surina.soundtouchexample" + minSdkVersion 14 + targetSdkVersion 21 + + externalNativeBuild.ndkBuild { + arguments "NDK_APPLICATION=jni/Application.mk", + "APP_ALLOW_MISSING_DEPS:=true" + } + } + + sourceSets { + main { + manifest.srcFile "./AndroidManifest.xml" + java.srcDirs = ["./src"] + res.srcDirs = ["res"] + } + } + + externalNativeBuild { + ndkBuild { + path 'jni/Android.mk' + } + } + + + buildTypes { + release { + minifyEnabled false + } + } +} diff --git a/source/Android-lib/gradle/wrapper/gradle-wrapper.jar b/source/Android-lib/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..99340b4 Binary files /dev/null and b/source/Android-lib/gradle/wrapper/gradle-wrapper.jar differ diff --git a/source/Android-lib/gradle/wrapper/gradle-wrapper.properties b/source/Android-lib/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..efc27cb --- /dev/null +++ b/source/Android-lib/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Jan 13 09:12:34 PST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip diff --git a/source/Android-lib/gradlew b/source/Android-lib/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/source/Android-lib/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/source/Android-lib/gradlew.bat b/source/Android-lib/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/source/Android-lib/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/source/Android-lib/jni/Android.mk b/source/Android-lib/jni/Android.mk index 778ed89..af46d1b 100644 --- a/source/Android-lib/jni/Android.mk +++ b/source/Android-lib/jni/Android.mk @@ -17,6 +17,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../include $(LOCAL_PATH)/../../SoundStretch # *** Remember: Change -O0 into -O2 in add-applications.mk *** LOCAL_MODULE := soundtouch @@ -38,7 +39,7 @@ LOCAL_LDLIBS += -llog # Custom Flags: # -fvisibility=hidden : don't export all symbols -LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections +LOCAL_CFLAGS += -fvisibility=hidden -fdata-sections -ffunction-sections # OpenMP mode : enable these flags to enable using OpenMP for parallel computation #LOCAL_CFLAGS += -fopenmp diff --git a/source/Android-lib/jni/Application.mk b/source/Android-lib/jni/Application.mk index 122fb12..022d1de 100644 --- a/source/Android-lib/jni/Application.mk +++ b/source/Android-lib/jni/Application.mk @@ -4,6 +4,6 @@ APP_ABI := all #armeabi-v7a armeabi APP_OPTIM := release -APP_STL := stlport_static +APP_STL := c++_static APP_CPPFLAGS := -fexceptions # -D SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS diff --git a/source/SoundTouchDLL/SoundTouchDLL.rc b/source/SoundTouchDLL/SoundTouchDLL.rc index 29c330c..cc6a408 100644 --- a/source/SoundTouchDLL/SoundTouchDLL.rc +++ b/source/SoundTouchDLL/SoundTouchDLL.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,0 - PRODUCTVERSION 2,0,0,0 + FILEVERSION 2,1,0,0 + PRODUCTVERSION 2,1,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "Comments", "SoundTouch Library licensed for 3rd party applications subject to LGPL license v2.1. Visit http://www.surina.net/soundtouch for more information about the SoundTouch library." VALUE "FileDescription", "SoundTouch Dynamic Link Library" - VALUE "FileVersion", "2.0.0.0" + VALUE "FileVersion", "2.1.0.0" VALUE "InternalName", "SoundTouch" - VALUE "LegalCopyright", "Copyright (C) Olli Parviainen 2017" + VALUE "LegalCopyright", "Copyright (C) Olli Parviainen 2018" VALUE "OriginalFilename", "SoundTouch.dll" VALUE "ProductName", " SoundTouch Dynamic Link Library" - VALUE "ProductVersion", "2.0.0.0" + VALUE "ProductVersion", "2.1.0.0" END END BLOCK "VarFileInfo" diff --git a/source/csharp-example/SoundTouch.dll b/source/csharp-example/SoundTouch.dll index 4f9667b..eb37c7a 100644 Binary files a/source/csharp-example/SoundTouch.dll and b/source/csharp-example/SoundTouch.dll differ