Added support for multi-channel audio

This commit is contained in:
oparviai 2013-06-12 15:24:44 +00:00
parent 9bb265e3cd
commit 8c65661b91
13 changed files with 734 additions and 298 deletions

View File

@ -15,8 +15,8 @@
</head> </head>
<body class="normal"> <body class="normal">
<hr> <hr>
<h1>SoundTouch audio processing library v1.7.1</h1> <h1>SoundTouch audio processing library v1.7.2 (developing)</h1>
<p class="normal">SoundTouch library Copyright Š Olli Parviainen 2001-2012 </p> <p class="normal">SoundTouch library Copyright © Olli Parviainen 2001-2013 </p>
<hr> <hr>
<h2>1. Introduction </h2> <h2>1. Introduction </h2>
<p>SoundTouch is an open-source audio processing library that allows <p>SoundTouch is an open-source audio processing library that allows
@ -513,6 +513,10 @@ and estimates the BPM rate:</p>
<hr> <hr>
<h2>5. Change History</h2> <h2>5. Change History</h2>
<h3>5.1. SoundTouch library Change History </h3> <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> <p><b>1.7.1:</b></p>
<ul> <ul>
<li>Added files for Android compilation <li>Added files for Android compilation

View File

@ -78,6 +78,13 @@ namespace soundtouch
//#undef SOUNDTOUCH_INTEGER_SAMPLES //#undef SOUNDTOUCH_INTEGER_SAMPLES
//#undef SOUNDTOUCH_FLOAT_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__)) #if (defined(__SOFTFP__))
// For Android compilation: Force use of Integer samples in case that // For Android compilation: Force use of Integer samples in case that
// compilation uses soft-floating point emulation - soft-fp is way too slow // compilation uses soft-floating point emulation - soft-fp is way too slow

View File

