Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alexmarsev/soundtouch.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroparviai <oparviai@f3a24b6a-cf45-0410-b55a-8c22e2698227>2013-06-12 19:24:44 +0400
committeroparviai <oparviai@f3a24b6a-cf45-0410-b55a-8c22e2698227>2013-06-12 19:24:44 +0400
commit41c97b8cc2618ee9fc5a67c092c93450a5609f62 (patch)
treea927e346b857b45e608c6071e5ed14324523a8ed
parentbff840aad1ac978fb58e20a32dc23d1d0583e38d (diff)
Added support for multi-channel audio
-rw-r--r--README.html8
-rw-r--r--include/STTypes.h7
-rw-r--r--include/SoundTouch.h4
-rw-r--r--source/SoundStretch/soundstretch.sln36
-rw-r--r--source/SoundStretch/soundstretch.vcproj249
-rw-r--r--source/SoundTouch/FIRFilter.cpp73
-rw-r--r--source/SoundTouch/FIRFilter.h1
-rw-r--r--source/SoundTouch/RateTransposer.cpp238
-rw-r--r--source/SoundTouch/RateTransposer.h7
-rw-r--r--source/SoundTouch/SoundTouch.cpp9
-rw-r--r--source/SoundTouch/SoundTouch.vcproj305
-rw-r--r--source/SoundTouch/TDStretch.cpp74
-rw-r--r--source/SoundTouch/TDStretch.h1
13 files changed, 724 insertions, 288 deletions
diff --git a/README.html b/README.html
index b6c8ffb..609241c 100644
--- a/README.html
+++ b/README.html
@@ -15,8 +15,8 @@
</head>
<body class="normal">
<hr>
-<h1>SoundTouch audio processing library v1.7.1</h1>
-<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2012 </p>
+<h1>SoundTouch audio processing library v1.7.2 (developing)</h1>
+<p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2013 </p>
<hr>
<h2>1. Introduction </h2>
<p>SoundTouch is an open-source audio processing library that allows
@@ -513,6 +513,10 @@ and estimates the BPM rate:</p>
<hr>
<h2>5. Change History</h2>
<h3>5.1. SoundTouch library Change History </h3>
+<p><b>1.7.2 (under work):</b></p>
+<ul>
+ <li>Added support for multi-channel audio processing
+</ul>
<p><b>1.7.1:</b></p>
<ul>
<li>Added files for Android compilation
diff --git a/include/STTypes.h b/include/STTypes.h
index 92016fb..46da0fe 100644
--- a/include/STTypes.h
+++ b/include/STTypes.h
@@ -78,6 +78,13 @@ namespace soundtouch
//#undef SOUNDTOUCH_INTEGER_SAMPLES
//#undef SOUNDTOUCH_FLOAT_SAMPLES
+ /// If following flag is defined, always uses multichannel processing
+ /// routines also for mono and stero sound. This is for routine testing
+ /// purposes; output should be same with either routines, yet disabling
+ /// the dedicated mono/stereo processing routines will result in slower
+ /// runtime performance so recommendation is to keep this off.
+ // #define USE_MULTICH_ALWAYS
+
#if (defined(__SOFTFP__))
// For Android compilation: Force use of Integer samples in case that
// compilation uses soft-floating point emulation - soft-fp is way too slow
diff --git a/include/SoundTouch.h b/include/SoundTouch.h
index b54bc39..4d3d80f 100644
--- a/include/SoundTouch.h
+++ b/include/SoundTouch.h
@@ -79,10 +79,10 @@ namespace soundtouch
{
/// Soundtouch library version string
-#define SOUNDTOUCH_VERSION "1.7.1"
+#define SOUNDTOUCH_VERSION "1.7.2 (dev)"
/// SoundTouch library version id
-#define SOUNDTOUCH_VERSION_ID (10701)
+#define SOUNDTOUCH_VERSION_ID (10702)
//
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
diff --git a/source/SoundStretch/soundstretch.sln b/source/SoundStretch/soundstretch.sln
index dfdc4ac..1b9a49a 100644
--- a/source/SoundStretch/soundstretch.sln
+++ b/source/SoundStretch/soundstretch.sln
@@ -1,32 +1,28 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundstretch", "soundstretch.vcproj", "{5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}"
ProjectSection(ProjectDependencies) = postProject
{68A5DD20-7057-448B-8FE0-B6AC8D205509} = {68A5DD20-7057-448B-8FE0-B6AC8D205509}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\SoundTouch\SoundTouch.vcproj", "{68A5DD20-7057-448B-8FE0-B6AC8D205509}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
EndProject
Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Debug.ActiveCfg = Debug|Win32
- {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Debug.Build.0 = Debug|Win32
- {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Release.ActiveCfg = Release|Win32
- {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Release.Build.0 = Release|Win32
- {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug.ActiveCfg = Debug|Win32
- {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug.Build.0 = Debug|Win32
- {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release.ActiveCfg = Release|Win32
- {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release.Build.0 = Release|Win32
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Debug|Win32.Build.0 = Debug|Win32
+ {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Release|Win32.ActiveCfg = Release|Win32
+ {5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Release|Win32.Build.0 = Release|Win32
+ {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.ActiveCfg = Debug|Win32
+ {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Debug|Win32.Build.0 = Debug|Win32
+ {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.ActiveCfg = Release|Win32
+ {68A5DD20-7057-448B-8FE0-B6AC8D205509}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
diff --git a/source/SoundStretch/soundstretch.vcproj b/source/SoundStretch/soundstretch.vcproj
index 5643c1b..53eb827 100644
--- a/source/SoundStretch/soundstretch.vcproj
+++ b/source/SoundStretch/soundstretch.vcproj
@@ -1,30 +1,53 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="7.10"
+ Version="9.00"
Name="soundstretch"
- SccProjectName=""
- SccLocalPath="">
+ ProjectGUID="{5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}"
+ TargetFrameworkVersion="131072"
+ >
<Platforms>
<Platform
- Name="Win32"/>
+ Name="Win32"
+ />
</Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Debug/soundstretch.tlb"
+ HeaderFileName=""
+ />
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
BasicRuntimeChecks="3"
- RuntimeLibrary="5"
+ RuntimeLibrary="1"
StructMemberAlignment="5"
PrecompiledHeaderFile=".\Debug/soundstretch.pch"
AssemblerListingLocation=".\Debug/"
@@ -32,117 +55,155 @@
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
DebugInformationFormat="4"
- CompileAs="0"/>
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1035"
+ />
<Tool
- Name="VCCustomBuildTool"/>
+ Name="VCPreLinkEventTool"
+ />
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SoundTouchD.lib"
OutputFile="Debug/soundstretchD.exe"
LinkIncremental="2"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib"
IgnoreDefaultLibraryNames="libc"
- GenerateDebugInformation="TRUE"
+ GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/soundstretchD.pdb"
- GenerateMapFile="TRUE"
+ GenerateMapFile="true"
MapFileName=".\Debug/soundstretchD.map"
SubSystem="1"
- TargetMachine="1"/>
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
<Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\Debug/soundstretch.tlb"
- HeaderFileName=""/>
- <Tool
- Name="VCPostBuildEventTool"
- CommandLine="copy Debug\soundstretchD.exe ..\..\bin\"/>
+ Name="VCALinkTool"
+ />
<Tool
- Name="VCPreBuildEventTool"/>
+ Name="VCManifestTool"
+ />
<Tool
- Name="VCPreLinkEventTool"/>
+ Name="VCXDCMakeTool"
+ />
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1035"/>
+ Name="VCBscMakeTool"
+ />
<Tool
- Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCFxCopTool"
+ />
<Tool
- Name="VCXMLDataGeneratorTool"/>
+ Name="VCAppVerifierTool"
+ />
<Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ Name="VCPostBuildEventTool"
+ CommandLine="copy Debug\soundstretchD.exe ..\..\bin\"
+ />
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TypeLibraryName=".\Release/soundstretch.tlb"
+ HeaderFileName=""
+ />
<Tool
Name="VCCLCompilerTool"
Optimization="3"
- GlobalOptimizations="FALSE"
InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="TRUE"
+ EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/soundstretch.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
DebugInformationFormat="0"
- CompileAs="0"/>
+ CompileAs="0"
+ />
<Tool
- Name="VCCustomBuildTool"/>
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1035"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
<Tool
Name="VCLinkerTool"
AdditionalDependencies="SoundTouch.lib"
OutputFile=".\Release/soundstretch.exe"
LinkIncremental="1"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib"
- GenerateDebugInformation="FALSE"
- GenerateMapFile="TRUE"
+ GenerateDebugInformation="false"
+ GenerateMapFile="true"
MapFileName=".\Release/soundstretch.map"
SubSystem="1"
- TargetMachine="1"/>
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
<Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\Release/soundstretch.tlb"
- HeaderFileName=""/>
+ Name="VCALinkTool"
+ />
<Tool
- Name="VCPostBuildEventTool"
- CommandLine="copy Release\soundstretch.exe ..\..\bin\"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1035"/>
+ Name="VCManifestTool"
+ />
<Tool
- Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCXDCMakeTool"
+ />
<Tool
- Name="VCXMLDataGeneratorTool"/>
+ Name="VCBscMakeTool"
+ />
<Tool
- Name="VCWebDeploymentTool"/>
+ Name="VCFxCopTool"
+ />
<Tool
- Name="VCManagedWrapperGeneratorTool"/>
+ Name="VCAppVerifierTool"
+ />
<Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ Name="VCPostBuildEventTool"
+ CommandLine="copy Release\soundstretch.exe ..\..\bin\"
+ />
</Configuration>
</Configurations>
<References>
@@ -150,84 +211,104 @@
<Files>
<Filter
Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
<File
- RelativePath="main.cpp">
+ RelativePath="main.cpp"
+ >
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
</File>
<File
- RelativePath="RunParameters.cpp">
+ RelativePath="RunParameters.cpp"
+ >
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
</File>
<File
- RelativePath="WavFile.cpp">
+ RelativePath="WavFile.cpp"
+ >
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
+ Filter="h;hpp;hxx;hm;inl"
+ >
<File
- RelativePath="RunParameters.h">
+ RelativePath="RunParameters.h"
+ >
</File>
<File
- RelativePath="WavFile.h">
+ RelativePath="WavFile.h"
+ >
</File>
</Filter>
<Filter
Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
</Filter>
</Files>
<Globals>
diff --git a/source/SoundTouch/FIRFilter.cpp b/source/SoundTouch/FIRFilter.cpp
index f882f7e..5cc774f 100644
--- a/source/SoundTouch/FIRFilter.cpp
+++ b/source/SoundTouch/FIRFilter.cpp
@@ -167,6 +167,60 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
}
+uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
+{
+ uint i, j, end, c;
+ LONG_SAMPLETYPE *sum=(LONG_SAMPLETYPE*)alloca(numChannels*sizeof(*sum));
+#ifdef SOUNDTOUCH_FLOAT_SAMPLES
+ // when using floating point samples, use a scaler instead of a divider
+ // because division is much slower operation than multiplying.
+ double dScaler = 1.0 / (double)resultDivider;
+#endif
+
+ assert(length != 0);
+ assert(src != NULL);
+ assert(dest != NULL);
+ assert(filterCoeffs != NULL);
+
+ end = numChannels * (numSamples - length);
+
+ for (c = 0; c < numChannels; c ++)
+ {
+ sum[c] = 0;
+ }
+
+ for (j = 0; j < end; j += numChannels)
+ {
+ const SAMPLETYPE *ptr;
+
+ ptr = src + j;
+
+ for (i = 0; i < length; i ++)
+ {
+ SAMPLETYPE coef=filterCoeffs[i];
+ for (c = 0; c < numChannels; c ++)
+ {
+ sum[c] += ptr[0] * coef;
+ ptr ++;
+ }
+ }
+
+ for (c = 0; c < numChannels; c ++)
+ {
+#ifdef SOUNDTOUCH_INTEGER_SAMPLES
+ sum[c] >>= resultDivFactor;
+#else
+ sum[c] *= dScaler;
+#endif // SOUNDTOUCH_INTEGER_SAMPLES
+ *dest = (SAMPLETYPE)sum[c];
+ dest++;
+ sum[c] = 0;
+ }
+ }
+ return numSamples - length;
+}
+
+
// Set filter coeffiecients and length.
//
// Throws an exception if filter length isn't divisible by 8
@@ -201,16 +255,25 @@ uint FIRFilter::getLength() const
// smaller than the amount of input samples.
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
{
- assert(numChannels == 1 || numChannels == 2);
-
assert(length > 0);
assert(lengthDiv8 * 8 == length);
+
if (numSamples < length) return 0;
- if (numChannels == 2)
+
+#ifndef USE_MULTICH_ALWAYS
+ if (numChannels == 1)
{
- return evaluateFilterStereo(dest, src, numSamples);
- } else {
return evaluateFilterMono(dest, src, numSamples);
+ }
+ else if (numChannels == 2)
+ {
+ return evaluateFilterStereo(dest, src, numSamples);
+ }
+ else
+#endif // USE_MULTICH_ALWAYS
+ {
+ assert(numChannels > 0);
+ return evaluateFilterMulti(dest, src, numSamples, numChannels);
}
}
diff --git a/source/SoundTouch/FIRFilter.h b/source/SoundTouch/FIRFilter.h
index fcee72a..622b9c4 100644
--- a/source/SoundTouch/FIRFilter.h
+++ b/source/SoundTouch/FIRFilter.h
@@ -71,6 +71,7 @@ protected:
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) const;
+ virtual uint evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const;
public:
FIRFilter();
diff --git a/source/SoundTouch/RateTransposer.cpp b/source/SoundTouch/RateTransposer.cpp
index 772e95b..6913972 100644
--- a/source/SoundTouch/RateTransposer.cpp
+++ b/source/SoundTouch/RateTransposer.cpp
@@ -55,17 +55,17 @@ class RateTransposerInteger : public RateTransposer
protected:
int iSlopeCount;
int iRate;
- SAMPLETYPE sPrevSampleL, sPrevSampleR;
+ SAMPLETYPE *sPrevSample;
virtual void resetRegisters();
- virtual uint transposeStereo(SAMPLETYPE *dest,
+ virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
- virtual uint transposeMono(SAMPLETYPE *dest,
+ virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
-
+ virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples);
public:
RateTransposerInteger();
virtual ~RateTransposerInteger();
@@ -83,16 +83,17 @@ class RateTransposerFloat : public RateTransposer
{
protected:
float fSlopeCount;
- SAMPLETYPE sPrevSampleL, sPrevSampleR;
+ SAMPLETYPE *sPrevSample;
virtual void resetRegisters();
- virtual uint transposeStereo(SAMPLETYPE *dest,
+ virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
- virtual uint transposeMono(SAMPLETYPE *dest,
+ virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
+ virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples);
public:
RateTransposerFloat();
@@ -260,7 +261,7 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
- if (count == 0) return;
+ if (count == 0) return;
// Remove the filtered samples from 'storeBuffer'
storeBuffer.receiveSamples(count);
@@ -308,15 +309,22 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
// Transposes the sample rate of the given samples using linear interpolation.
// Returns the number of samples returned in the "dest" buffer
-inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+inline int RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
- if (numChannels == 2)
+#ifndef USE_MULTICH_ALWAYS
+ if (numChannels == 1)
+ {
+ return transposeMono(dest, src, nSamples);
+ }
+ else if (numChannels == 2)
{
return transposeStereo(dest, src, nSamples);
}
else
+#endif // USE_MULTICH_ALWAYS
{
- return transposeMono(dest, src, nSamples);
+ assert(numChannels > 0);
+ return transposeMulti(dest, src, nSamples);
}
}
@@ -327,7 +335,7 @@ void RateTransposer::setChannels(int nChannels)
assert(nChannels > 0);
if (numChannels == nChannels) return;
- assert(nChannels == 1 || nChannels == 2);
+// assert(nChannels == 1 || nChannels == 2);
numChannels = nChannels;
storeBuffer.setChannels(numChannels);
@@ -371,6 +379,7 @@ RateTransposerInteger::RateTransposerInteger() : RateTransposer()
{
// Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions.
+ sPrevSample=0;
RateTransposerInteger::resetRegisters();
RateTransposerInteger::setRate(1.0f);
}
@@ -378,14 +387,16 @@ RateTransposerInteger::RateTransposerInteger() : RateTransposer()
RateTransposerInteger::~RateTransposerInteger()
{
+ if (sPrevSample) delete[] sPrevSample;
}
void RateTransposerInteger::resetRegisters()
{
iSlopeCount = 0;
- sPrevSampleL =
- sPrevSampleR = 0;
+ if (sPrevSample) delete[] sPrevSample;
+ sPrevSample = new SAMPLETYPE[numChannels];
+ memset(sPrevSample, 0, numChannels*sizeof(*sPrevSample));
}
@@ -393,21 +404,21 @@ void RateTransposerInteger::resetRegisters()
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
-uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+int RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
- unsigned int i, used;
+ int i, remain;
LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work
- used = 0;
+ remain = nSamples - 1;
i = 0;
// Process the last sample saved from the previous call first...
while (iSlopeCount <= SCALE)
{
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
- temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
+ temp = vol1 * sPrevSample[0] + iSlopeCount * src[0];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
@@ -420,11 +431,12 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
- used ++;
- if (used >= nSamples - 1) goto end;
+ src ++;
+ remain --;
+ if (remain == 0) goto end;
}
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
- temp = src[used] * vol1 + iSlopeCount * src[used + 1];
+ temp = src[0] * vol1 + iSlopeCount * src[1];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
@@ -432,7 +444,7 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
}
end:
// Store the last sample for the next round
- sPrevSampleL = src[nSamples - 1];
+ sPrevSample[0] = src[0];
return i;
}
@@ -441,23 +453,23 @@ end:
// Transposes the sample rate of the given samples using linear interpolation.
// 'Stereo' version of the routine. Returns the number of samples returned in
// the "dest" buffer
-uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+int RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
- unsigned int srcPos, i, used;
+ int i, remain;
LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work
- used = 0;
+ remain = nSamples - 1;
i = 0;
// Process the last sample saved from the sPrevSampleLious call first...
while (iSlopeCount <= SCALE)
{
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
- temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
+ temp = vol1 * sPrevSample[0] + iSlopeCount * src[0];
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
- temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
+ temp = vol1 * sPrevSample[1] + iSlopeCount * src[1];
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
@@ -470,14 +482,14 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
- used ++;
- if (used >= nSamples - 1) goto end;
+ remain --;
+ src += 2;
+ if (remain == 0) goto end;
}
- srcPos = 2 * used;
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
- temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
+ temp = src[0] * vol1 + iSlopeCount * src[2];
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
- temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
+ temp = src[1] * vol1 + iSlopeCount * src[3];
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
@@ -485,13 +497,68 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
}
end:
// Store the last sample for the next round
- sPrevSampleL = src[2 * nSamples - 2];
- sPrevSampleR = src[2 * nSamples - 1];
+ sPrevSample[0] = src[0];
+ sPrevSample[1] = src[1];
return i;
}
+int RateTransposerInteger::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ int i, remaining;
+ LONG_SAMPLETYPE temp, vol1;
+
+ if (nSamples == 0) return 0; // no samples, no work
+
+ remaining = nSamples - 1;
+ i = 0;
+
+ // Process the last sample saved from the sPrevSampleLious call first...
+ while (iSlopeCount <= SCALE)
+ {
+ for (int c = 0; c < numChannels; c ++)
+ {
+ vol1 = (SCALE - iSlopeCount);
+ temp = vol1 * sPrevSample[c] + iSlopeCount * src[c];
+ *dest = (SAMPLETYPE)(temp / SCALE);
+ dest ++;
+ }
+ i++;
+
+ iSlopeCount += iRate;
+ }
+ // now always (iSlopeCount > SCALE)
+ iSlopeCount -= SCALE;
+
+ while (1)
+ {
+ while (iSlopeCount > SCALE)
+ {
+ iSlopeCount -= SCALE;
+ src += numChannels;
+ remaining --;
+ if (remaining == 0) goto end;
+ }
+
+ for (int c = 0; c < numChannels; c ++)
+ {
+ vol1 = (SCALE - iSlopeCount);
+ temp = src[c] * vol1 + iSlopeCount * src[c + numChannels];
+ *dest = (SAMPLETYPE)(temp / SCALE);
+ dest++;
+ }
+
+ i++;
+ iSlopeCount += iRate;
+ }
+end:
+ // Store the last sample for the next round
+ memcpy(sPrevSample, src, numChannels * sizeof(SAMPLETYPE));
+
+ return i;
+}
+
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposerInteger::setRate(float newRate)
@@ -512,6 +579,7 @@ RateTransposerFloat::RateTransposerFloat() : RateTransposer()
{
// Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions.
+ sPrevSample=0;
RateTransposerFloat::resetRegisters();
RateTransposerFloat::setRate(1.0f);
}
@@ -519,14 +587,16 @@ RateTransposerFloat::RateTransposerFloat() : RateTransposer()
RateTransposerFloat::~RateTransposerFloat()
{
+ if (sPrevSample) delete[] sPrevSample;
}
void RateTransposerFloat::resetRegisters()
{
fSlopeCount = 0;
- sPrevSampleL =
- sPrevSampleR = 0;
+ if (sPrevSample) delete[] sPrevSample;
+ sPrevSample = new SAMPLETYPE[numChannels];
+ memset(sPrevSample, 0, numChannels*sizeof(*sPrevSample));
}
@@ -534,17 +604,17 @@ void RateTransposerFloat::resetRegisters()
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
-uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+int RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
- unsigned int i, used;
+ int i, remain;
- used = 0;
+ remain = 0;
i = 0;
// Process the last sample saved from the previous call first...
while (fSlopeCount <= 1.0f)
{
- dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
+ dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[0] + fSlopeCount * src[0]);
i++;
fSlopeCount += fRate;
}
@@ -557,17 +627,18 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
- used ++;
- if (used >= nSamples - 1) goto end;
+ src ++;
+ remain --;
+ if (remain == 0) goto end;
}
- dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
+ dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[0] + fSlopeCount * src[1]);
i++;
fSlopeCount += fRate;
}
}
end:
// Store the last sample for the next round
- sPrevSampleL = src[nSamples - 1];
+ sPrevSample[0] = src[0];
return i;
}
@@ -576,20 +647,20 @@ end:
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
-uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+int RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
- unsigned int srcPos, i, used;
+ int i, remain;
if (nSamples == 0) return 0; // no samples, no work
- used = 0;
+ remain = nSamples - 1;
i = 0;
// Process the last sample saved from the sPrevSampleLious call first...
while (fSlopeCount <= 1.0f)
{
- dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
- dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
+ dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[0] + fSlopeCount * src[0]);
+ dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[1] + fSlopeCount * src[1]);
i++;
fSlopeCount += fRate;
}
@@ -603,15 +674,15 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
- used ++;
- if (used >= nSamples - 1) goto end;
+ remain --;
+ src += 2;
+ if (remain == 0) goto end;
}
- srcPos = 2 * used;
- dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
- + fSlopeCount * src[srcPos + 2]);
- dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
- + fSlopeCount * src[srcPos + 3]);
+ dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[0]
+ + fSlopeCount * src[2]);
+ dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[1]
+ + fSlopeCount * src[3]);
i++;
fSlopeCount += fRate;
@@ -619,8 +690,59 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
}
end:
// Store the last sample for the next round
- sPrevSampleL = src[2 * nSamples - 2];
- sPrevSampleR = src[2 * nSamples - 1];
+ sPrevSample[0] = src[0];
+ sPrevSample[1] = src[1];
+
+ return i;
+}
+
+int RateTransposerFloat::transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
+{
+ int i, remaining;
+
+ if (nSamples == 0) return 0; // no samples, no work
+
+ remaining = nSamples - 1;
+ i = 0;
+
+ // Process the last sample saved from the sPrevSampleLious call first...
+ while (fSlopeCount <= 1.0f)
+ {
+ for (int c = 0; c < numChannels; c ++)
+ {
+ *dest = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[c] + fSlopeCount * src[c]);
+ dest ++;
+ }
+ i++;
+ fSlopeCount += fRate;
+ }
+ // now always (iSlopeCount > 1.0f)
+ fSlopeCount -= 1.0f;
+
+ while (remaining > 0)
+ {
+ while (fSlopeCount > 1.0f)
+ {
+ fSlopeCount -= 1.0f;
+ src += numChannels;
+ remaining --;
+ if (remaining == 0) goto end;
+ }
+
+ for (int c = 0; c < numChannels; c ++)
+ {
+ *dest = (SAMPLETYPE)((1.0f - fSlopeCount) * src[c]
+ + fSlopeCount * src[c + numChannels]);
+ dest++;
+ }
+
+ i++;
+ fSlopeCount += fRate;
+ }
+
+end:
+ // Store the last sample for the next round
+ memcpy(sPrevSample, src, numChannels * sizeof(SAMPLETYPE));
return i;
}
diff --git a/source/SoundTouch/RateTransposer.h b/source/SoundTouch/RateTransposer.h
index 9cd1c6f..7c8f67b 100644
--- a/source/SoundTouch/RateTransposer.h
+++ b/source/SoundTouch/RateTransposer.h
@@ -85,13 +85,14 @@ protected:
virtual void resetRegisters() = 0;
- virtual uint transposeStereo(SAMPLETYPE *dest,
+ virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) = 0;
- virtual uint transposeMono(SAMPLETYPE *dest,
+ virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) = 0;
- inline uint transpose(SAMPLETYPE *dest,
+ virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples) = 0;
+ inline int transpose(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
diff --git a/source/SoundTouch/SoundTouch.cpp b/source/SoundTouch/SoundTouch.cpp
index 79ce263..cd7693b 100644
--- a/source/SoundTouch/SoundTouch.cpp
+++ b/source/SoundTouch/SoundTouch.cpp
@@ -143,10 +143,11 @@ uint SoundTouch::getVersionId()
// Sets the number of channels, 1 = mono, 2 = stereo
void SoundTouch::setChannels(uint numChannels)
{
- if (numChannels != 1 && numChannels != 2)
+ /*if (numChannels != 1 && numChannels != 2)
{
- ST_THROW_RT_ERROR("Illegal number of channels");
- }
+ //ST_THROW_RT_ERROR("Illegal number of channels");
+ return;
+ }*/
channels = numChannels;
pRateTransposer->setChannels((int)numChannels);
pTDStretch->setChannels((int)numChannels);
@@ -347,7 +348,7 @@ void SoundTouch::flush()
int i;
int nUnprocessed;
int nOut;
- SAMPLETYPE buff[64*2]; // note: allocate 2*64 to cater 64 sample frames of stereo sound
+ SAMPLETYPE *buff=(SAMPLETYPE*)alloca(64*channels*sizeof(SAMPLETYPE));
// check how many samples still await processing, and scale
// that by tempo & rate to get expected output sample count
diff --git a/source/SoundTouch/SoundTouch.vcproj b/source/SoundTouch/SoundTouch.vcproj
index e872e14..56d0651 100644
--- a/source/SoundTouch/SoundTouch.vcproj
+++ b/source/SoundTouch/SoundTouch.vcproj
@@ -1,123 +1,172 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="7.10"
+ Version="9.00"
Name="SoundTouch"
ProjectGUID="{68A5DD20-7057-448B-8FE0-B6AC8D205509}"
- SccProjectName=""
- SccLocalPath="">
+ TargetFrameworkVersion="131072"
+ >
<Platforms>
<Platform
- Name="Win32"/>
+ Name="Win32"
+ />
</Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
- EnableIntrinsicFunctions="TRUE"
+ EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="2"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/SoundTouch.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
DebugInformationFormat="0"
- CompileAs="0"/>
+ CompileAs="0"
+ />
<Tool
- Name="VCCustomBuildTool"/>
+ Name="VCManagedResourceCompilerTool"
+ />
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\Release\SoundTouch.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- CommandLine="copy .\Release\SoundTouch.lib ..\..\lib\"/>
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1035"
+ />
<Tool
- Name="VCPreBuildEventTool"/>
+ Name="VCPreLinkEventTool"
+ />
<Tool
- Name="VCPreLinkEventTool"/>
+ Name="VCLibrarianTool"
+ OutputFile=".\Release\SoundTouch.lib"
+ SuppressStartupBanner="true"
+ />
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1035"/>
+ Name="VCALinkTool"
+ />
<Tool
- Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCXDCMakeTool"
+ />
<Tool
- Name="VCXMLDataGeneratorTool"/>
+ Name="VCBscMakeTool"
+ />
<Tool
- Name="VCManagedWrapperGeneratorTool"/>
+ Name="VCFxCopTool"
+ />
<Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ Name="VCPostBuildEventTool"
+ CommandLine="copy .\Release\SoundTouch.lib ..\..\lib\"
+ />
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="2"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/SoundTouch.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
- SuppressStartupBanner="TRUE"
+ SuppressStartupBanner="true"
DebugInformationFormat="4"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="Debug\SoundTouchD.lib"
- SuppressStartupBanner="TRUE"/>
+ CompileAs="0"
+ />
<Tool
- Name="VCMIDLTool"/>
+ Name="VCManagedResourceCompilerTool"
+ />
<Tool
- Name="VCPostBuildEventTool"
- CommandLine="copy .\Debug\SoundTouchD.lib ..\..\lib\"/>
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1035"
+ />
<Tool
- Name="VCPreBuildEventTool"/>
+ Name="VCPreLinkEventTool"
+ />
<Tool
- Name="VCPreLinkEventTool"/>
+ Name="VCLibrarianTool"
+ OutputFile="Debug\SoundTouchD.lib"
+ SuppressStartupBanner="true"
+ />
<Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1035"/>
+ Name="VCALinkTool"
+ />
<Tool
- Name="VCWebServiceProxyGeneratorTool"/>
+ Name="VCXDCMakeTool"
+ />
<Tool
- Name="VCXMLDataGeneratorTool"/>
+ Name="VCBscMakeTool"
+ />
<Tool
- Name="VCManagedWrapperGeneratorTool"/>
+ Name="VCFxCopTool"
+ />
<Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ Name="VCPostBuildEventTool"
+ CommandLine="copy .\Debug\SoundTouchD.lib ..\..\lib\"
+ />
</Configuration>
</Configurations>
<References>
@@ -125,188 +174,236 @@
<Files>
<Filter
Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
<File
- RelativePath="AAFilter.cpp">
+ RelativePath="AAFilter.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<File
- RelativePath=".\cpu_detect_x86.cpp">
+ RelativePath=".\cpu_detect_x86.cpp"
+ >
</File>
<File
- RelativePath="FIFOSampleBuffer.cpp">
+ RelativePath="FIFOSampleBuffer.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<File
- RelativePath="FIRFilter.cpp">
+ RelativePath="FIRFilter.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<File
- RelativePath=".\mmx_optimized.cpp">
+ RelativePath=".\mmx_optimized.cpp"
+ >
</File>
<File
- RelativePath="RateTransposer.cpp">
+ RelativePath="RateTransposer.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<File
- RelativePath="SoundTouch.cpp">
+ RelativePath="SoundTouch.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<File
- RelativePath=".\sse_optimized.cpp">
+ RelativePath=".\sse_optimized.cpp"
+ >
</File>
<File
- RelativePath="TDStretch.cpp">
+ RelativePath="TDStretch.cpp"
+ >
<FileConfiguration
- Name="Release|Win32">
+ Name="Release|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
+ PreprocessorDefinitions=""
+ />
</FileConfiguration>
<FileConfiguration
- Name="Debug|Win32">
+ Name="Debug|Win32"
+ >
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
- BrowseInformation="1"/>
+ BrowseInformation="1"
+ />
</FileConfiguration>
</File>
<Filter
Name="bpm"
- Filter="">
+ >
<File
- RelativePath=".\BPMDetect.cpp">
+ RelativePath=".\BPMDetect.cpp"
+ >
</File>
<File
- RelativePath=".\PeakFinder.cpp">
+ RelativePath=".\PeakFinder.cpp"
+ >
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
+ Filter="h;hpp;hxx;hm;inl"
+ >
<File
- RelativePath="AAFilter.h">
+ RelativePath="AAFilter.h"
+ >
</File>
<File
- RelativePath="..\..\include\BPMDetect.h">
+ RelativePath="..\..\include\BPMDetect.h"
+ >
</File>
<File
- RelativePath="cpu_detect.h">
+ RelativePath="cpu_detect.h"
+ >
</File>
<File
- RelativePath="..\..\include\FIFOSampleBuffer.h">
+ RelativePath="..\..\include\FIFOSampleBuffer.h"
+ >
</File>
<File
- RelativePath="..\..\include\FIFOSamplePipe.h">
+ RelativePath="..\..\include\FIFOSamplePipe.h"
+ >
</File>
<File
- RelativePath="FIRFilter.h">
+ RelativePath="FIRFilter.h"
+ >
</File>
<File
- RelativePath=".\PeakFinder.h">
+ RelativePath=".\PeakFinder.h"
+ >
</File>
<File
- RelativePath="RateTransposer.h">
+ RelativePath="RateTransposer.h"
+ >
</File>
<File
- RelativePath="..\..\include\SoundTouch.h">
+ RelativePath="..\..\include\SoundTouch.h"
+ >
</File>
<File
- RelativePath="..\..\include\STTypes.h">
+ RelativePath="..\..\include\STTypes.h"
+ >
</File>
<File
- RelativePath="TDStretch.h">
+ RelativePath="TDStretch.h"
+ >
</File>
</Filter>
</Files>
diff --git a/source/SoundTouch/TDStretch.cpp b/source/SoundTouch/TDStretch.cpp
index e272811..f2060bc 100644
--- a/source/SoundTouch/TDStretch.cpp
+++ b/source/SoundTouch/TDStretch.cpp
@@ -212,7 +212,7 @@ void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
void TDStretch::clearMidBuffer()
{
- memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
+ memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
}
@@ -265,14 +265,23 @@ int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
// of 'ovlPos'.
inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
{
- if (channels == 2)
+#ifndef USE_MULTICH_ALWAYS
+ if (channels == 1)
{
- // stereo sound
- overlapStereo(pOutput, pInput + 2 * ovlPos);
- } else {
// mono sound.
overlapMono(pOutput, pInput + ovlPos);
}
+ else if (channels == 2)
+ {
+ // stereo sound
+ overlapStereo(pOutput, pInput + 2 * ovlPos);
+ }
+ else
+#endif // USE_MULTICH_ALWAYS
+ {
+ assert(channels > 0);
+ overlapMulti(pOutput, pInput + channels * ovlPos);
+ }
}
@@ -458,11 +467,15 @@ void TDStretch::setChannels(int numChannels)
{
assert(numChannels > 0);
if (channels == numChannels) return;
- assert(numChannels == 1 || numChannels == 2);
+// assert(numChannels == 1 || numChannels == 2);
channels = numChannels;
inputBuffer.setChannels(channels);
outputBuffer.setChannels(channels);
+
+ // re-init overlap/buffer
+ overlapLength=0;
+ setParameters(sampleRate);
}
@@ -666,6 +679,27 @@ void TDStretch::overlapStereo(short *poutput, const short *input) const
}
}
+
+// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Multi'
+// version of the routine.
+void TDStretch::overlapMulti(SAMPLETYPE *poutput, const SAMPLETYPE *input) const
+{
+ SAMPLETYPE m1=(SAMPLETYPE)0;
+ SAMPLETYPE m2;
+ int i=0;
+
+ for (m2 = (SAMPLETYPE)overlapLength; m2; m2 --)
+ {
+ for (int c = 0; c < channels; c ++)
+ {
+ poutput[i] = (input[i] * m1 + pMidBuffer[i] * m2) / overlapLength;
+ i++;
+ }
+
+ m1++;
+ }
+}
+
// Calculates the x having the closest 2^x value for the given value
static int _getClosest2Power(double value)
{
@@ -760,6 +794,34 @@ void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
}
+// Overlaps samples in 'midBuffer' with the samples in 'input'.
+void TDStretch::overlapMulti(float *pOutput, const float *pInput) const
+{
+ int i;
+ float fScale;
+ float f1;
+ float f2;
+
+ fScale = 1.0f / (float)overlapLength;
+
+ f1 = 0;
+ f2 = 1.0f;
+
+ i=0;
+ for (int i2 = 0; i2 < overlapLength; i2 ++)
+ {
+ // note: Could optimize this slightly by taking into account that always channels > 2
+ for (int c = 0; c < channels; c ++)
+ {
+ pOutput[i] = pInput[i] * f1 + pMidBuffer[i] * f2;
+ i++;
+ }
+ f1 += fScale;
+ f2 -= fScale;
+ }
+}
+
+
/// Calculates overlapInMsec period length in samples.
void TDStretch::calculateOverlapLength(int overlapInMsec)
{
diff --git a/source/SoundTouch/TDStretch.h b/source/SoundTouch/TDStretch.h
index 12ce2cf..c0f2853 100644
--- a/source/SoundTouch/TDStretch.h
+++ b/source/SoundTouch/TDStretch.h
@@ -147,6 +147,7 @@ protected:
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
+ virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
void clearMidBuffer();
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;