@ -79,10 +79,10 @@ namespace soundtouch
{ {
/// Soundtouch library version string /// Soundtouch library version string
#define SOUNDTOUCH_VERSION "1.7.1" #define SOUNDTOUCH_VERSION "1.7.2 (dev)"
/// SoundTouch library version id /// SoundTouch library version id
#define SOUNDTOUCH_VERSION_ID (10701) #define SOUNDTOUCH_VERSION_ID (10702)
// //
// Available setting IDs for the 'setSetting' & 'get_setting' functions: // Available setting IDs for the 'setSetting' & 'get_setting' functions:

View File

@ -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}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundstretch", "soundstretch.vcproj", "{5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{68A5DD20-7057-448B-8FE0-B6AC8D205509} = {68A5DD20-7057-448B-8FE0-B6AC8D205509} {68A5DD20-7057-448B-8FE0-B6AC8D205509} = {68A5DD20-7057-448B-8FE0-B6AC8D205509}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\SoundTouch\SoundTouch.vcproj", "{68A5DD20-7057-448B-8FE0-B6AC8D205509}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "..\SoundTouch\SoundTouch.vcproj", "{68A5DD20-7057-448B-8FE0-B6AC8D205509}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug = Debug Debug|Win32 = Debug|Win32
Release = Release Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectDependencies) = 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 EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution GlobalSection(SolutionProperties) = preSolution
{5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}.Debug.ActiveCfg = Debug|Win32 HideSolutionNode = FALSE
{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
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -1,30 +1,53 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="9.00"
Name="soundstretch" Name="soundstretch"
SccProjectName="" ProjectGUID="{5AACDFFA-D491-44B8-A332-DA7ACCAAF2AF}"
SccLocalPath=""> TargetFrameworkVersion="131072"
>
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"
/>
</Platforms> </Platforms>
<ToolFiles>
</ToolFiles>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory=".\Debug" OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug" IntermediateDirectory=".\Debug"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"> CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/soundstretch.tlb"
HeaderFileName=""
/>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\include" AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="1"
StructMemberAlignment="5" StructMemberAlignment="5"
PrecompiledHeaderFile=".\Debug/soundstretch.pch" PrecompiledHeaderFile=".\Debug/soundstretch.pch"
AssemblerListingLocation=".\Debug/" AssemblerListingLocation=".\Debug/"
@ -32,117 +55,155 @@
ProgramDataBaseFileName=".\Debug/" ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1" BrowseInformation="1"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
DebugInformationFormat="4" DebugInformationFormat="4"
CompileAs="0"/> CompileAs="0"
/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1035"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="SoundTouchD.lib" AdditionalDependencies="SoundTouchD.lib"
OutputFile="Debug/soundstretchD.exe" OutputFile="Debug/soundstretchD.exe"
LinkIncremental="2" LinkIncremental="2"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib" AdditionalLibraryDirectories="..\..\lib"
IgnoreDefaultLibraryNames="libc" IgnoreDefaultLibraryNames="libc"
GenerateDebugInformation="TRUE" GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/soundstretchD.pdb" ProgramDatabaseFile=".\Debug/soundstretchD.pdb"
GenerateMapFile="TRUE" GenerateMapFile="true"
MapFileName=".\Debug/soundstretchD.map" MapFileName=".\Debug/soundstretchD.map"
SubSystem="1" SubSystem="1"
TargetMachine="1"/> RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCALinkTool"
TypeLibraryName=".\Debug/soundstretch.tlb" />
HeaderFileName=""/> <Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
CommandLine="copy Debug\soundstretchD.exe ..\..\bin\"/> CommandLine="copy Debug\soundstretchD.exe ..\..\bin\"
<Tool />
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1035"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory=".\Release" OutputDirectory=".\Release"
IntermediateDirectory=".\Release" IntermediateDirectory=".\Release"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"> CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/soundstretch.tlb"
HeaderFileName=""
/>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="3" Optimization="3"
GlobalOptimizations="FALSE"
InlineFunctionExpansion="2" InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE" EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include" AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
StringPooling="TRUE" StringPooling="true"
RuntimeLibrary="4" RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\Release/soundstretch.pch" PrecompiledHeaderFile=".\Release/soundstretch.pch"
AssemblerListingLocation=".\Release/" AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/" ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/" ProgramDataBaseFileName=".\Release/"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
DebugInformationFormat="0" DebugInformationFormat="0"
CompileAs="0"/> CompileAs="0"
/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1035"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="SoundTouch.lib" AdditionalDependencies="SoundTouch.lib"
OutputFile=".\Release/soundstretch.exe" OutputFile=".\Release/soundstretch.exe"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib" AdditionalLibraryDirectories="..\..\lib"
GenerateDebugInformation="FALSE" GenerateDebugInformation="false"
GenerateMapFile="TRUE" GenerateMapFile="true"
MapFileName=".\Release/soundstretch.map" MapFileName=".\Release/soundstretch.map"
SubSystem="1" SubSystem="1"
TargetMachine="1"/> RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCALinkTool"
TypeLibraryName=".\Release/soundstretch.tlb" />
HeaderFileName=""/> <Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
CommandLine="copy Release\soundstretch.exe ..\..\bin\"/> CommandLine="copy Release\soundstretch.exe ..\..\bin\"
<Tool />
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1035"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
</Configurations> </Configurations>
<References> <References>
@ -150,84 +211,104 @@
<Files> <Files>
<Filter <Filter
Name="Source Files" 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 <File
RelativePath="main.cpp"> RelativePath="main.cpp"
>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="RunParameters.cpp"> RelativePath="RunParameters.cpp"
>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="WavFile.cpp"> RelativePath="WavFile.cpp"
>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl"> Filter="h;hpp;hxx;hm;inl"
>
<File <File
RelativePath="RunParameters.h"> RelativePath="RunParameters.h"
>
</File> </File>
<File <File
RelativePath="WavFile.h"> RelativePath="WavFile.h"
>
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" 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> </Filter>
</Files> </Files>
<Globals> <Globals>

View File

@ -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. // Set filter coeffiecients and length.
// //
// Throws an exception if filter length isn't divisible by 8 // 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. // smaller than the amount of input samples.
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
{ {
assert(numChannels == 1 || numChannels == 2);
assert(length > 0); assert(length > 0);
assert(lengthDiv8 * 8 == length); assert(lengthDiv8 * 8 == length);
if (numSamples < length) return 0; if (numSamples < length) return 0;
if (numChannels == 2)
#ifndef USE_MULTICH_ALWAYS
if (numChannels == 1)
{
return evaluateFilterMono(dest, src, numSamples);
}
else if (numChannels == 2)
{ {
return evaluateFilterStereo(dest, src, numSamples); return evaluateFilterStereo(dest, src, numSamples);
} else { }
return evaluateFilterMono(dest, src, numSamples); else
#endif // USE_MULTICH_ALWAYS
{
assert(numChannels > 0);
return evaluateFilterMulti(dest, src, numSamples, numChannels);
} }
} }

View File

@ -71,6 +71,7 @@ protected:
virtual uint evaluateFilterMono(SAMPLETYPE *dest, virtual uint evaluateFilterMono(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples) const; uint numSamples) const;
virtual uint evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const;
public: public:
FIRFilter(); FIRFilter();

View File

@ -55,17 +55,17 @@ class RateTransposerInteger : public RateTransposer
protected: protected:
int iSlopeCount; int iSlopeCount;
int iRate; int iRate;
SAMPLETYPE sPrevSampleL, sPrevSampleR; SAMPLETYPE *sPrevSample;
virtual void resetRegisters(); virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest, virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples); uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest, virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples); uint numSamples);
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples);
public: public:
RateTransposerInteger(); RateTransposerInteger();
virtual ~RateTransposerInteger(); virtual ~RateTransposerInteger();
@ -83,16 +83,17 @@ class RateTransposerFloat : public RateTransposer
{ {
protected: protected:
float fSlopeCount; float fSlopeCount;
SAMPLETYPE sPrevSampleL, sPrevSampleR; SAMPLETYPE *sPrevSample;
virtual void resetRegisters(); virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest, virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples); uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest, virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples); uint numSamples);
virtual int transposeMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples);
public: public:
RateTransposerFloat(); RateTransposerFloat();
@ -308,15 +309,22 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
// Transposes the sample rate of the given samples using linear interpolation. // Transposes the sample rate of the given samples using linear interpolation.
// Returns the number of samples returned in the "dest" buffer // 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); return transposeStereo(dest, src, nSamples);
} }
else 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); assert(nChannels > 0);
if (numChannels == nChannels) return; if (numChannels == nChannels) return;
assert(nChannels == 1 || nChannels == 2); // assert(nChannels == 1 || nChannels == 2);
numChannels = nChannels; numChannels = nChannels;
storeBuffer.setChannels(numChannels); storeBuffer.setChannels(numChannels);
@ -371,6 +379,7 @@ RateTransposerInteger::RateTransposerInteger() : RateTransposer()
{ {
// Notice: use local function calling syntax for sake of clarity, // Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions. // to indicate the fact that C++ constructor can't call virtual functions.
sPrevSample=0;
RateTransposerInteger::resetRegisters(); RateTransposerInteger::resetRegisters();
RateTransposerInteger::setRate(1.0f); RateTransposerInteger::setRate(1.0f);
} }
@ -378,14 +387,16 @@ RateTransposerInteger::RateTransposerInteger() : RateTransposer()
RateTransposerInteger::~RateTransposerInteger() RateTransposerInteger::~RateTransposerInteger()
{ {
if (sPrevSample) delete[] sPrevSample;
} }
void RateTransposerInteger::resetRegisters() void RateTransposerInteger::resetRegisters()
{ {
iSlopeCount = 0; iSlopeCount = 0;
sPrevSampleL = if (sPrevSample) delete[] sPrevSample;
sPrevSampleR = 0; 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. // Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in // 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer // 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; LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work if (nSamples == 0) return 0; // no samples, no work
used = 0; remain = nSamples - 1;
i = 0; i = 0;
// Process the last sample saved from the previous call first... // Process the last sample saved from the previous call first...
while (iSlopeCount <= SCALE) while (iSlopeCount <= SCALE)
{ {
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; temp = vol1 * sPrevSample[0] + iSlopeCount * src[0];
dest[i] = (SAMPLETYPE)(temp / SCALE); dest[i] = (SAMPLETYPE)(temp / SCALE);
i++; i++;
iSlopeCount += iRate; iSlopeCount += iRate;
@ -420,11 +431,12 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
while (iSlopeCount > SCALE) while (iSlopeCount > SCALE)
{ {
iSlopeCount -= SCALE; iSlopeCount -= SCALE;
used ++; src ++;
if (used >= nSamples - 1) goto end; remain --;
if (remain == 0) goto end;
} }
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 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); dest[i] = (SAMPLETYPE)(temp / SCALE);
i++; i++;
@ -432,7 +444,7 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
} }
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[nSamples - 1]; sPrevSample[0] = src[0];
return i; return i;
} }
@ -441,23 +453,23 @@ end:
// Transposes the sample rate of the given samples using linear interpolation. // Transposes the sample rate of the given samples using linear interpolation.
// 'Stereo' version of the routine. Returns the number of samples returned in // 'Stereo' version of the routine. Returns the number of samples returned in
// the "dest" buffer // 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; LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work if (nSamples == 0) return 0; // no samples, no work
used = 0; remain = nSamples - 1;
i = 0; i = 0;
// Process the last sample saved from the sPrevSampleLious call first... // Process the last sample saved from the sPrevSampleLious call first...
while (iSlopeCount <= SCALE) while (iSlopeCount <= SCALE)
{ {
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = vol1 * sPrevSampleL + iSlopeCount * src[0]; temp = vol1 * sPrevSample[0] + iSlopeCount * src[0];
dest[2 * i] = (SAMPLETYPE)(temp / SCALE); 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); dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++; i++;
iSlopeCount += iRate; iSlopeCount += iRate;
@ -470,14 +482,14 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
while (iSlopeCount > SCALE) while (iSlopeCount > SCALE)
{ {
iSlopeCount -= SCALE; iSlopeCount -= SCALE;
used ++; remain --;
if (used >= nSamples - 1) goto end; src += 2;
if (remain == 0) goto end;
} }
srcPos = 2 * used;
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount); 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); 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); dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++; i++;
@ -485,13 +497,68 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
} }
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[2 * nSamples - 2]; sPrevSample[0] = src[0];
sPrevSampleR = src[2 * nSamples - 1]; sPrevSample[1] = src[1];
return i; 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 // Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates. // iRate, larger faster iRates.
void RateTransposerInteger::setRate(float newRate) void RateTransposerInteger::setRate(float newRate)
@ -512,6 +579,7 @@ RateTransposerFloat::RateTransposerFloat() : RateTransposer()
{ {
// Notice: use local function calling syntax for sake of clarity, // Notice: use local function calling syntax for sake of clarity,
// to indicate the fact that C++ constructor can't call virtual functions. // to indicate the fact that C++ constructor can't call virtual functions.
sPrevSample=0;
RateTransposerFloat::resetRegisters(); RateTransposerFloat::resetRegisters();
RateTransposerFloat::setRate(1.0f); RateTransposerFloat::setRate(1.0f);
} }
@ -519,14 +587,16 @@ RateTransposerFloat::RateTransposerFloat() : RateTransposer()
RateTransposerFloat::~RateTransposerFloat() RateTransposerFloat::~RateTransposerFloat()
{ {
if (sPrevSample) delete[] sPrevSample;
} }
void RateTransposerFloat::resetRegisters() void RateTransposerFloat::resetRegisters()
{ {
fSlopeCount = 0; fSlopeCount = 0;
sPrevSampleL = if (sPrevSample) delete[] sPrevSample;
sPrevSampleR = 0; 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. // Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in // 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer // 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; i = 0;
// Process the last sample saved from the previous call first... // Process the last sample saved from the previous call first...
while (fSlopeCount <= 1.0f) 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++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
} }
@ -557,17 +627,18 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
while (fSlopeCount > 1.0f) while (fSlopeCount > 1.0f)
{ {
fSlopeCount -= 1.0f; fSlopeCount -= 1.0f;
used ++; src ++;
if (used >= nSamples - 1) goto end; 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++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
} }
} }
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[nSamples - 1]; sPrevSample[0] = src[0];
return i; return i;
} }
@ -576,20 +647,20 @@ end:
// Transposes the sample rate of the given samples using linear interpolation. // Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in // 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer // 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 if (nSamples == 0) return 0; // no samples, no work
used = 0; remain = nSamples - 1;
i = 0; i = 0;
// Process the last sample saved from the sPrevSampleLious call first... // Process the last sample saved from the sPrevSampleLious call first...
while (fSlopeCount <= 1.0f) while (fSlopeCount <= 1.0f)
{ {
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]); dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[0] + fSlopeCount * src[0]);
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]); dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSample[1] + fSlopeCount * src[1]);
i++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
} }
@ -603,15 +674,15 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
while (fSlopeCount > 1.0f) while (fSlopeCount > 1.0f)
{ {
fSlopeCount -= 1.0f; fSlopeCount -= 1.0f;
used ++; remain --;
if (used >= nSamples - 1) goto end; src += 2;
if (remain == 0) goto end;
} }
srcPos = 2 * used;
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos] dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[0]
+ fSlopeCount * src[srcPos + 2]); + fSlopeCount * src[2]);
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1] dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[1]
+ fSlopeCount * src[srcPos + 3]); + fSlopeCount * src[3]);
i++; i++;
fSlopeCount += fRate; fSlopeCount += fRate;
@ -619,8 +690,59 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
} }
end: end:
// Store the last sample for the next round // Store the last sample for the next round
sPrevSampleL = src[2 * nSamples - 2]; sPrevSample[0] = src[0];
sPrevSampleR = src[2 * nSamples - 1]; 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; return i;
} }

View File

@ -85,13 +85,14 @@ protected:
virtual void resetRegisters() = 0; virtual void resetRegisters() = 0;
virtual uint transposeStereo(SAMPLETYPE *dest, virtual int transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples) = 0; uint numSamples) = 0;
virtual uint transposeMono(SAMPLETYPE *dest, virtual int transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src, const SAMPLETYPE *src,
uint numSamples) = 0; 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, const SAMPLETYPE *src,
uint numSamples); uint numSamples);

View File

@ -143,10 +143,11 @@ uint SoundTouch::getVersionId()
// Sets the number of channels, 1 = mono, 2 = stereo // Sets the number of channels, 1 = mono, 2 = stereo
void SoundTouch::setChannels(uint numChannels) 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; channels = numChannels;
pRateTransposer->setChannels((int)numChannels); pRateTransposer->setChannels((int)numChannels);
pTDStretch->setChannels((int)numChannels); pTDStretch->setChannels((int)numChannels);
@ -347,7 +348,7 @@ void SoundTouch::flush()
int i; int i;
int nUnprocessed; int nUnprocessed;
int nOut; 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 // check how many samples still await processing, and scale
// that by tempo & rate to get expected output sample count // that by tempo & rate to get expected output sample count

View File

@ -1,123 +1,172 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="9.00"
Name="SoundTouch" Name="SoundTouch"
ProjectGUID="{68A5DD20-7057-448B-8FE0-B6AC8D205509}" ProjectGUID="{68A5DD20-7057-448B-8FE0-B6AC8D205509}"
SccProjectName="" TargetFrameworkVersion="131072"
SccLocalPath=""> >
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"
/>
</Platforms> </Platforms>
<ToolFiles>
</ToolFiles>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory=".\Release" OutputDirectory=".\Release"
IntermediateDirectory=".\Release" IntermediateDirectory=".\Release"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"> CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="3" Optimization="3"
InlineFunctionExpansion="2" InlineFunctionExpansion="2"
EnableIntrinsicFunctions="TRUE" EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\include" AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB" PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE" StringPooling="true"
RuntimeLibrary="4" RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2" UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/SoundTouch.pch" PrecompiledHeaderFile=".\Release/SoundTouch.pch"
AssemblerListingLocation=".\Release/" AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/" ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/" ProgramDataBaseFileName=".\Release/"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
DebugInformationFormat="0" DebugInformationFormat="0"
CompileAs="0"/> CompileAs="0"
/>
<Tool <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\"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool" Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG" PreprocessorDefinitions="NDEBUG"
Culture="1035"/> Culture="1035"
/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCPreLinkEventTool"
/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCLibrarianTool"
OutputFile=".\Release\SoundTouch.lib"
SuppressStartupBanner="true"
/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCALinkTool"
/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy .\Release\SoundTouch.lib ..\..\lib\"
/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory=".\Debug" OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug" IntermediateDirectory=".\Debug"
ConfigurationType="4" ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"> CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\include" AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB" PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="1"
UsePrecompiledHeader="2" UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/SoundTouch.pch" PrecompiledHeaderFile=".\Debug/SoundTouch.pch"
AssemblerListingLocation=".\Debug/" AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/" ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/" ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1" BrowseInformation="1"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="true"
DebugInformationFormat="4" DebugInformationFormat="4"
CompileAs="0"/> CompileAs="0"
/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCManagedResourceCompilerTool"
<Tool />
Name="VCLibrarianTool"
OutputFile="Debug\SoundTouchD.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy .\Debug\SoundTouchD.lib ..\..\lib\"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool" Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG" PreprocessorDefinitions="_DEBUG"
Culture="1035"/> Culture="1035"
/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCPreLinkEventTool"
/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCLibrarianTool"
OutputFile="Debug\SoundTouchD.lib"
SuppressStartupBanner="true"
/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCALinkTool"
/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy .\Debug\SoundTouchD.lib ..\..\lib\"
/>
</Configuration> </Configuration>
</Configurations> </Configurations>
<References> <References>
@ -125,188 +174,236 @@
<Files> <Files>
<Filter <Filter
Name="Source Files" 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 <File
RelativePath="AAFilter.cpp"> RelativePath="AAFilter.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath=".\cpu_detect_x86.cpp"> RelativePath=".\cpu_detect_x86.cpp"
>
</File> </File>
<File <File
RelativePath="FIFOSampleBuffer.cpp"> RelativePath="FIFOSampleBuffer.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="FIRFilter.cpp"> RelativePath="FIRFilter.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath=".\mmx_optimized.cpp"> RelativePath=".\mmx_optimized.cpp"
>
</File> </File>
<File <File
RelativePath="RateTransposer.cpp"> RelativePath="RateTransposer.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="SoundTouch.cpp"> RelativePath="SoundTouch.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath=".\sse_optimized.cpp"> RelativePath=".\sse_optimized.cpp"
>
</File> </File>
<File <File
RelativePath="TDStretch.cpp"> RelativePath="TDStretch.cpp"
>
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/> PreprocessorDefinitions=""
/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32"> Name="Debug|Win32"
>
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories=""
PreprocessorDefinitions="" PreprocessorDefinitions=""
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
BrowseInformation="1"/> BrowseInformation="1"
/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<Filter <Filter
Name="bpm" Name="bpm"
Filter=""> >
<File <File
RelativePath=".\BPMDetect.cpp"> RelativePath=".\BPMDetect.cpp"
>
</File> </File>
<File <File
RelativePath=".\PeakFinder.cpp"> RelativePath=".\PeakFinder.cpp"
>
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl"> Filter="h;hpp;hxx;hm;inl"
>
<File <File
RelativePath="AAFilter.h"> RelativePath="AAFilter.h"
>
</File> </File>
<File <File
RelativePath="..\..\include\BPMDetect.h"> RelativePath="..\..\include\BPMDetect.h"
>
</File> </File>
<File <File
RelativePath="cpu_detect.h"> RelativePath="cpu_detect.h"
>
</File> </File>
<File <File
RelativePath="..\..\include\FIFOSampleBuffer.h"> RelativePath="..\..\include\FIFOSampleBuffer.h"
>
</File> </File>
<File <File
RelativePath="..\..\include\FIFOSamplePipe.h"> RelativePath="..\..\include\FIFOSamplePipe.h"
>
</File> </File>
<File <File
RelativePath="FIRFilter.h"> RelativePath="FIRFilter.h"
>
</File> </File>
<File <File
RelativePath=".\PeakFinder.h"> RelativePath=".\PeakFinder.h"
>
</File> </File>
<File <File
RelativePath="RateTransposer.h"> RelativePath="RateTransposer.h"
>
</File> </File>
<File <File
RelativePath="..\..\include\SoundTouch.h"> RelativePath="..\..\include\SoundTouch.h"
>
</File> </File>
<File <File
RelativePath="..\..\include\STTypes.h"> RelativePath="..\..\include\STTypes.h"
>
</File> </File>
<File <File
RelativePath="TDStretch.h"> RelativePath="TDStretch.h"
>
</File> </File>
</Filter> </Filter>
</Files> </Files>

View File

@ -212,7 +212,7 @@ void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
void TDStretch::clearMidBuffer() void TDStretch::clearMidBuffer()
{ {
memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength); memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
} }
@ -265,13 +265,22 @@ int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
// of 'ovlPos'. // of 'ovlPos'.
inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
{ {
if (channels == 2) #ifndef USE_MULTICH_ALWAYS
if (channels == 1)
{
// mono sound.
overlapMono(pOutput, pInput + ovlPos);
}
else if (channels == 2)
{ {
// stereo sound // stereo sound
overlapStereo(pOutput, pInput + 2 * ovlPos); overlapStereo(pOutput, pInput + 2 * ovlPos);
} else { }
// mono sound. else
overlapMono(pOutput, pInput + ovlPos); #endif // USE_MULTICH_ALWAYS
{
assert(channels > 0);
overlapMulti(pOutput, pInput + channels * ovlPos);
} }
} }
@ -458,11 +467,15 @@ void TDStretch::setChannels(int numChannels)
{ {
assert(numChannels > 0); assert(numChannels > 0);
if (channels == numChannels) return; if (channels == numChannels) return;
assert(numChannels == 1 || numChannels == 2); // assert(numChannels == 1 || numChannels == 2);
channels = numChannels; channels = numChannels;
inputBuffer.setChannels(channels); inputBuffer.setChannels(channels);
outputBuffer.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 // Calculates the x having the closest 2^x value for the given value
static int _getClosest2Power(double 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. /// Calculates overlapInMsec period length in samples.
void TDStretch::calculateOverlapLength(int overlapInMsec) void TDStretch::calculateOverlapLength(int overlapInMsec)
{ {

View File

@ -147,6 +147,7 @@ protected:
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
virtual void overlapMono(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 clearMidBuffer();
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;