Compare commits

..

4 Commits

Author SHA1 Message Date
gregory.hainaut
f9dd6277e3 1.2.x: cherry pick r5888 from trunk
git-svn-id: http://pcsx2.googlecode.com/svn/branches/1.2.x@5896 96395faa-99c1-11dd-bbfe-3dabce05a288
2014-02-10 18:57:09 +00:00
gregory.hainaut
e5f49d0ae7 1.2.x: keep a trace of ppa package update for 1.2 release
git-svn-id: http://pcsx2.googlecode.com/svn/branches/1.2.x@5895 96395faa-99c1-11dd-bbfe-3dabce05a288
2014-02-10 18:29:35 +00:00
gregory.hainaut
73371c3098 Create a 1.2 branch from the 1.2.1 tags
git-svn-id: http://pcsx2.googlecode.com/svn/branches/1.2.x@5887 96395faa-99c1-11dd-bbfe-3dabce05a288
2014-02-07 18:16:27 +00:00
gigaherz
11da1c053d Tag the 1.2.1 release at r5875
git-svn-id: http://pcsx2.googlecode.com/svn/tags/v1.2.1@5883 96395faa-99c1-11dd-bbfe-3dabce05a288
2014-02-05 11:45:07 +00:00
6387 changed files with 956590 additions and 1228257 deletions

View File

@@ -1,89 +0,0 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 0
CommentPragmas: '^ (IWYU pragma:|NOLINT)'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: []
IncludeCategories:
- Regex: '^"(stdafx|PrecompiledHeader)'
Priority: -2
- Regex: '^".*Common'
Priority: -1
- Regex: '^<'
Priority: 1
- Regex: '^"'
Priority: 2
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 3
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...

View File

@@ -1,12 +0,0 @@
# Should always be specified at the top of the file outside of any sections
root = true
# TODO: Add one for resource script file and other Linux specific files ?
[*.{cpp,h}]
indent_style = tab
indent_size = 4
#trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

8
.gitattributes vendored
View File

@@ -1,8 +0,0 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
*.props text eol=crlf
*.vcxproj text eol=crlf
*.vcxproj.filters text eol=crlf

114
.gitignore vendored
View File

@@ -1,114 +0,0 @@
.*.swp
.*.swn
.*.swo
*.suo
*.ncb
*.sdf
*.opensdf
*.user
*.log
*.dsp
*.dsw
*.bsc
*.aps
*.exe
*.wav
*.trace
*.dump
*.asm
!/plugins/zerogs/dx/x86-32.asm
!/plugins/zerogs/dx/x86-64.asm
!/plugins/zerogs/opengl/x86-32.asm
!/plugins/zzogl-pg/opengl/x86-32.asm
*.VC.db
*.VC.VC.opendb
**/Win32/Release*
**/Win32/Debug*
**/Win32/Devel*
**/x64/Release*
**/x64/Debug*
**/x64/Devel*
_ReSharper.*
pcsx2.snapshot_*
svnrev.h
/build
/obj-*
.DS_Store
Thumbs.db
Debug.txt
install_log.txt
padLog.txt
Debug
Release
Devel
oprofile_data/
# Recording Specific Ignores (pcsx2-rr)
*.p2s
*.p2m2
*.p2m2_backup
*.p2m2_SaveState.p2s
# Visual Studio upgrades
/Backup*
/UpgradeLog*.htm
/bin/**/*.dll
/bin/**/*.exp
/bin/**/*.ilk
/bin/**/*.lib
/bin/**/*.pdb
/bin/PCSX2
/bin/*ReplayLoader
/bin/bios
/bin/dumps
/bin/help
/bin/inis
/bin/logs
/bin/memcards
/bin/plugins
/bin/snaps
/bin/sstates
/deps
/ipch
!/3rdparty/libjpeg/change.log
/3rdparty/portaudio/portaudio-2.0.pc
/3rdparty/portaudio/bin
/3rdparty/portaudio/bin-*
/3rdparty/portaudio/autom4te.cache
/3rdparty/portaudio/libtool
/3rdparty/portaudio/config.*
/3rdparty/portaudio/lib-stamp
/3rdparty/portaudio/Makefile
/3rdparty/portaudio/bindings
/3rdparty/portaudio/test
/3rdparty/portaudio/testcvs
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/common
/3rdparty/portaudio/src/hostapi/asio/ASIOSDK/host
/3rdparty/portaudio/src/hostapi/wasapi/mingw-include
/3rdparty/**/include/wx/setup.h
/3rdparty/**/wx/msw/rcdefs.h
/pcsx2/gui/Resources/*.h
!/pcsx2/gui/Resources/EmbeddedImage.h
/plugins/GSdx/Template
/plugins/USBqemu/Win32/bin
/plugins/zerospu2/Windows/dsound51.cpp
/tools/bin
/tools/GSDumpGUI/bin
/tools/GSDumpGUI/obj
.vs
/pcsx2/windows/VCprojects/GSdx_opengl_debug_hw.txt
/pcsx2/windows/VCprojects/GSdx_opengl_debug_sw.txt

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "3rdparty/xz/xz"]
path = 3rdparty/xz/xz
url = https://github.com/PCSX2/xz.git

View File

@@ -1,34 +0,0 @@
language: cpp
sudo: required
cache: ccache
dist: xenial
matrix:
include:
- env: VERSION=8 BITS=64
compiler: gcc
os: linux
- env: VERSION=8 BITS=32
compiler: gcc
os: linux
- env: VERSION=7 BITS=32
compiler: gcc
os: linux
- env: VERSION=3.8 BITS=32
compiler: clang
os: linux
before_install:
- ./travis.sh before_install
before_script:
- ./travis.sh before_script
script:
- ./travis.sh script
after_success:
- ./travis.sh after_success

View File

@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir>$(SolutionDir)deps\$(PlatformName)\$(Configuration)\</OutDir>
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
<ExtensionsToDeleteOnClean>*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>16Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
</ItemDefinitionGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir>$(SvnRootDir)\deps\$(PlatformName)\$(Configuration)\</OutDir>
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
<ExtensionsToDeleteOnClean>*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>16Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
</ItemDefinitionGroup>
</Project>

26
3rdparty/3rdparty.vsprops vendored Normal file
View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="3rdparty"
OutputDirectory="$(SvnRootDir)\deps\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
DeleteExtensionsOnClean="*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath)"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;"
PreprocessorDefinitions="__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
StructMemberAlignment="5"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="false"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCLinkerTool"
GenerateDebugInformation="true"
SubSystem="2"
/>
</VisualStudioPropertySheet>

28
3rdparty/3rdpartyDLL.props vendored Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir>$(SvnRootDir)\deps\$(PlatformName)\$(Configuration)\</OutDir>
<IntDir>$(PlatformName)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>16Bytes</StructMemberAlignment>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(OutDir)$(ProjectName).lib</ImportLibrary>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>$(SvnRootDir)/common/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
</Project>

30
3rdparty/3rdpartyDLL.vsprops vendored Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="3rdpartyDLL"
OutputDirectory="$(SvnRootDir)\deps\$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(ProjectDir)&quot;"
PreprocessorDefinitions="__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
StructMemberAlignment="5"
RuntimeTypeInfo="false"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\$(ProjectName).dll"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
ImportLibrary="$(OutDir)\$(ProjectName).lib"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="&quot;$(SvnRootDir)/common/include&quot;"
/>
</VisualStudioPropertySheet>

8
3rdparty/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,8 @@
# Check that people use the good file
if(NOT TOP_CMAKE_WAS_SOURCED)
message(FATAL_ERROR "
You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir.
It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt")
endif(NOT TOP_CMAKE_WAS_SOURCED)
### 3rd party was dropped

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<ProjectRootDir>$(ProjectDir)</ProjectRootDir>
<SvnRootDir>$(ProjectRootDir)\..\..</SvnRootDir>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
</PropertyGroup>
<ItemGroup>
<BuildMacro Include="ProjectRootDir">
<Value>$(ProjectRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnRootDir">
<Value>$(SvnRootDir)</Value>
</BuildMacro>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<ProjectRootDir>$(ProjectDir)</ProjectRootDir>
<SvnRootDir>$(ProjectRootDir)\..\..</SvnRootDir>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
</PropertyGroup>
<ItemGroup>
<BuildMacro Include="ProjectRootDir">
<Value>$(ProjectRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnRootDir">
<Value>$(SvnRootDir)</Value>
</BuildMacro>
</ItemGroup>
</Project>

15
3rdparty/DefaultProjectRootDir.vsprops vendored Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="DefaultProjectRootDir"
>
<UserMacro
Name="ProjectRootDir"
Value="$(ProjectDir)"
/>
<UserMacro
Name="SvnRootDir"
Value="$(ProjectRootDir)\..\.."
/>
</VisualStudioPropertySheet>

5866
3rdparty/GL/glcorearb.h vendored

File diff suppressed because it is too large Load Diff

14435
3rdparty/GL/glew.h vendored Normal file

File diff suppressed because it is too large Load Diff

2273
3rdparty/GL/glext.h vendored

File diff suppressed because it is too large Load Diff

1476
3rdparty/GL/glxew.h vendored Normal file

File diff suppressed because it is too large Load Diff

1247
3rdparty/GL/wglew.h vendored Normal file

File diff suppressed because it is too large Load Diff

1363
3rdparty/GL/wglext.h vendored

File diff suppressed because it is too large Load Diff

349
3rdparty/SoundTouch/3dnow_win.cpp vendored Normal file
View File

@@ -0,0 +1,349 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon
/// processors. All 3DNow! optimized functions have been gathered into this
/// single source code file, regardless to their class or original source code
/// file, in order to ease porting the library to other compiler and processor
/// platforms.
///
/// By the way; the performance gain depends heavily on the CPU generation: On
/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the
/// difference to the original routines stayed at unremarkable 8%! Such a small
/// improvement on Athlon is due to 3DNow can perform only two operations in
/// parallel, and obviously also the Athlon FPU is doing a very good job with
/// the standard C floating point routines! Here these routines are anyway,
/// although it might not be worth the effort to convert these to GCC platform,
/// for Athlon CPU at least. The situation is different regarding the SSE
/// optimizations though, thanks to the four parallel operations of SSE that
/// already make a difference.
///
/// This file is to be compiled in Windows platform with Microsoft Visual C++
/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all
/// GNU platforms (if file supplied).
///
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
/// 6.0 processor pack" update to support 3DNow! instruction set. The update is
/// available for download at Microsoft Developers Network, see here:
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
///
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
/// perform a search with keywords "processor pack".
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
// File revision : $Revision: 4 $
//
// $Id: 3dnow_win.cpp 63 2009-02-21 16:00:14Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#include "STTypes.h"
#ifndef WIN32
#error "wrong platform - this source code file is exclusively for Win32 platform"
#endif
using namespace soundtouch;
#ifdef ALLOW_3DNOW
// 3DNow! routines available only with float sample type
//////////////////////////////////////////////////////////////////////////////
//
// implementation of 3DNow! optimized functions of class 'TDStretch3DNow'
//
//////////////////////////////////////////////////////////////////////////////
#include "TDStretch.h"
// Calculates cross correlation of two buffers
double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const
{
int overlapLengthLocal = overlapLength;
float corr = 0;
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
/*
c-pseudocode:
corr = 0;
for (i = 0; i < overlapLength / 4; i ++)
{
corr += pV1[0] * pV2[0];
pV1[1] * pV2[1];
pV1[2] * pV2[2];
pV1[3] * pV2[3];
pV1[4] * pV2[4];
pV1[5] * pV2[5];
pV1[6] * pV2[6];
pV1[7] * pV2[7];
pV1 += 8;
pV2 += 8;
}
*/
_asm
{
// give prefetch hints to CPU of what data are to be needed soonish.
// give more aggressive hints on pV1 as that changes more between different calls
// while pV2 stays the same.
prefetch [pV1]
prefetch [pV2]
prefetch [pV1 + 32]
mov eax, dword ptr pV2
mov ebx, dword ptr pV1
pxor mm0, mm0
mov ecx, overlapLengthLocal
shr ecx, 2 // div by four
loop1:
movq mm1, [eax]
prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish
pfmul mm1, [ebx]
prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
movq mm2, [eax + 8]
pfadd mm0, mm1
pfmul mm2, [ebx + 8]
movq mm3, [eax + 16]
pfadd mm0, mm2
pfmul mm3, [ebx + 16]
movq mm4, [eax + 24]
pfadd mm0, mm3
pfmul mm4, [ebx + 24]
add eax, 32
pfadd mm0, mm4
add ebx, 32
dec ecx
jnz loop1
// add halfs of mm0 together and return the result.
// note: mm1 is used as a dummy parameter only, we actually don't care about it's value
pfacc mm0, mm1
movd corr, mm0
femms
}
return corr;
}
//////////////////////////////////////////////////////////////////////////////
//
// implementation of 3DNow! optimized functions of class 'FIRFilter'
//
//////////////////////////////////////////////////////////////////////////////
#include "FIRFilter.h"
FIRFilter3DNow::FIRFilter3DNow() : FIRFilter()
{
filterCoeffsUnalign = NULL;
filterCoeffsAlign = NULL;
}
FIRFilter3DNow::~FIRFilter3DNow()
{
delete[] filterCoeffsUnalign;
filterCoeffsUnalign = NULL;
filterCoeffsAlign = NULL;
}
// (overloaded) Calculates filter coefficients for 3DNow! routine
void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
{
uint i;
float fDivider;
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
// also rearrange coefficients suitably for 3DNow!
// Ensure that filter coeffs array is aligned to 16-byte boundary
delete[] filterCoeffsUnalign;
filterCoeffsUnalign = new float[2 * newLength + 4];
filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint)-16);
fDivider = (float)resultDivider;
// rearrange the filter coefficients for mmx routines
for (i = 0; i < newLength; i ++)
{
filterCoeffsAlign[2 * i + 0] =
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
}
}
// 3DNow!-optimized version of the filter routine for stereo sound
uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint numSamples) const
{
float *filterCoeffsLocal = filterCoeffsAlign;
uint count = (numSamples - length) & (uint)-2;
uint lengthLocal = length / 4;
assert(length != 0);
assert(count % 2 == 0);
/* original code:
double suml1, suml2;
double sumr1, sumr2;
uint i, j;
for (j = 0; j < count; j += 2)
{
const float *ptr;
suml1 = sumr1 = 0.0;
suml2 = sumr2 = 0.0;
ptr = src;
filterCoeffsLocal = filterCoeffs;
for (i = 0; i < lengthLocal; i ++)
{
// unroll loop for efficiency.
suml1 += ptr[0] * filterCoeffsLocal[0] +
ptr[2] * filterCoeffsLocal[2] +
ptr[4] * filterCoeffsLocal[4] +
ptr[6] * filterCoeffsLocal[6];
sumr1 += ptr[1] * filterCoeffsLocal[1] +
ptr[3] * filterCoeffsLocal[3] +
ptr[5] * filterCoeffsLocal[5] +
ptr[7] * filterCoeffsLocal[7];
suml2 += ptr[8] * filterCoeffsLocal[0] +
ptr[10] * filterCoeffsLocal[2] +
ptr[12] * filterCoeffsLocal[4] +
ptr[14] * filterCoeffsLocal[6];
sumr2 += ptr[9] * filterCoeffsLocal[1] +
ptr[11] * filterCoeffsLocal[3] +
ptr[13] * filterCoeffsLocal[5] +
ptr[15] * filterCoeffsLocal[7];
ptr += 16;
filterCoeffsLocal += 8;
}
dest[0] = (float)suml1;
dest[1] = (float)sumr1;
dest[2] = (float)suml2;
dest[3] = (float)sumr2;
src += 4;
dest += 4;
}
*/
_asm
{
mov eax, dword ptr dest
mov ebx, dword ptr src
mov edx, count
shr edx, 1
loop1:
// "outer loop" : during each round 2*2 output samples are calculated
prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish
prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish
mov esi, ebx
mov edi, filterCoeffsLocal
pxor mm0, mm0
pxor mm1, mm1
mov ecx, lengthLocal
loop2:
// "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples
movq mm2, [edi]
movq mm3, mm2
prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
pfmul mm2, [esi]
prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
pfmul mm3, [esi + 8]
movq mm4, [edi + 8]
movq mm5, mm4
pfadd mm0, mm2
pfmul mm4, [esi + 8]
pfadd mm1, mm3
pfmul mm5, [esi + 16]
movq mm2, [edi + 16]
movq mm6, mm2
pfadd mm0, mm4
pfmul mm2, [esi + 16]
pfadd mm1, mm5
pfmul mm6, [esi + 24]
movq mm3, [edi + 24]
movq mm7, mm3
pfadd mm0, mm2
pfmul mm3, [esi + 24]
pfadd mm1, mm6
pfmul mm7, [esi + 32]
add esi, 32
pfadd mm0, mm3
add edi, 32
pfadd mm1, mm7
dec ecx
jnz loop2
movq [eax], mm0
add ebx, 16
movq [eax + 8], mm1
add eax, 16
dec edx
jnz loop1
femms
}
return count;
}
#endif // ALLOW_3DNOW

184
3rdparty/SoundTouch/AAFilter.cpp vendored Normal file
View File

@@ -0,0 +1,184 @@
////////////////////////////////////////////////////////////////////////////////
///
/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
/// MMX optimization.
///
/// Anti-alias filter is used to prevent folding of high frequencies when
/// transposing the sample rate with interpolation.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2009-01-11 09:34:24 -0200 (dom, 11 jan 2009) $
// File revision : $Revision: 4 $
//
// $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include "AAFilter.h"
#include "FIRFilter.h"
using namespace soundtouch;
#define PI 3.141592655357989
#define TWOPI (2 * PI)
/*****************************************************************************
*
* Implementation of the class 'AAFilter'
*
*****************************************************************************/
AAFilter::AAFilter(uint len)
{
pFIR = FIRFilter::newInstance();
cutoffFreq = 0.5;
setLength(len);
}
AAFilter::~AAFilter()
{
delete pFIR;
}
// Sets new anti-alias filter cut-off edge frequency, scaled to
// sampling frequency (nyquist frequency = 0.5).
// The filter will cut frequencies higher than the given frequency.
void AAFilter::setCutoffFreq(double newCutoffFreq)
{
cutoffFreq = newCutoffFreq;
calculateCoeffs();
}
// Sets number of FIR filter taps
void AAFilter::setLength(uint newLength)
{
length = newLength;
calculateCoeffs();
}
// Calculates coefficients for a low-pass FIR filter using Hamming window
void AAFilter::calculateCoeffs()
{
uint i;
double cntTemp, temp, tempCoeff,h, w;
double fc2, wc;
double scaleCoeff, sum;
double *work;
SAMPLETYPE *coeffs;
assert(length >= 2);
assert(length % 4 == 0);
assert(cutoffFreq >= 0);
assert(cutoffFreq <= 0.5);
work = new double[length];
coeffs = new SAMPLETYPE[length];
fc2 = 2.0 * cutoffFreq;
wc = PI * fc2;
tempCoeff = TWOPI / (double)length;
sum = 0;
for (i = 0; i < length; i ++)
{
cntTemp = (double)i - (double)(length / 2);
temp = cntTemp * wc;
if (temp != 0)
{
h = fc2 * sin(temp) / temp; // sinc function
}
else
{
h = 1.0;
}
w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window
temp = w * h;
work[i] = temp;
// calc net sum of coefficients
sum += temp;
}
// ensure the sum of coefficients is larger than zero
assert(sum > 0);
// ensure we've really designed a lowpass filter...
assert(work[length/2] > 0);
assert(work[length/2 + 1] > -1e-6);
assert(work[length/2 - 1] > -1e-6);
// Calculate a scaling coefficient in such a way that the result can be
// divided by 16384
scaleCoeff = 16384.0f / sum;
for (i = 0; i < length; i ++)
{
// scale & round to nearest integer
temp = work[i] * scaleCoeff;
temp += (temp >= 0) ? 0.5 : -0.5;
// ensure no overfloods
assert(temp >= -32768 && temp <= 32767);
coeffs[i] = (SAMPLETYPE)temp;
}
// Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
pFIR->setCoefficients(coeffs, length, 14);
delete[] work;
delete[] coeffs;
}
// Applies the filter to the given sequence of samples.
// Note : The amount of outputted samples is by value of 'filter length'
// smaller than the amount of input samples.
uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
{
return pFIR->evaluate(dest, src, numSamples, numChannels);
}
uint AAFilter::getLength() const
{
return pFIR->getLength();
}

View File

@@ -13,6 +13,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2008-02-10 14:26:55 -0200 (dom, 10 fev 2008) $
// File revision : $Revision: 4 $
//
// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -38,7 +45,6 @@
#define AAFilter_H
#include "STTypes.h"
#include "FIFOSampleBuffer.h"
namespace soundtouch
{
@@ -78,14 +84,6 @@ public:
const SAMPLETYPE *src,
uint numSamples,
uint numChannels) const;
/// Applies the filter to the given src & dest pipes, so that processed amount of
/// samples get removed from src, and produced amount added to dest
/// Note : The amount of outputted samples is by value of 'filter length'
/// smaller than the amount of input samples.
uint evaluate(FIFOSampleBuffer &dest,
FIFOSampleBuffer &src) const;
};
}

370
3rdparty/SoundTouch/BPMDetect.cpp vendored Normal file
View File

@@ -0,0 +1,370 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Beats-per-minute (BPM) detection routine.
///
/// The beat detection algorithm works as follows:
/// - Use function 'inputSamples' to input a chunks of samples to the class for
/// analysis. It's a good idea to enter a large sound file or stream in smallish
/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
/// - Inputted sound data is decimated to approx 500 Hz to reduce calculation burden,
/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
/// Simple averaging is used for anti-alias filtering because the resulting signal
/// quality isn't of that high importance.
/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
/// taking absolute value that's smoothed by sliding average. Signal levels that
/// are below a couple of times the general RMS amplitude level are cut away to
/// leave only notable peaks there.
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
/// autocorrelation function of the enveloped signal.
/// - After whole sound data file has been analyzed as above, the bpm level is
/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
/// function, calculates it's precise location and converts this reading to bpm's.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-08-30 16:45:25 -0300 (qui, 30 ago 2012) $
// File revision : $Revision: 4 $
//
// $Id: BPMDetect.cpp 149 2012-08-30 19:45:25Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <math.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "FIFOSampleBuffer.h"
#include "PeakFinder.h"
#include "BPMDetect.h"
using namespace soundtouch;
#define INPUT_BLOCK_SAMPLES 2048
#define DECIMATED_BLOCK_SAMPLES 256
/// decay constant for calculating RMS volume sliding average approximation
/// (time constant is about 10 sec)
const float avgdecay = 0.99986f;
/// Normalization coefficient for calculating RMS sliding average approximation.
const float avgnorm = (1 - avgdecay);
////////////////////////////////////////////////////////////////////////////////
// Enable following define to create bpm analysis file:
// #define _CREATE_BPM_DEBUG_FILE
#ifdef _CREATE_BPM_DEBUG_FILE
#define DEBUGFILE_NAME "c:\\temp\\soundtouch-bpm-debug.txt"
static void _SaveDebugData(const float *data, int minpos, int maxpos, double coeff)
{
FILE *fptr = fopen(DEBUGFILE_NAME, "wt");
int i;
if (fptr)
{
printf("\n\nWriting BPM debug data into file " DEBUGFILE_NAME "\n\n");
for (i = minpos; i < maxpos; i ++)
{
fprintf(fptr, "%d\t%.1lf\t%f\n", i, coeff / (double)i, data[i]);
}
fclose(fptr);
}
}
#else
#define _SaveDebugData(a,b,c,d)
#endif
////////////////////////////////////////////////////////////////////////////////
BPMDetect::BPMDetect(int numChannels, int aSampleRate)
{
this->sampleRate = aSampleRate;
this->channels = numChannels;
decimateSum = 0;
decimateCount = 0;
envelopeAccu = 0;
// Initialize RMS volume accumulator to RMS level of 1500 (out of 32768) that's
// safe initial RMS signal level value for song data. This value is then adapted
// to the actual level during processing.
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
// integer samples
RMSVolumeAccu = (1500 * 1500) / avgnorm;
#else
// float samples, scaled to range [-1..+1[
RMSVolumeAccu = (0.045f * 0.045f) / avgnorm;
#endif
// choose decimation factor so that result is approx. 1000 Hz
decimateBy = sampleRate / 1000;
assert(decimateBy > 0);
assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
// Calculate window length & starting item according to desired min & max bpms
windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
assert(windowLen > windowStart);
// allocate new working objects
xcorr = new float[windowLen];
memset(xcorr, 0, windowLen * sizeof(float));
// allocate processing buffer
buffer = new FIFOSampleBuffer();
// we do processing in mono mode
buffer->setChannels(1);
buffer->clear();
}
BPMDetect::~BPMDetect()
{
delete[] xcorr;
delete buffer;
}
/// convert to mono, low-pass filter & decimate to about 500 Hz.
/// return number of outputted samples.
///
/// Decimation is used to remove the unnecessary frequencies and thus to reduce
/// the amount of data needed to be processed as calculating autocorrelation
/// function is a very-very heavy operation.
///
/// Anti-alias filtering is done simply by averaging the samples. This is really a
/// poor-man's anti-alias filtering, but it's not so critical in this kind of application
/// (it'd also be difficult to design a high-quality filter with steep cut-off at very
/// narrow band)
int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
{
int count, outcount;
LONG_SAMPLETYPE out;
assert(channels > 0);
assert(decimateBy > 0);
outcount = 0;
for (count = 0; count < numsamples; count ++)
{
int j;
// convert to mono and accumulate
for (j = 0; j < channels; j ++)
{
decimateSum += src[j];
}
src += j;
decimateCount ++;
if (decimateCount >= decimateBy)
{
// Store every Nth sample only
out = (LONG_SAMPLETYPE)(decimateSum / (decimateBy * channels));
decimateSum = 0;
decimateCount = 0;
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
// check ranges for sure (shouldn't actually be necessary)
if (out > 32767)
{
out = 32767;
}
else if (out < -32768)
{
out = -32768;
}
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[outcount] = (SAMPLETYPE)out;
outcount ++;
}
}
return outcount;
}
// Calculates autocorrelation function of the sample history buffer
void BPMDetect::updateXCorr(int process_samples)
{
int offs;
SAMPLETYPE *pBuffer;
assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
pBuffer = buffer->ptrBegin();
for (offs = windowStart; offs < windowLen; offs ++)
{
LONG_SAMPLETYPE sum;
int i;
sum = 0;
for (i = 0; i < process_samples; i ++)
{
sum += pBuffer[i] * pBuffer[i + offs]; // scaling the sub-result shouldn't be necessary
}
// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients
// if it's desired that the system adapts automatically to
// various bpms, e.g. in processing continouos music stream.
// The 'xcorr_decay' should be a value that's smaller than but
// close to one, and should also depend on 'process_samples' value.
xcorr[offs] += (float)sum;
}
}
// Calculates envelope of the sample data
void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples)
{
const static double decay = 0.7f; // decay constant for smoothing the envelope
const static double norm = (1 - decay);
int i;
LONG_SAMPLETYPE out;
double val;
for (i = 0; i < numsamples; i ++)
{
// calc average RMS volume
RMSVolumeAccu *= avgdecay;
val = (float)fabs((float)samples[i]);
RMSVolumeAccu += val * val;
// cut amplitudes that are below cutoff ~2 times RMS volume
// (we're interested in peak values, not the silent moments)
if (val < 0.5 * sqrt(RMSVolumeAccu * avgnorm))
{
val = 0;
}
// smooth amplitude envelope
envelopeAccu *= decay;
envelopeAccu += val;
out = (LONG_SAMPLETYPE)(envelopeAccu * norm);
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
// cut peaks (shouldn't be necessary though)
if (out > 32767) out = 32767;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
samples[i] = (SAMPLETYPE)out;
}
}
void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
{
SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
// iterate so that max INPUT_BLOCK_SAMPLES processed per iteration
while (numSamples > 0)
{
int block;
int decSamples;
block = (numSamples > INPUT_BLOCK_SAMPLES) ? INPUT_BLOCK_SAMPLES : numSamples;
// decimate. note that converts to mono at the same time
decSamples = decimate(decimated, samples, block);
samples += block * channels;
numSamples -= block;
// envelope new samples and add them to buffer
calcEnvelope(decimated, decSamples);
buffer->putSamples(decimated, decSamples);
}
// when the buffer has enought samples for processing...
if ((int)buffer->numSamples() > windowLen)
{
int processLength;
// how many samples are processed
processLength = (int)buffer->numSamples() - windowLen;
// ... calculate autocorrelations for oldest samples...
updateXCorr(processLength);
// ... and remove them from the buffer
buffer->receiveSamples(processLength);
}
}
void BPMDetect::removeBias()
{
int i;
float minval = 1e12f; // arbitrary large number
for (i = windowStart; i < windowLen; i ++)
{
if (xcorr[i] < minval)
{
minval = xcorr[i];
}
}
for (i = windowStart; i < windowLen; i ++)
{
xcorr[i] -= minval;
}
}
float BPMDetect::getBpm()
{
double peakPos;
double coeff;
PeakFinder peakFinder;
coeff = 60.0 * ((double)sampleRate / (double)decimateBy);
// save bpm debug analysis data if debug data enabled
_SaveDebugData(xcorr, windowStart, windowLen, coeff);
// remove bias from xcorr data
removeBias();
// find peak position
peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen);
assert(decimateBy != 0);
if (peakPos < 1e-9) return 0.0; // detection failed.
// calculate BPM
return (float) (coeff / peakPos);
}

164
3rdparty/SoundTouch/BPMDetect.h vendored Normal file
View File

@@ -0,0 +1,164 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Beats-per-minute (BPM) detection routine.
///
/// The beat detection algorithm works as follows:
/// - Use function 'inputSamples' to input a chunks of samples to the class for
/// analysis. It's a good idea to enter a large sound file or stream in smallish
/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
/// - Input sound data is decimated to approx 500 Hz to reduce calculation burden,
/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
/// Simple averaging is used for anti-alias filtering because the resulting signal
/// quality isn't of that high importance.
/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
/// taking absolute value that's smoothed by sliding average. Signal levels that
/// are below a couple of times the general RMS amplitude level are cut away to
/// leave only notable peaks there.
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
/// autocorrelation function of the enveloped signal.
/// - After whole sound data file has been analyzed as above, the bpm level is
/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
/// function, calculates it's precise location and converts this reading to bpm's.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-08-30 16:53:44 -0300 (qui, 30 ago 2012) $
// File revision : $Revision: 4 $
//
// $Id: BPMDetect.h 150 2012-08-30 19:53:44Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _BPMDetect_H_
#define _BPMDetect_H_
#include "STTypes.h"
#include "FIFOSampleBuffer.h"
namespace soundtouch
{
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
#define MIN_BPM 29
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
#define MAX_BPM 200
/// Class for calculating BPM rate for audio data.
class BPMDetect
{
protected:
/// Auto-correlation accumulator bins.
float *xcorr;
/// Amplitude envelope sliding average approximation level accumulator
double envelopeAccu;
/// RMS volume sliding average approximation level accumulator
double RMSVolumeAccu;
/// Sample average counter.
int decimateCount;
/// Sample average accumulator for FIFO-like decimation.
soundtouch::LONG_SAMPLETYPE decimateSum;
/// Decimate sound by this coefficient to reach approx. 500 Hz.
int decimateBy;
/// Auto-correlation window length
int windowLen;
/// Number of channels (1 = mono, 2 = stereo)
int channels;
/// sample rate
int sampleRate;
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
/// the first these many correlation bins.
int windowStart;
/// FIFO-buffer for decimated processing samples.
soundtouch::FIFOSampleBuffer *buffer;
/// Updates auto-correlation function for given number of decimated samples that
/// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
/// though).
void updateXCorr(int process_samples /// How many samples are processed.
);
/// Decimates samples to approx. 500 Hz.
///
/// \return Number of output samples.
int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
int numsamples ///< Number of source samples.
);
/// Calculates amplitude envelope for the buffer of samples.
/// Result is output to 'samples'.
void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
int numsamples ///< Number of samples in buffer
);
/// remove constant bias from xcorr data
void removeBias();
public:
/// Constructor.
BPMDetect(int numChannels, ///< Number of channels in sample data.
int sampleRate ///< Sample rate in Hz.
);
/// Destructor.
virtual ~BPMDetect();
/// Inputs a block of samples for analyzing: Envelopes the samples and then
/// updates the autocorrelation estimation. When whole song data has been input
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
/// function.
///
/// Notice that data in 'samples' array can be disrupted in processing.
void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
int numSamples ///< Number of samples in buffer
);
/// Analyzes the results and returns the BPM rate. Use this function to read result
/// after whole song data has been input to the class by consecutive calls of
/// 'inputSamples' function.
///
/// \return Beats-per-minute rate, or zero if detection failed.
float getBpm();
};
}
#endif // _BPMDetect_H_

67
3rdparty/SoundTouch/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,67 @@
# SoundTouch library
# library name
set(Output pcsx2_SoundTouch)
set(CommonFlags
-march=athlon-xp
-march=prescott
)
set(OptimizationFlags
-Os
-W
)
# Debug - Build
if(CMAKE_BUILD_TYPE STREQUAL Debug)
# add defines
add_definitions(${CommonFlags} -g)
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
# Devel - Build
if(CMAKE_BUILD_TYPE STREQUAL Devel)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags})
endif(CMAKE_BUILD_TYPE STREQUAL Devel)
# Release - Build
if(CMAKE_BUILD_TYPE STREQUAL Release)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags})
endif(CMAKE_BUILD_TYPE STREQUAL Release)
# variable with all sources of this library
set(SoundTouchSources
AAFilter.cpp
FIFOSampleBuffer.cpp
FIRFilter.cpp
RateTransposer.cpp
SoundTouch.cpp
TDStretch.cpp
# WavFile.cpp # directly include in spu2x
cpu_detect_x86_gcc.cpp
mmx_optimized.cpp
sse_optimized.cpp)
# variable with all headers of this library
set(SoundTouchHeaders
AAFilter.h
BPMDetect.h
FIFOSampleBuffer.h
FIFOSamplePipe.h
FIRFilter.h
RateTransposer.h
STTypes.h
SoundTouch.h
TDStretch.h
# WavFile.h # directly include in spu2x
cpu_detect.h)
# add library
add_library(${Output} STATIC ${SoundTouchSources} ${SoundTouchHeaders})
# User flags options
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")

View File

@@ -15,6 +15,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
// File revision : $Revision: 4 $
//
// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -73,8 +80,7 @@ void FIFOSampleBuffer::setChannels(int numChannels)
{
uint usedBytes;
if (!verifyNumberOfChannels(numChannels)) return;
assert(numChannels > 0);
usedBytes = channels * samplesInBuffer;
channels = (uint)numChannels;
samplesInBuffer = usedBytes / channels;
@@ -125,7 +131,7 @@ void FIFOSampleBuffer::putSamples(uint nSamples)
//
// Parameter 'slackCapacity' tells the function how much free capacity (in
// terms of samples) there _at least_ should be, in order to the caller to
// successfully insert all the required samples to the buffer. When necessary,
// succesfully insert all the required samples to the buffer. When necessary,
// the function grows the buffer size to comply with this requirement.
//
// When using this function as means for inserting new samples, also remember
@@ -152,7 +158,7 @@ SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
}
// Ensures that the buffer has enough capacity, i.e. space for _at least_
// Ensures that the buffer has enought capacity, i.e. space for _at least_
// 'capacityRequirement' number of samples. The buffer is grown in steps of
// 4 kilobytes to eliminate the need for frequently growing up the buffer,
// as well as to round the buffer size up to the virtual memory page size.
@@ -265,3 +271,4 @@ uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
}
return samplesInBuffer;
}

View File

@@ -15,6 +15,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
// File revision : $Revision: 4 $
//
// $Id: FIFOSampleBuffer.h 143 2012-06-13 19:29:53Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -112,7 +119,7 @@ public:
/// 'putSamples(numSamples)' function.
SAMPLETYPE *ptrEnd(
uint slackCapacity ///< How much free capacity (in samples) there _at least_
///< should be so that the caller can successfully insert the
///< should be so that the caller can succesfully insert the
///< desired samples to the buffer. If necessary, the function
///< grows the buffer size to comply with this requirement.
);
@@ -155,12 +162,6 @@ public:
/// Sets number of channels, 1 = mono, 2 = stereo.
void setChannels(int numChannels);
/// Get number of channels
int getChannels()
{
return channels;
}
/// Returns nonzero if there aren't any samples available for outputting.
virtual int isEmpty() const;

View File

@@ -17,6 +17,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
// File revision : $Revision: 4 $
//
// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -51,18 +58,6 @@ namespace soundtouch
/// Abstract base class for FIFO (first-in-first-out) sample processing classes.
class FIFOSamplePipe
{
protected:
bool verifyNumberOfChannels(int nChannels) const
{
if ((nChannels > 0) && (nChannels <= SOUNDTOUCH_MAX_CHANNELS))
{
return true;
}
ST_THROW_RT_ERROR("Error: Illegal number of channels");
return false;
}
public:
// virtual default destructor
virtual ~FIFOSamplePipe() {}
@@ -127,6 +122,7 @@ public:
};
/// Base-class for sound processing routines working in FIFO principle. With this base
/// class it's easy to implement sound processing stages that can be chained together,
/// so that samples that are fed into beginning of the pipe automatically go through
@@ -149,6 +145,7 @@ protected:
output = pOutput;
}
/// Constructor. Doesn't define output pipe; it has to be set be
/// 'setOutPipe' function.
FIFOProcessor()
@@ -156,6 +153,7 @@ protected:
output = NULL;
}
/// Constructor. Configures output pipe.
FIFOProcessor(FIFOSamplePipe *pOutput ///< Output pipe.
)
@@ -163,11 +161,13 @@ protected:
output = pOutput;
}
/// Destructor.
virtual ~FIFOProcessor()
{
}
/// Returns a pointer to the beginning of the output samples.
/// This function is provided for accessing the output samples directly.
/// Please be careful for not to corrupt the book-keeping!
@@ -194,6 +194,7 @@ public:
return output->receiveSamples(outBuffer, maxSamples);
}
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
/// sample buffer without copying them anywhere.
///
@@ -205,12 +206,14 @@ public:
return output->receiveSamples(maxSamples);
}
/// Returns number of samples currently available.
virtual uint numSamples() const
{
return output->numSamples();
}
/// Returns nonzero if there aren't any samples available for outputting.
virtual int isEmpty() const
{
@@ -223,6 +226,7 @@ public:
{
return output->adjustAmountOfSamples(numSamples);
}
};
}

259
3rdparty/SoundTouch/FIRFilter.cpp vendored Normal file
View File

@@ -0,0 +1,259 @@
////////////////////////////////////////////////////////////////////////////////
///
/// General FIR digital filter routines with MMX optimization.
///
/// Note : MMX optimized functions reside in a separate, platform-specific file,
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
// File revision : $Revision: 4 $
//
// $Id: FIRFilter.cpp 131 2011-09-02 18:56:11Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include "FIRFilter.h"
#include "cpu_detect.h"
using namespace soundtouch;
/*****************************************************************************
*
* Implementation of the class 'FIRFilter'
*
*****************************************************************************/
FIRFilter::FIRFilter()
{
resultDivFactor = 0;
resultDivider = 0;
length = 0;
lengthDiv8 = 0;
filterCoeffs = NULL;
}
FIRFilter::~FIRFilter()
{
delete[] filterCoeffs;
}
// Usual C-version of the filter routine for stereo sound
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
{
uint i, j, end;
LONG_SAMPLETYPE suml, sumr;
#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 = 2 * (numSamples - length);
for (j = 0; j < end; j += 2)
{
const SAMPLETYPE *ptr;
suml = sumr = 0;
ptr = src + j;
for (i = 0; i < length; i += 4)
{
// loop is unrolled by factor of 4 here for efficiency
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
ptr[2 * i + 2] * filterCoeffs[i + 1] +
ptr[2 * i + 4] * filterCoeffs[i + 2] +
ptr[2 * i + 6] * filterCoeffs[i + 3];
sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
ptr[2 * i + 3] * filterCoeffs[i + 1] +
ptr[2 * i + 5] * filterCoeffs[i + 2] +
ptr[2 * i + 7] * filterCoeffs[i + 3];
}
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
suml >>= resultDivFactor;
sumr >>= resultDivFactor;
// saturate to 16 bit integer limits
suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
// saturate to 16 bit integer limits
sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
#else
suml *= dScaler;
sumr *= dScaler;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[j] = (SAMPLETYPE)suml;
dest[j + 1] = (SAMPLETYPE)sumr;
}
return numSamples - length;
}
// Usual C-version of the filter routine for mono sound
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
{
uint i, j, end;
LONG_SAMPLETYPE 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);
end = numSamples - length;
for (j = 0; j < end; j ++)
{
sum = 0;
for (i = 0; i < length; i += 4)
{
// loop is unrolled by factor of 4 here for efficiency
sum += src[i + 0] * filterCoeffs[i + 0] +
src[i + 1] * filterCoeffs[i + 1] +
src[i + 2] * filterCoeffs[i + 2] +
src[i + 3] * filterCoeffs[i + 3];
}
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
sum >>= resultDivFactor;
// saturate to 16 bit integer limits
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
#else
sum *= dScaler;
#endif // SOUNDTOUCH_INTEGER_SAMPLES
dest[j] = (SAMPLETYPE)sum;
src ++;
}
return end;
}
// Set filter coeffiecients and length.
//
// Throws an exception if filter length isn't divisible by 8
void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
{
assert(newLength > 0);
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
lengthDiv8 = newLength / 8;
length = lengthDiv8 * 8;
assert(length == newLength);
resultDivFactor = uResultDivFactor;
resultDivider = (SAMPLETYPE)::pow(2.0, (int)resultDivFactor);
delete[] filterCoeffs;
filterCoeffs = new SAMPLETYPE[length];
memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
}
uint FIRFilter::getLength() const
{
return length;
}
// Applies the filter to the given sequence of samples.
//
// Note : The amount of outputted samples is by value of 'filter_length'
// 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)
{
return evaluateFilterStereo(dest, src, numSamples);
} else {
return evaluateFilterMono(dest, src, numSamples);
}
}
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// depending on if we've a MMX-capable CPU available or not.
void * FIRFilter::operator new(size_t s)
{
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
return newInstance();
}
FIRFilter * FIRFilter::newInstance()
{
uint uExtensions;
uExtensions = detectCPUextensions();
// Check if MMX/SSE instruction set extensions supported by CPU
#ifdef SOUNDTOUCH_ALLOW_MMX
// MMX routines available only with integer sample types
if (uExtensions & SUPPORT_MMX)
{
return ::new FIRFilterMMX;
}
else
#endif // SOUNDTOUCH_ALLOW_MMX
#ifdef SOUNDTOUCH_ALLOW_SSE
if (uExtensions & SUPPORT_SSE)
{
// SSE support
return ::new FIRFilterSSE;
}
else
#endif // SOUNDTOUCH_ALLOW_SSE
{
// ISA optimizations not supported, use plain C version
return ::new FIRFilter;
}
}

View File

@@ -11,6 +11,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-02-13 17:13:57 -0200 (dom, 13 fev 2011) $
// File revision : $Revision: 4 $
//
// $Id: FIRFilter.h 104 2011-02-13 19:13:57Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -64,7 +71,6 @@ protected:
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) const;
virtual uint evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels);
public:
FIRFilter();
@@ -84,7 +90,7 @@ public:
uint evaluate(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples,
uint numChannels);
uint numChannels) const;
uint getLength() const;

71
3rdparty/SoundTouch/Makefile.am vendored Normal file
View File

@@ -0,0 +1,71 @@
## Process this file with automake to create Makefile.in
##
## $Id: Makefile.am 138 2012-04-01 20:00:09Z oparviai $
##
## This file is part of SoundTouch, an audio processing library for pitch/time adjustments
##
## SoundTouch is free software; you can redistribute it and/or modify it under the
## terms of the GNU General Public License as published by the Free Software
## Foundation; either version 2 of the License, or (at your option) any later
## version.
##
## SoundTouch is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
## A PARTICULAR PURPOSE. See the GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, write to the Free Software Foundation, Inc., 59 Temple
## Place - Suite 330, Boston, MA 02111-1307, USA
include $(top_srcdir)/config/am_include.mk
# set to something if you want other stuff to be included in the distribution tarball
EXTRA_DIST=SoundTouch.dsp SoundTouch.dsw SoundTouch.sln SoundTouch.vcproj
noinst_HEADERS=AAFilter.h cpu_detect.h cpu_detect_x86.cpp FIRFilter.h RateTransposer.h TDStretch.h PeakFinder.h
lib_LTLIBRARIES=libSoundTouch.la
#
libSoundTouch_la_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp RateTransposer.cpp SoundTouch.cpp TDStretch.cpp cpu_detect_x86.cpp BPMDetect.cpp PeakFinder.cpp
# Compiler flags
AM_CXXFLAGS=-O3 -fcheck-new -I../../include
# Compile the files that need MMX and SSE individually.
libSoundTouch_la_LIBADD=libSoundTouchMMX.la libSoundTouchSSE.la
noinst_LTLIBRARIES=libSoundTouchMMX.la libSoundTouchSSE.la
libSoundTouchMMX_la_SOURCES=mmx_optimized.cpp
libSoundTouchSSE_la_SOURCES=sse_optimized.cpp
# We enable optimizations by default.
# If MMX is supported compile with -mmmx.
# Do not assume -msse is also supported.
if HAVE_MMX
libSoundTouchMMX_la_CXXFLAGS = -mmmx $(AM_CXXFLAGS)
else
libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS)
endif
# We enable optimizations by default.
# If SSE is supported compile with -msse.
if HAVE_SSE
libSoundTouchSSE_la_CXXFLAGS = -msse $(AM_CXXFLAGS)
else
libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS)
endif
# Let the user disable optimizations if he wishes to.
if !X86_OPTIMIZATIONS
libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS)
libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS)
endif
# other linking flags to add
# noinst_LTLIBRARIES = libSoundTouchOpt.la
# libSoundTouch_la_LIBADD = libSoundTouchOpt.la
# libSoundTouchOpt_la_SOURCES = mmx_optimized.cpp sse_optimized.cpp
# libSoundTouchOpt_la_CXXFLAGS = -O3 -msse -fcheck-new -I../../include

View File

@@ -1,277 +1,276 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Peak detection routine.
///
/// The routine detects highest value on an array of values and calculates the
/// precise peak location as a mass-center of the 'hump' around the peak value.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <math.h>
#include <assert.h>
#include "PeakFinder.h"
using namespace soundtouch;
#define max(x, y) (((x) > (y)) ? (x) : (y))
PeakFinder::PeakFinder()
{
minPos = maxPos = 0;
}
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
int PeakFinder::findTop(const float *data, int peakpos) const
{
int i;
int start, end;
float refvalue;
refvalue = data[peakpos];
// seek within <20>10 points
start = peakpos - 10;
if (start < minPos) start = minPos;
end = peakpos + 10;
if (end > maxPos) end = maxPos;
for (i = start; i <= end; i ++)
{
if (data[i] > refvalue)
{
peakpos = i;
refvalue = data[i];
}
}
// failure if max value is at edges of seek range => it's not peak, it's at slope.
if ((peakpos == start) || (peakpos == end)) return 0;
return peakpos;
}
// Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding
// to direction defined by 'direction' until next 'hump' after minimum value will
// begin
int PeakFinder::findGround(const float *data, int peakpos, int direction) const
{
int lowpos;
int pos;
int climb_count;
float refvalue;
float delta;
climb_count = 0;
refvalue = data[peakpos];
lowpos = peakpos;
pos = peakpos;
while ((pos > minPos+1) && (pos < maxPos-1))
{
int prevpos;
prevpos = pos;
pos += direction;
// calculate derivate
delta = data[pos] - data[prevpos];
if (delta <= 0)
{
// going downhill, ok
if (climb_count)
{
climb_count --; // decrease climb count
}
// check if new minimum found
if (data[pos] < refvalue)
{
// new minimum found
lowpos = pos;
refvalue = data[pos];
}
}
else
{
// going uphill, increase climbing counter
climb_count ++;
if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit
}
}
return lowpos;
}
// Find offset where the value crosses the given level, when starting from 'peakpos' and
// proceeds to direction defined in 'direction'
int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, int direction) const
{
float peaklevel;
int pos;
peaklevel = data[peakpos];
assert(peaklevel >= level);
pos = peakpos;
while ((pos >= minPos) && (pos < maxPos))
{
if (data[pos + direction] < level) return pos; // crossing found
pos += direction;
}
return -1; // not found
}
// Calculates the center of mass location of 'data' array items between 'firstPos' and 'lastPos'
double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) const
{
int i;
float sum;
float wsum;
sum = 0;
wsum = 0;
for (i = firstPos; i <= lastPos; i ++)
{
sum += (float)i * data[i];
wsum += data[i];
}
if (wsum < 1e-6) return 0;
return sum / wsum;
}
/// get exact center of peak near given position by calculating local mass of center
double PeakFinder::getPeakCenter(const float *data, int peakpos) const
{
float peakLevel; // peak level
int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
float cutLevel; // cutting value
float groundLevel; // ground level of the peak
int gp1, gp2; // bottom positions of the peak 'hump'
// find ground positions.
gp1 = findGround(data, peakpos, -1);
gp2 = findGround(data, peakpos, 1);
peakLevel = data[peakpos];
if (gp1 == gp2)
{
// avoid rounding errors when all are equal
assert(gp1 == peakpos);
cutLevel = groundLevel = peakLevel;
} else {
// get average of the ground levels
groundLevel = 0.5f * (data[gp1] + data[gp2]);
// calculate 70%-level of the peak
cutLevel = 0.70f * peakLevel + 0.30f * groundLevel;
}
// find mid-level crossings
crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1);
crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1);
if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak..
// calculate mass center of the peak surroundings
return calcMassCenter(data, crosspos1, crosspos2);
}
double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
{
int i;
int peakpos; // position of peak level
double highPeak, peak;
this->minPos = aminPos;
this->maxPos = amaxPos;
// find absolute peak
peakpos = minPos;
peak = data[minPos];
for (i = minPos + 1; i < maxPos; i ++)
{
if (data[i] > peak)
{
peak = data[i];
peakpos = i;
}
}
// Calculate exact location of the highest peak mass center
highPeak = getPeakCenter(data, peakpos);
peak = highPeak;
// Now check if the highest peak were in fact harmonic of the true base beat peak
// - sometimes the highest peak can be Nth harmonic of the true base peak yet
// just a slightly higher than the true base
for (i = 1; i < 3; i ++)
{
double peaktmp, harmonic;
int i1,i2;
harmonic = (double)pow(2.0, i);
peakpos = (int)(highPeak / harmonic + 0.5f);
if (peakpos < minPos) break;
peakpos = findTop(data, peakpos); // seek true local maximum index
if (peakpos == 0) continue; // no local max here
// calculate mass-center of possible harmonic peak
peaktmp = getPeakCenter(data, peakpos);
// accept harmonic peak if
// (a) it is found
// (b) is within <20>4% of the expected harmonic interval
// (c) has at least half x-corr value of the max. peak
double diff = harmonic * peaktmp / highPeak;
if ((diff < 0.96) || (diff > 1.04)) continue; // peak too afar from expected
// now compare to highest detected peak
i1 = (int)(highPeak + 0.5);
i2 = (int)(peaktmp + 0.5);
if (data[i2] >= 0.4*data[i1])
{
// The harmonic is at least half as high primary peak,
// thus use the harmonic peak instead
peak = peaktmp;
}
}
return peak;
}
////////////////////////////////////////////////////////////////////////////////
///
/// Peak detection routine.
///
/// The routine detects highest value on an array of values and calculates the
/// precise peak location as a mass-center of the 'hump' around the peak value.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-12-28 17:52:47 -0200 (sex, 28 dez 2012) $
// File revision : $Revision: 4 $
//
// $Id: PeakFinder.cpp 164 2012-12-28 19:52:47Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <math.h>
#include <assert.h>
#include "PeakFinder.h"
using namespace soundtouch;
#define max(x, y) (((x) > (y)) ? (x) : (y))
PeakFinder::PeakFinder()
{
minPos = maxPos = 0;
}
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
int PeakFinder::findTop(const float *data, int peakpos) const
{
int i;
int start, end;
float refvalue;
refvalue = data[peakpos];
// seek within ±10 points
start = peakpos - 10;
if (start < minPos) start = minPos;
end = peakpos + 10;
if (end > maxPos) end = maxPos;
for (i = start; i <= end; i ++)
{
if (data[i] > refvalue)
{
peakpos = i;
refvalue = data[i];
}
}
// failure if max value is at edges of seek range => it's not peak, it's at slope.
if ((peakpos == start) || (peakpos == end)) return 0;
return peakpos;
}
// Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding
// to direction defined by 'direction' until next 'hump' after minimum value will
// begin
int PeakFinder::findGround(const float *data, int peakpos, int direction) const
{
int lowpos;
int pos;
int climb_count;
float refvalue;
float delta;
climb_count = 0;
refvalue = data[peakpos];
lowpos = peakpos;
pos = peakpos;
while ((pos > minPos+1) && (pos < maxPos-1))
{
int prevpos;
prevpos = pos;
pos += direction;
// calculate derivate
delta = data[pos] - data[prevpos];
if (delta <= 0)
{
// going downhill, ok
if (climb_count)
{
climb_count --; // decrease climb count
}
// check if new minimum found
if (data[pos] < refvalue)
{
// new minimum found
lowpos = pos;
refvalue = data[pos];
}
}
else
{
// going uphill, increase climbing counter
climb_count ++;
if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit
}
}
return lowpos;
}
// Find offset where the value crosses the given level, when starting from 'peakpos' and
// proceeds to direction defined in 'direction'
int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, int direction) const
{
float peaklevel;
int pos;
peaklevel = data[peakpos];
assert(peaklevel >= level);
pos = peakpos;
while ((pos >= minPos) && (pos < maxPos))
{
if (data[pos + direction] < level) return pos; // crossing found
pos += direction;
}
return -1; // not found
}
// Calculates the center of mass location of 'data' array items between 'firstPos' and 'lastPos'
double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) const
{
int i;
float sum;
float wsum;
sum = 0;
wsum = 0;
for (i = firstPos; i <= lastPos; i ++)
{
sum += (float)i * data[i];
wsum += data[i];
}
if (wsum < 1e-6) return 0;
return sum / wsum;
}
/// get exact center of peak near given position by calculating local mass of center
double PeakFinder::getPeakCenter(const float *data, int peakpos) const
{
float peakLevel; // peak level
int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
float cutLevel; // cutting value
float groundLevel; // ground level of the peak
int gp1, gp2; // bottom positions of the peak 'hump'
// find ground positions.
gp1 = findGround(data, peakpos, -1);
gp2 = findGround(data, peakpos, 1);
groundLevel = 0.5f * (data[gp1] + data[gp2]);
peakLevel = data[peakpos];
// calculate 70%-level of the peak
cutLevel = 0.70f * peakLevel + 0.30f * groundLevel;
// find mid-level crossings
crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1);
crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1);
if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak..
// calculate mass center of the peak surroundings
return calcMassCenter(data, crosspos1, crosspos2);
}
double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
{
int i;
int peakpos; // position of peak level
double highPeak, peak;
this->minPos = aminPos;
this->maxPos = amaxPos;
// find absolute peak
peakpos = minPos;
peak = data[minPos];
for (i = minPos + 1; i < maxPos; i ++)
{
if (data[i] > peak)
{
peak = data[i];
peakpos = i;
}
}
// Calculate exact location of the highest peak mass center
highPeak = getPeakCenter(data, peakpos);
peak = highPeak;
// Now check if the highest peak were in fact harmonic of the true base beat peak
// - sometimes the highest peak can be Nth harmonic of the true base peak yet
// just a slightly higher than the true base
for (i = 3; i < 10; i ++)
{
double peaktmp, harmonic;
int i1,i2;
harmonic = (double)i * 0.5;
peakpos = (int)(highPeak / harmonic + 0.5f);
if (peakpos < minPos) break;
peakpos = findTop(data, peakpos); // seek true local maximum index
if (peakpos == 0) continue; // no local max here
// calculate mass-center of possible harmonic peak
peaktmp = getPeakCenter(data, peakpos);
// accept harmonic peak if
// (a) it is found
// (b) is within ±4% of the expected harmonic interval
// (c) has at least half x-corr value of the max. peak
double diff = harmonic * peaktmp / highPeak;
if ((diff < 0.96) || (diff > 1.04)) continue; // peak too afar from expected
// now compare to highest detected peak
i1 = (int)(highPeak + 0.5);
i2 = (int)(peaktmp + 0.5);
if (data[i2] >= 0.4*data[i1])
{
// The harmonic is at least half as high primary peak,
// thus use the harmonic peak instead
peak = peaktmp;
}
}
return peak;
}

View File

@@ -1,90 +1,97 @@
////////////////////////////////////////////////////////////////////////////////
///
/// The routine detects highest value on an array of values and calculates the
/// precise peak location as a mass-center of the 'hump' around the peak value.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PeakFinder_H_
#define _PeakFinder_H_
namespace soundtouch
{
class PeakFinder
{
protected:
/// Min, max allowed peak positions within the data vector
int minPos, maxPos;
/// Calculates the mass center between given vector items.
double calcMassCenter(const float *data, ///< Data vector.
int firstPos, ///< Index of first vector item belonging to the peak.
int lastPos ///< Index of last vector item belonging to the peak.
) const;
/// Finds the data vector index where the monotoniously decreasing signal crosses the
/// given level.
int findCrossingLevel(const float *data, ///< Data vector.
float level, ///< Goal crossing level.
int peakpos, ///< Peak position index within the data vector.
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
) const;
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
int findTop(const float *data, int peakpos) const;
/// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right-
/// or left-hand side of the given peak position.
int findGround(const float *data, /// Data vector.
int peakpos, /// Peak position index within the data vector.
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
) const;
/// get exact center of peak near given position by calculating local mass of center
double getPeakCenter(const float *data, int peakpos) const;
public:
/// Constructor.
PeakFinder();
/// Detect exact peak position of the data vector by finding the largest peak 'hump'
/// and calculating the mass-center location of the peak hump.
///
/// \return The location of the largest base harmonic peak hump.
double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has
/// to be at least 'maxPos' items long.
int minPos, ///< Min allowed peak location within the vector data.
int maxPos ///< Max allowed peak location within the vector data.
);
};
}
#endif // _PeakFinder_H_
////////////////////////////////////////////////////////////////////////////////
///
/// The routine detects highest value on an array of values and calculates the
/// precise peak location as a mass-center of the 'hump' around the peak value.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-12-30 18:33:46 -0200 (sex, 30 dez 2011) $
// File revision : $Revision: 4 $
//
// $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef _PeakFinder_H_
#define _PeakFinder_H_
namespace soundtouch
{
class PeakFinder
{
protected:
/// Min, max allowed peak positions within the data vector
int minPos, maxPos;
/// Calculates the mass center between given vector items.
double calcMassCenter(const float *data, ///< Data vector.
int firstPos, ///< Index of first vector item beloging to the peak.
int lastPos ///< Index of last vector item beloging to the peak.
) const;
/// Finds the data vector index where the monotoniously decreasing signal crosses the
/// given level.
int findCrossingLevel(const float *data, ///< Data vector.
float level, ///< Goal crossing level.
int peakpos, ///< Peak position index within the data vector.
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
) const;
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
int findTop(const float *data, int peakpos) const;
/// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right-
/// or left-hand side of the given peak position.
int findGround(const float *data, /// Data vector.
int peakpos, /// Peak position index within the data vector.
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
) const;
/// get exact center of peak near given position by calculating local mass of center
double getPeakCenter(const float *data, int peakpos) const;
public:
/// Constructor.
PeakFinder();
/// Detect exact peak position of the data vector by finding the largest peak 'hump'
/// and calculating the mass-center location of the peak hump.
///
/// \return The location of the largest base harmonic peak hump.
double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has
/// to be at least 'maxPos' items long.
int minPos, ///< Min allowed peak location within the vector data.
int maxPos ///< Max allowed peak location within the vector data.
);
};
}
#endif // _PeakFinder_H_

777
3rdparty/SoundTouch/README.html vendored Normal file
View File

@@ -0,0 +1,777 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SoundTouch library README</title>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-1252">
<meta http-equiv="Content-Language" content="en-us">
<meta name="author" content="Olli Parviainen">
<meta name="description"
content="Readme file for SoundTouch audio processing library">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<style> <!-- .normal { font-family: Arial }
--></style>
</head>
<body class="normal">
<hr>
<h1>SoundTouch audio processing library v1.7.1</h1>
<p class="normal">SoundTouch library Copyright <20> Olli Parviainen 2001-2012 </p>
<hr>
<h2>1. Introduction </h2>
<p>SoundTouch is an open-source audio processing library that allows
changing the sound tempo, pitch and playback rate parameters
independently from each other, i.e.:</p>
<ul>
<li> Sound tempo can be increased or decreased while maintaining the
original pitch </li>
<li> Sound pitch can be increased or decreased while maintaining the
original tempo </li>
<li> Change playback rate that affects both tempo and pitch at the
same time </li>
<li> Choose any combination of tempo/pitch/rate</li>
</ul>
<h3>1.1 Contact information </h3>
<p>Author email: oparviai 'at' iki.fi </p>
<p>SoundTouch WWW page: <a href="http://www.surina.net/soundtouch">http://www.surina.net/soundtouch</a></p>
<hr>
<h2>2. Compiling SoundTouch</h2>
<p>Before compiling, notice that you can choose the sample data format
if it's desirable to use floating point sample data instead of 16bit
integers. See section "sample data format" for more information.</p>
<h3>2.1. Building in Microsoft Windows</h3>
<p>Project files for Microsoft Visual C++ 6.0 and Visual C++ .NET are
supplied with the source code package.<br>
</p>
<p> Please notice that SoundTouch library uses processor-specific
optimizations for Pentium III and AMD processors. Visual Studio .NET
and later versions supports the required instructions by default, but
Visual Studio 6.0 requires a processor pack upgrade to be installed in
order to support these optimizations. The processor pack upgrade can be
downloaded from Microsoft site at this URL:</p>
<p><a href="http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx">http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx</a></p>
<p>If the above URL is unavailable or removed, go to <a
href="http://msdn.microsoft.com/"> http://msdn.microsoft.com</a> and
perform a search with keywords "processor pack". </p>
<p>To build the binaries with Visual C++ compiler, either run
"make-win.bat" script, or open the appropriate project files in source
code directories with Visual Studio. The final executable will appear
under the "SoundTouch\bin" directory. If using the Visual Studio IDE
instead of the make-win.bat script, directories bin and lib may need to
be created manually to the SoundTouch package root for the final
executables. The make-win.bat script creates these directories
automatically. </p>
<h3>2.2. Building in Gnu platforms</h3>
<p>The SoundTouch library compiles in practically any platform
supporting GNU compiler (GCC) tools. SoundTouch requires GCC version 4.3 or later.</p>
<p>To build and install the binaries, run the following commands in
/soundtouch directory:</p>
<table border="0" cellpadding="0" cellspacing="4">
<tbody>
<tr>
<td style="vertical-align: top;">
<pre>./bootstrap -</pre>
</td>
<td style="vertical-align: top;">Creates "configure" file with
local autoconf/automake toolset.<br>
</td>
</tr>
<tr valign="top">
<td>
<pre>./configure -</pre>
</td>
<td>
<p>Configures the SoundTouch package for the local environment.
Notice that "configure" file is not available before running the
"./bootstrap" command as above.<br>
</p>
</td>
</tr>
<tr valign="top">
<td>
<pre>make -</pre>
</td>
<td>
<p>Builds the SoundTouch library &amp; SoundStretch utility.</p>
</td>
</tr>
<tr valign="top">
<td>
<pre>make install -</pre>
</td>
<td>
<p>Installs the SoundTouch &amp; BPM libraries to <b>/usr/local/lib</b>
and SoundStretch utility to <b>/usr/local/bin</b>. Please notice that
'root' privileges may be required to install the binaries to the
destination locations.</p>
</td>
</tr>
</tbody>
</table>
<h4><b>2.2.1 Required GNU tools</b>&nbsp;</h4>
<p> <span style="font-weight: bold;">Bash shell</span>, <span
style="font-weight: bold;">GNU C++ compiler</span>, <span
style="font-weight: bold;">libtool</span>, <span
style="font-weight: bold;">autoconf</span> and <span
style="font-weight: bold;">automake</span> tools
are required for compiling the SoundTouch library. These are usually
included with the GNU/Linux distribution, but if not, install these
packages first. For example, Ubuntu Linux can acquire and install
these with the following command:</p>
<pre><b>sudo apt-get install automake autoconf libtool build-essential</b></pre>
<h4><b>2.2.2 Problems with GCC compiler compatibility</b></h4>
<p>At the release time the SoundTouch package has been tested to
compile in GNU/Linux platform. However, If you have problems getting the
SoundTouch library compiled, try disabling optimizations that are specific for
x86 processors by running <b>./configure</b> script with switch
<blockquote>
<pre>--enable-x86-optimizations=no</pre>
</blockquote>
Alternatively, if you don't use GNU Configure system, edit file "include/STTypes.h"
directly and remove the following definition:<blockquote>
<pre>#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1</pre>
</blockquote>
<h4><b>2.2.3 Compiling Shared Library / DLL version</b></h4>
<p>
The GNU compilation does not automatically create a shared-library version of
SoundTouch (.so or .dll). If such is desired, then you can create it as follows
after running the usual compilation:</p>
<blockquote>
<pre>g++ -shared -static -DDLL_EXPORTS -I../../include -o SoundTouch.dll \
SoundTouchDLL.cpp ../SoundTouch/.libs/libSoundTouch.a
sstrip SoundTouch.dll</pre>
</blockquote>
<h3>2.1. Building in Android</h3>
<p>Android compilation instructions are within the
source code package, see file &quot;<b>source/Android-lib/README-SoundTouch-Android.html</b>&quot;
in the package.</p>
<hr>
<h2>3. About implementation &amp; Usage tips <h3>3.1. Supported sample data formats</h3>
<p>The sample data format can be chosen between 16bit signed integer
and 32bit floating point values, the default is 32bit floating point. </p>
<p> In Windows environment, the sample data format is chosen in file
"STTypes.h" by choosing one of the following defines:</p>
<ul>
<li> <span style="font-weight: bold;">#define
SOUNDTOUCH_INTEGER_SAMPLES</span> for 16bit signed integer </li>
<li> <span style="font-weight: bold;">#define </span><span
style="font-weight: bold;">SOUNDTOUCH_</span><span
style="font-weight: bold;">FLOAT_SAMPLES</span> for 32bit floating
point</li>
</ul>
<p> In GNU environment, the floating sample format is used by default,
but integer sample format can be chosen by giving the following switch
to the configure script: </p>
<blockquote>
<pre>./configure --enable-integer-samples</pre>
</blockquote>
<p>The sample data can have either single (mono) or double (stereo)
audio channel. Stereo data is interleaved so that every other data
value is for left channel and every second for right channel. Notice
that while it'd be possible in theory to process stereo sound as two
separate mono channels, this isn't recommended because processing the
channels separately would result in losing the phase coherency between
the channels, which consequently would ruin the stereo effect.</p>
<p>Sample rates between 8000-48000H are supported.</p>
<h3>3.2. Processing latency</h3>
<p>The processing and latency constraints of the SoundTouch library are:</p>
<ul>
<li> Input/output processing latency for the SoundTouch processor is
around 100 ms. This is when time-stretching is used. If the rate
transposing effect alone is used, the latency requirement is much
shorter, see section 'About algorithms'. </li>
<li> Processing CD-quality sound (16bit stereo sound with 44100H
sample rate) in real-time or faster is possible starting from
processors equivalent to Intel Pentium 133Mh or better, if using the
"quick" processing algorithm. If not using the "quick" mode or if
floating point sample data are being used, several times more CPU power
is typically required.</li>
</ul>
<h3>3.3. About algorithms</h3>
<p>SoundTouch provides three seemingly independent effects: tempo,
pitch and playback rate control. These three controls are implemented
as combination of two primary effects, <em>sample rate transposing</em>
and <em>time-stretching</em>.</p>
<p><em>Sample rate transposing</em> affects both the audio stream
duration and pitch. It's implemented simply by converting the original
audio sample stream to the&nbsp; desired duration by interpolating from
the original audio samples. In SoundTouch, linear interpolation with
anti-alias filtering is used. Theoretically a higher-order
interpolation provide better result than 1st order linear
interpolation, but in audio application linear interpolation together
with anti-alias filtering performs subjectively about as well as
higher-order filtering would.</p>
<p><em>Time-stretching </em>means changing the audio stream duration
without affecting it's pitch. SoundTouch uses WSOLA-like
time-stretching routines that operate in the time domain. Compared to
sample rate transposing, time-stretching is a much heavier operation
and also requires a longer processing "window" of sound samples used by
the processing algorithm, thus increasing the algorithm input/output
latency. Typical i/o latency for the SoundTouch time-stretch algorithm
is around 100 ms.</p>
<p>Sample rate transposing and time-stretching are then used together
to produce the tempo, pitch and rate controls:</p>
<ul>
<li> <strong>'Tempo'</strong> control is implemented purely by
time-stretching. </li>
<li> <strong>'Rate</strong>' control is implemented purely by sample
rate transposing. </li>
<li> <strong>'Pitch</strong>' control is implemented as a
combination of time-stretching and sample rate transposing. For
example, to increase pitch the audio stream is first time-stretched to
longer duration (without affecting pitch) and then transposed back to
original duration by sample rate transposing, which simultaneously
reduces duration and increases pitch. The result is original duration
but increased pitch.</li>
</ul>
<h3>3.4 Tuning the algorithm parameters</h3>
<p>The time-stretch algorithm has few parameters that can be tuned to
optimize sound quality for certain application. The current default
parameters have been chosen by iterative if-then analysis (read: "trial
and error") to obtain best subjective sound quality in pop/rock music
processing, but in applications processing different kind of sound the
default parameter set may result into a sub-optimal result.</p>
<p>The time-stretch algorithm default parameter values are set by the
following #defines in file "TDStretch.h":</p>
<blockquote>
<pre>#define DEFAULT_SEQUENCE_MS AUTOMATIC<br>#define DEFAULT_SEEKWINDOW_MS AUTOMATIC<br>#define DEFAULT_OVERLAP_MS 8</pre>
</blockquote>
<p>These parameters affect to the time-stretch algorithm as follows:</p>
<ul>
<li> <strong>DEFAULT_SEQUENCE_MS</strong>: This is the default
length of a single processing sequence in milliseconds which determines
the how the original sound is chopped in the time-stretch algorithm.
Larger values mean fewer sequences are used in processing. In principle
a larger value sounds better when slowing down the tempo, but worse
when increasing the tempo and vice versa.&nbsp;<br>
<br>
By default, this setting value is calculated automatically according to
tempo value.<br>
</li>
<li> <strong>DEFAULT_SEEKWINDOW_MS</strong>: The seeking window
default length in milliseconds is for the algorithm that seeks the best
possible overlapping location. This determines from how wide a sample
"window" the algorithm can use to find an optimal mixing location when
the sound sequences are to be linked back together.&nbsp;<br>
<br>
The bigger this window setting is, the higher the possibility to find a
better mixing position becomes, but at the same time large values may
cause a "drifting" sound artifact because neighboring sequences can be
chosen at more uneven intervals. If there's a disturbing artifact that
sounds as if a constant frequency was drifting around, try reducing
this setting.<br>
<br>
By default, this setting value is calculated automatically according to
tempo value.<br>
</li>
<li> <strong>DEFAULT_OVERLAP_MS</strong>: Overlap length in
milliseconds. When the sound sequences are mixed back together to form
again a continuous sound stream, this parameter defines how much the
ends of the consecutive sequences will overlap with each other.<br>
<br>
This shouldn't be that critical parameter. If you reduce the
DEFAULT_SEQUENCE_MS setting by a large amount, you might wish to try a
smaller value on this.</li>
</ul>
<p>Notice that these parameters can also be set during execution time
with functions "<strong>TDStretch::setParameters()</strong>" and "<strong>SoundTouch::setSetting()</strong>".</p>
<p>The table below summaries how the parameters can be adjusted for
different applications:</p>
<table border="1">
<tbody>
<tr>
<td valign="top"><strong>Parameter name</strong></td>
<td valign="top"><strong>Default value magnitude</strong></td>
<td valign="top"><strong>Larger value affects...</strong></td>
<td valign="top"><strong>Smaller value affects...</strong></td>
<td valign="top"><strong>Effect to CPU burden</strong></td>
</tr>
<tr>
<td valign="top">
<pre>SEQUENCE_MS</pre>
</td>
<td valign="top">Default value is relatively large, chosen for
slowing down music tempo</td>
<td valign="top">Larger value is usually better for slowing down
tempo. Growing the value decelerates the "echoing" artifact when
slowing down the tempo.</td>
<td valign="top">Smaller value might be better for speeding up
tempo. Reducing the value accelerates the "echoing" artifact when
slowing down the tempo </td>
<td valign="top">Increasing the parameter value reduces
computation burden</td>
</tr>
<tr>
<td valign="top">
<pre>SEEKWINDOW_MS</pre>
</td>
<td valign="top">Default value is relatively large, chosen for
slowing down music tempo</td>
<td valign="top">Larger value eases finding a good mixing
position, but may cause a "drifting" artifact</td>
<td valign="top">Smaller reduce possibility to find a good mixing
position, but reduce the "drifting" artifact.</td>
<td valign="top">Increasing the parameter value increases
computation burden</td>
</tr>
<tr>
<td valign="top">
<pre>OVERLAP_MS</pre>
</td>
<td valign="top">Default value is relatively large, chosen to
suit with above parameters.</td>
<td valign="top">&nbsp;</td>
<td valign="top">If you reduce the "sequence ms" setting, you
might wish to try a smaller value.</td>
<td valign="top">Increasing the parameter value increases
computation burden</td>
</tr>
</tbody>
</table>
<h3>3.5 Performance Optimizations </h3>
<p><strong>General optimizations:</strong></p>
<p>The time-stretch routine has a 'quick' mode that substantially
speeds up the algorithm but may degrade the sound quality by a small
amount. This mode is activated by calling SoundTouch::setSetting()
function with parameter&nbsp; id of SETTING_USE_QUICKSEEK and value
"1", i.e. </p>
<blockquote>
<p>setSetting(SETTING_USE_QUICKSEEK, 1);</p>
</blockquote>
<p><strong>CPU-specific optimizations:</strong></p>
<ul>
<li> Intel MMX optimized routines are used with compatible CPUs when
16bit integer sample type is used. MMX optimizations are available both
in Win32 and Gnu/x86 platforms. Compatible processors are Intel
PentiumMMX and later; AMD K6-2, Athlon and later. </li>
<li> Intel SSE optimized routines are used with compatible CPUs when
floating point sample type is used. SSE optimizations are currently
implemented for Win32 platform only. Processors compatible with SSE
extension are Intel processors starting from Pentium-III, and AMD
processors starting from Athlon XP. </li>
<li> AMD 3DNow! optimized routines are used with compatible CPUs when
floating point sample type is used, but SSE extension isn't supported .
3DNow! optimizations are currently implemented for Win32 platform only.
These optimizations are used in AMD K6-2 and Athlon (classic) CPU's;
better performing SSE routines are used with AMD processor starting
from Athlon XP. </li>
</ul>
<hr>
<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
</h2>
<p>SoundStretch audio processing utility<br>
Copyright (c) Olli Parviainen 2002-2012</p>
<p>SoundStretch is a simple command-line application that can change
tempo, pitch and playback rates of WAV sound files. This program is
intended primarily to demonstrate how the "SoundTouch" library can be
used to process sound in your own program, but it can as well be used
for processing sound files.</p>
<h3>4.1. SoundStretch Usage Instructions</h3>
<p>SoundStretch Usage syntax:</p>
<blockquote>
<pre>soundstretch infilename outfilename [switches]</pre>
</blockquote>
<p>Where: </p>
<table width="100%" border="0" cellpadding="2">
<tbody>
<tr>
<td valign="top">
<pre>"infilename"</pre>
</td>
<td valign="top">Name of the input sound data file (in .WAV audio
file format). Give "stdin" as filename to use standard input pipe. </td>
</tr>
<tr>
<td valign="top">
<pre>"outfilename"</pre>
</td>
<td valign="top">Name of the output sound file where the
resulting sound is saved (in .WAV audio file format). This parameter
may be omitted if you&nbsp; don't want to save the output (e.g. when
only calculating BPM rate with '-bpm' switch). Give "stdout" as
filename to use standard output pipe.</td>
</tr>
<tr>
<td valign="top">
<pre>&nbsp;[switches]</pre>
</td>
<td valign="top">Are one or more control switches.</td>
</tr>
</tbody>
</table>
<p>Available control switches are:</p>
<table width="100%" border="0" cellpadding="2">
<tbody>
<tr>
<td valign="top">
<pre>-tempo=n </pre>
</td>
<td valign="top">Change the sound tempo by n percents (n = -95.0
.. +5000.0 %) </td>
</tr>
<tr>
<td valign="top">
<pre>-pitch=n</pre>
</td>
<td valign="top">Change the sound pitch by n semitones (n = -60.0
.. + 60.0 semitones) </td>
</tr>
<tr>
<td valign="top">
<pre>-rate=n</pre>
</td>
<td valign="top">Change the sound playback rate by n percents (n
= -95.0 .. +5000.0 %) </td>
</tr>
<tr>
<td valign="top">
<pre>-bpm=n</pre>
</td>
<td valign="top">Detect the Beats-Per-Minute (BPM) rate of the
sound and adjust the tempo to meet 'n' BPMs. When this switch is
applied, the "-tempo" switch is ignored. If "=n" is omitted, i.e.
switch "-bpm" is used alone, then the BPM rate is estimated and
displayed, but tempo not adjusted according to the BPM value. </td>
</tr>
<tr>
<td valign="top">
<pre>-quick</pre>
</td>
<td valign="top">Use quicker tempo change algorithm. Gains speed
but loses sound quality. </td>
</tr>
<tr>
<td valign="top">
<pre>-naa</pre>
</td>
<td valign="top">Don't use anti-alias filtering in sample rate
transposing. Gains speed but loses sound quality. </td>
</tr>
<tr>
<td valign="top">
<pre>-license</pre>
</td>
<td valign="top">Displays the program license text (LGPL)</td>
</tr>
</tbody>
</table>
<p>Notes:</p>
<ul>
<li> To use standard input/output pipes for processing, give "stdin"
and "stdout" as input/output filenames correspondingly. The standard
input/output pipes will still carry the audio data in .wav audio file
format. </li>
<li> The numerical switches allow both integer (e.g. "-tempo=123")
and decimal (e.g. "-tempo=123.45") numbers. </li>
<li> The "-naa" and/or "-quick" switches can be used to reduce CPU
usage while compromising some sound quality </li>
<li> The BPM detection algorithm works by detecting repeating bass or
drum patterns at low frequencies of &lt;250Hz. A lower-than-expected
BPM figure may be reported for music with uneven or complex bass
patterns. </li>
</ul>
<h3>4.2. SoundStretch usage examples </h3>
<p><strong>Example 1</strong></p>
<p>The following command increases tempo of the sound file
"originalfile.wav" by 12.5% and stores result to file
"destinationfile.wav":</p>
<blockquote>
<pre>soundstretch originalfile.wav destinationfile.wav -tempo=12.5</pre>
</blockquote>
<p><strong>Example 2</strong></p>
<p>The following command decreases the sound pitch (key) of the sound
file "orig.wav" by two semitones and stores the result to file
"dest.wav":</p>
<blockquote>
<pre>soundstretch orig.wav dest.wav -pitch=-2</pre>
</blockquote>
<p><strong>Example 3</strong></p>
<p>The following command processes the file "orig.wav" by decreasing
the sound tempo by 25.3% and increasing the sound pitch (key) by 1.5
semitones. Resulting .wav audio data is directed to standard output
pipe:</p>
<blockquote>
<pre>soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5</pre>
</blockquote>
<p><strong>Example 4</strong></p>
<p>The following command detects the BPM rate of the file "orig.wav"
and adjusts the tempo to match 100 beats per minute. Result is stored
to file "dest.wav":</p>
<blockquote>
<pre>soundstretch orig.wav dest.wav -bpm=100</pre>
</blockquote>
<p><strong>Example 5</strong></p>
<p>The following command reads .wav sound data from standard input pipe
and estimates the BPM rate:</p>
<blockquote>
<pre>soundstretch stdin -bpm</pre>
</blockquote>
<hr>
<h2>5. Change History</h2>
<h3>5.1. SoundTouch library Change History </h3>
<p><b>1.7.1:</b></p>
<ul>
<li>Added files for Android compilation
</ul>
<p><b>1.7.0:</b></p>
<ul>
<li>Sound quality improvements/li>
<li>Improved flush() to adjust output sound stream duration to match better with
ideal duration</li>
<li>Rewrote x86 cpu feature check to resolve compatibility problems</li>
<li>Configure script automatically checks if CPU supports mmx & sse compatibility for GNU platform, and
the script support now "--enable-x86-optimizations" switch to allow disabling x86-specific optimizations.</li>
<li>Revised #define conditions for 32bit/64bit compatibility</li>
<li>gnu autoconf/automake script compatibility fixes</li>
<li>Tuned beat-per-minute detection algorithm</li>
</ul>
<p><b>1.6.0:</b></p>
<ul>
<li> Added automatic cutoff threshold adaptation to beat detection
routine to better adapt BPM calculation to different types of music </li>
<li> Retired 3DNow! optimization support as 3DNow! is nowadays
obsoleted and assembler code is nuisance to maintain</li>
<li>Retired "configure" file from source code package due to
autoconf/automake versio conflicts, so that it is from now on to be
generated by invoking "boostrap" script that uses locally available
toolchain version for generating the "configure" file</li>
<li>Resolved namespace/label naming conflicts with other libraries by
replacing global labels such as INTEGER_SAMPLES with more specific
SOUNDTOUCH_INTEGER_SAMPLES etc.<br>
</li>
<li>Updated windows build scripts &amp; project files for Visual
Studio 2008 support</li>
<li> Updated SoundTouch.dll API for .NET compatibility</li>
<li> Added API for querying nominal processing input &amp; output
sample batch sizes</li>
</ul>
<p><strong>1.5.0:</strong></p>
<ul>
<li> Added normalization to correlation calculation and improvement
automatic seek/sequence parameter calculation to improve sound quality </li>
<li> Bugfixes:&nbsp;
<ul>
<li> Fixed negative array indexing in quick seek algorithm </li>
<li> FIR autoalias filter running too far in processing buffer </li>
<li> Check against zero sample count in rate transposing </li>
<li> Fix for x86-64 support: Removed pop/push instructions from
the cpu detection algorithm.&nbsp; </li>
<li> Check against empty buffers in FIFOSampleBuffer </li>
<li> Other minor fixes &amp; code cleanup</li>
</ul>
</li>
<li> Fixes in compilation scripts for non-Intel platforms </li>
<li> Added Dynamic-Link-Library (DLL) version of SoundTouch library
build, provided with Delphi/Pascal wrapper for calling the dll routines
</li>
<li> Added #define PREVENT_CLICK_AT_RATE_CROSSOVER that prevents a
click artifact when crossing the nominal pitch from either positive to
negative side or vice versa</li>
</ul>
<p><strong>1.4.1:</strong></p>
<ul>
<li> Fixed a buffer overflow bug in BPM detect algorithm routines if
processing more than 2048 samples at one call&nbsp;</li>
</ul>
<p><strong>1.4.0:</strong></p>
<ul>
<li> Improved sound quality by automatic calculation of time stretch
algorithm processing parameters according to tempo setting </li>
<li> Moved BPM detection routines from SoundStretch application into
SoundTouch library </li>
<li> Bugfixes: Usage of uninitialied variables, GNU build scripts,
compiler errors due to 'const' keyword mismatch. </li>
<li> Source code cleanup</li>
</ul>
<p><strong>1.3.1: </strong> </p>
<ul>
<li> Changed static class declaration to GCC 4.x compiler compatible
syntax. </li>
<li> Enabled MMX/SSE-optimized routines also for GCC compilers.
Earlier the MMX/SSE-optimized routines were written in
compiler-specific inline assembler, now these routines are migrated to
use compiler intrinsic syntax which allows compiling the same
MMX/SSE-optimized source code with both Visual C++ and GCC compilers. </li>
<li> Set floating point as the default sample format and added switch
to the GNU configure script for selecting the other sample format.</li>
</ul>
<p><strong>1.3.0: </strong> </p>
<ul>
<li> Fixed tempo routine output duration inaccuracy due to rounding
error </li>
<li> Implemented separate processing routines for integer and
floating arithmetic to allow improvements to floating point routines
(earlier used algorithms mostly optimized for integer arithmetic also
for floating point samples) </li>
<li> Fixed a bug that distorts sound if sample rate changes during
the sound stream </li>
<li> Fixed a memory leak that appeared in MMX/SSE/3DNow! optimized
routines </li>
<li> Reduced redundant code pieces in MMX/SSE/3DNow! optimized
routines vs. the standard C routines. </li>
<li> MMX routine incompatibility with new gcc compiler versions </li>
<li> Other miscellaneous bug fixes </li>
</ul>
<p><strong>1.2.1: </strong> </p>
<ul>
<li> Added automake/autoconf scripts for GNU platforms (in courtesy
of David Durham) </li>
<li> Fixed SCALE overflow bug in rate transposer routine. </li>
<li> Fixed 64bit address space bugs. </li>
<li> Created a 'soundtouch' namespace for SAMPLETYPE definitions.</li>
</ul>
<p><strong>1.2.0: </strong> </p>
<ul>
<li> Added support for 32bit floating point sample data type with
SSE/3DNow! optimizations for Win32 platform (SSE/3DNow! optimizations
currently not supported in GCC environment) </li>
<li> Replaced 'make-gcc' script for GNU environment by master
Makefile </li>
<li> Added time-stretch routine configurability to SoundTouch main
class </li>
<li> Bugfixes</li>
</ul>
<p><strong>1.1.1: </strong> </p>
<ul>
<li> Moved SoundTouch under lesser GPL license (LGPL). This allows
using SoundTouch library in programs that aren't released under GPL
license. </li>
<li> Changed MMX routine organiation so that MMX optimized routines
are now implemented in classes that are derived from the basic classes
having the standard non-mmx routines. </li>
<li> MMX routines to support gcc version 3. </li>
<li> Replaced windows makefiles by script using the .dsw files </li>
</ul>
<p><strong>1.0.1: </strong> </p>
<ul>
<li> "mmx_gcc.cpp": Added "using namespace std" and removed "return
0" from a function with void return value to fix compiler errors when
compiling the library in Solaris environment. </li>
<li> Moved file "FIFOSampleBuffer.h" to "include" directory to allow
accessing the FIFOSampleBuffer class from external files. </li>
</ul>
<p><strong>1.0: </strong> </p>
<ul>
<li> Initial release </li>
</ul>
<p>&nbsp;</p>
<h3>5.2. SoundStretch application Change History </h3>
<p><b>1.7.0:</b></p>
<ul>
<li>Bugfixes in Wavfile: exception string formatting, avoid getLengthMs() integer
precision overflow, support WAV files using 24/32bit sample format.</li>
</ul>
<p><b>1.5.0:</b></p>
<ul>
<li> Added "-speech" switch to activate algorithm parameters more
suitable for speech processing than the default parameters tuned for
music processing.</li>
</ul>
<p><strong>1.4.0:</strong></p>
<ul>
<li> Moved BPM detection routines from SoundStretch application into
SoundTouch library </li>
<li> Allow using standard input/output pipes as audio processing
input/output streams</li>
</ul>
<p><strong>1.3.0:</strong></p>
<ul>
<li> Simplified accessing WAV files with floating point sample
format. </li>
</ul>
<p><strong>1.2.1: </strong> </p>
<ul>
<li> Fixed 64bit address space bugs.</li>
</ul>
<p><strong>1.2.0: </strong> </p>
<ul>
<li> Added support for 32bit floating point sample data type </li>
<li> Restructured the BPM routines into separate library </li>
<li> Fixed big-endian conversion bugs in WAV file routines (hopefully
:)</li>
</ul>
<p><strong>1.1.1: </strong> </p>
<ul>
<li> Fixed bugs in WAV file reading &amp; added byte-order conversion
for big-endian processors. </li>
<li> Moved SoundStretch source code under 'example' directory to
highlight difference from SoundTouch stuff. </li>
<li> Replaced windows makefiles by script using the .dsw files </li>
<li> Output file name isn't required if output isn't desired (e.g. if
using the switch '-bpm' in plain format only) </li>
</ul>
<p><strong>1.1:</strong></p>
<ul>
<li> Fixed "Release" settings in Microsoft Visual C++ project file
(.dsp) </li>
<li> Added beats-per-minute (BPM) detection routine and command-line
switch "-bpm" </li>
</ul>
<p><strong>1.01: </strong> </p>
<ul>
<li> Initial release </li>
</ul>
<hr>
<h2>6. Acknowledgements </h2>
<p>Kudos for these people who have contributed to development or
submitted bugfixes since SoundTouch v1.3.1: </p>
<ul>
<li> Arthur A</li>
<li> Richard Ash</li>
<li> Stanislav Brabec</li>
<li> Christian Budde</li>
<li> Jacek Caban</li>
<li> Brian Cameron</li>
<li> Jason Champion</li>
<li> David Clark</li>
<li> Patrick Colis</li>
<li> Miquel Colon</li>
<li> Justin Frankel</li>
<li> Jason Garland</li>
<li> Takashi Iwai</li>
<li> Yuval Naveh</li>
<li> Paulo Pizarro</li>
<li> Blaise Potard</li>
<li> RJ Ryan</li>
<li> Patrick Colis </li>
<li> Miquel Colon </li>
<li> Sandro Cumerlato</li>
<li> Justin Frankel </li>
<li> Jason Garland </li>
<li> Takashi Iwai </li>
<li> Mathias M<>hl</li>
<li> Yuval Naveh </li>
<li> Paulo Pizarro </li>
<li> Blaise Potard</li>
<li> RJ Ryan </li>
<li> John Sheehy</li>
<li> Tim Shuttleworth</li>
<li> John Stumpo</li>
<li> Tim Shuttleworth</li>
<li> Katja Vetter</li>
</ul>
<p>Moral greetings to all other contributors and users also!</p>
<hr>
<h2>7. LICENSE </h2>
<p>SoundTouch audio processing library<br>
Copyright (c) Olli Parviainen</p>
<p>This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 2.1
as published by the Free Software Foundation.</p>
<p>This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
General Public License for more details.</p>
<p>You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>
<hr><!--
$Id: README.html 168 2012-12-28 20:55:19Z oparviai $
-->
<p>
<i>RREADME.html file updated on 28-Dec-2012</i></p>
</body>

626
3rdparty/SoundTouch/RateTransposer.cpp vendored Normal file
View File

@@ -0,0 +1,626 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Sample rate transposer. Changes sample rate by using linear interpolation
/// together with anti-alias filtering (first order interpolation with anti-
/// alias filtering should be quite adequate for this application)
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
// File revision : $Revision: 4 $
//
// $Id: RateTransposer.cpp 131 2011-09-02 18:56:11Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <memory.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "RateTransposer.h"
#include "AAFilter.h"
using namespace soundtouch;
/// A linear samplerate transposer class that uses integer arithmetics.
/// for the transposing.
class RateTransposerInteger : public RateTransposer
{
protected:
int iSlopeCount;
int iRate;
SAMPLETYPE sPrevSampleL, sPrevSampleR;
virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
public:
RateTransposerInteger();
virtual ~RateTransposerInteger();
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// rate, larger faster rates.
virtual void setRate(float newRate);
};
/// A linear samplerate transposer class that uses floating point arithmetics
/// for the transposing.
class RateTransposerFloat : public RateTransposer
{
protected:
float fSlopeCount;
SAMPLETYPE sPrevSampleL, sPrevSampleR;
virtual void resetRegisters();
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
public:
RateTransposerFloat();
virtual ~RateTransposerFloat();
};
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
void * RateTransposer::operator new(size_t s)
{
ST_THROW_RT_ERROR("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
return newInstance();
}
RateTransposer *RateTransposer::newInstance()
{
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
return ::new RateTransposerInteger;
#else
return ::new RateTransposerFloat;
#endif
}
// Constructor
RateTransposer::RateTransposer() : FIFOProcessor(&outputBuffer)
{
numChannels = 2;
bUseAAFilter = TRUE;
fRate = 0;
// Instantiates the anti-alias filter with default tap length
// of 32
pAAFilter = new AAFilter(32);
}
RateTransposer::~RateTransposer()
{
delete pAAFilter;
}
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
void RateTransposer::enableAAFilter(BOOL newMode)
{
bUseAAFilter = newMode;
}
/// Returns nonzero if anti-alias filter is enabled.
BOOL RateTransposer::isAAFilterEnabled() const
{
return bUseAAFilter;
}
AAFilter *RateTransposer::getAAFilter()
{
return pAAFilter;
}
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposer::setRate(float newRate)
{
double fCutoff;
fRate = newRate;
// design a new anti-alias filter
if (newRate > 1.0f)
{
fCutoff = 0.5f / newRate;
}
else
{
fCutoff = 0.5f * newRate;
}
pAAFilter->setCutoffFreq(fCutoff);
}
// Outputs as many samples of the 'outputBuffer' as possible, and if there's
// any room left, outputs also as many of the incoming samples as possible.
// The goal is to drive the outputBuffer empty.
//
// It's allowed for 'output' and 'input' parameters to point to the same
// memory position.
/*
void RateTransposer::flushStoreBuffer()
{
if (storeBuffer.isEmpty()) return;
outputBuffer.moveSamples(storeBuffer);
}
*/
// Adds 'nSamples' pcs of samples from the 'samples' memory position into
// the input of the object.
void RateTransposer::putSamples(const SAMPLETYPE *samples, uint nSamples)
{
processSamples(samples, nSamples);
}
// Transposes up the sample rate, causing the observed playback 'rate' of the
// sound to decrease
void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
{
uint count, sizeTemp, num;
// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
// the samples and then apply the anti-alias filter to remove aliasing.
// First check that there's enough room in 'storeBuffer'
// (+16 is to reserve some slack in the destination buffer)
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
// Transpose the samples, store the result into the end of "storeBuffer"
count = transpose(storeBuffer.ptrEnd(sizeTemp), src, nSamples);
storeBuffer.putSamples(count);
// Apply the anti-alias filter to samples in "store output", output the
// result to "dest"
num = storeBuffer.numSamples();
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
storeBuffer.ptrBegin(), num, (uint)numChannels);
outputBuffer.putSamples(count);
// Remove the processed samples from "storeBuffer"
storeBuffer.receiveSamples(count);
}
// Transposes down the sample rate, causing the observed playback 'rate' of the
// sound to increase
void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
{
uint count, sizeTemp;
// If the parameter 'uRate' value is larger than 'SCALE', first apply the
// anti-alias filter to remove high frequencies (prevent them from folding
// over the lover frequencies), then transpose.
// Add the new samples to the end of the storeBuffer
storeBuffer.putSamples(src, nSamples);
// Anti-alias filter the samples to prevent folding and output the filtered
// data to tempBuffer. Note : because of the FIR filter length, the
// filtering routine takes in 'filter_length' more samples than it outputs.
assert(tempBuffer.isEmpty());
sizeTemp = storeBuffer.numSamples();
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
if (count == 0) return;
// Remove the filtered samples from 'storeBuffer'
storeBuffer.receiveSamples(count);
// Transpose the samples (+16 is to reserve some slack in the destination buffer)
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
count = transpose(outputBuffer.ptrEnd(sizeTemp), tempBuffer.ptrBegin(), count);
outputBuffer.putSamples(count);
}
// Transposes sample rate by applying anti-alias filter to prevent folding.
// Returns amount of samples returned in the "dest" buffer.
// The maximum amount of samples that can be returned at a time is set by
// the 'set_returnBuffer_size' function.
void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
{
uint count;
uint sizeReq;
if (nSamples == 0) return;
assert(pAAFilter);
// If anti-alias filter is turned off, simply transpose without applying
// the filter
if (bUseAAFilter == FALSE)
{
sizeReq = (uint)((float)nSamples / fRate + 1.0f);
count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
outputBuffer.putSamples(count);
return;
}
// Transpose with anti-alias filter
if (fRate < 1.0f)
{
upsample(src, nSamples);
}
else
{
downsample(src, 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)
{
if (numChannels == 2)
{
return transposeStereo(dest, src, nSamples);
}
else
{
return transposeMono(dest, src, nSamples);
}
}
// Sets the number of channels, 1 = mono, 2 = stereo
void RateTransposer::setChannels(int nChannels)
{
assert(nChannels > 0);
if (numChannels == nChannels) return;
assert(nChannels == 1 || nChannels == 2);
numChannels = nChannels;
storeBuffer.setChannels(numChannels);
tempBuffer.setChannels(numChannels);
outputBuffer.setChannels(numChannels);
// Inits the linear interpolation registers
resetRegisters();
}
// Clears all the samples in the object
void RateTransposer::clear()
{
outputBuffer.clear();
storeBuffer.clear();
}
// Returns nonzero if there aren't any samples available for outputting.
int RateTransposer::isEmpty() const
{
int res;
res = FIFOProcessor::isEmpty();
if (res == 0) return 0;
return storeBuffer.isEmpty();
}
//////////////////////////////////////////////////////////////////////////////
//
// RateTransposerInteger - integer arithmetic implementation
//
/// fixed-point interpolation routine precision
#define SCALE 65536
// Constructor
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.
RateTransposerInteger::resetRegisters();
RateTransposerInteger::setRate(1.0f);
}
RateTransposerInteger::~RateTransposerInteger()
{
}
void RateTransposerInteger::resetRegisters()
{
iSlopeCount = 0;
sPrevSampleL =
sPrevSampleR = 0;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int i, used;
LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work
used = 0;
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];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
}
// now always (iSlopeCount > SCALE)
iSlopeCount -= SCALE;
while (1)
{
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
used ++;
if (used >= nSamples - 1) goto end;
}
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = src[used] * vol1 + iSlopeCount * src[used + 1];
dest[i] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[nSamples - 1];
return i;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Stereo' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int srcPos, i, used;
LONG_SAMPLETYPE temp, vol1;
if (nSamples == 0) return 0; // no samples, no work
used = 0;
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];
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
temp = vol1 * sPrevSampleR + iSlopeCount * src[1];
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
}
// now always (iSlopeCount > SCALE)
iSlopeCount -= SCALE;
while (1)
{
while (iSlopeCount > SCALE)
{
iSlopeCount -= SCALE;
used ++;
if (used >= nSamples - 1) goto end;
}
srcPos = 2 * used;
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
temp = src[srcPos] * vol1 + iSlopeCount * src[srcPos + 2];
dest[2 * i] = (SAMPLETYPE)(temp / SCALE);
temp = src[srcPos + 1] * vol1 + iSlopeCount * src[srcPos + 3];
dest[2 * i + 1] = (SAMPLETYPE)(temp / SCALE);
i++;
iSlopeCount += iRate;
}
end:
// Store the last sample for the next round
sPrevSampleL = src[2 * nSamples - 2];
sPrevSampleR = src[2 * nSamples - 1];
return i;
}
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
// iRate, larger faster iRates.
void RateTransposerInteger::setRate(float newRate)
{
iRate = (int)(newRate * SCALE + 0.5f);
RateTransposer::setRate(newRate);
}
//////////////////////////////////////////////////////////////////////////////
//
// RateTransposerFloat - floating point arithmetic implementation
//
//////////////////////////////////////////////////////////////////////////////
// Constructor
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.
RateTransposerFloat::resetRegisters();
RateTransposerFloat::setRate(1.0f);
}
RateTransposerFloat::~RateTransposerFloat()
{
}
void RateTransposerFloat::resetRegisters()
{
fSlopeCount = 0;
sPrevSampleL =
sPrevSampleR = 0;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int i, used;
used = 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]);
i++;
fSlopeCount += fRate;
}
fSlopeCount -= 1.0f;
if (nSamples > 1)
{
while (1)
{
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= nSamples - 1) goto end;
}
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[used] + fSlopeCount * src[used + 1]);
i++;
fSlopeCount += fRate;
}
}
end:
// Store the last sample for the next round
sPrevSampleL = src[nSamples - 1];
return i;
}
// Transposes the sample rate of the given samples using linear interpolation.
// 'Mono' version of the routine. Returns the number of samples returned in
// the "dest" buffer
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
{
unsigned int srcPos, i, used;
if (nSamples == 0) return 0; // no samples, no work
used = 0;
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]);
i++;
fSlopeCount += fRate;
}
// now always (iSlopeCount > 1.0f)
fSlopeCount -= 1.0f;
if (nSamples > 1)
{
while (1)
{
while (fSlopeCount > 1.0f)
{
fSlopeCount -= 1.0f;
used ++;
if (used >= nSamples - 1) 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]);
i++;
fSlopeCount += fRate;
}
}
end:
// Store the last sample for the next round
sPrevSampleL = src[2 * nSamples - 2];
sPrevSampleR = src[2 * nSamples - 1];
return i;
}

159
3rdparty/SoundTouch/RateTransposer.h vendored Normal file
View File

@@ -0,0 +1,159 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Sample rate transposer. Changes sample rate by using linear interpolation
/// together with anti-alias filtering (first order interpolation with anti-
/// alias filtering should be quite adequate for this application).
///
/// Use either of the derived classes of 'RateTransposerInteger' or
/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
/// algorithm implementation.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2009-02-21 13:00:14 -0300 (sáb, 21 fev 2009) $
// File revision : $Revision: 4 $
//
// $Id: RateTransposer.h 63 2009-02-21 16:00:14Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef RateTransposer_H
#define RateTransposer_H
#include <stddef.h>
#include "AAFilter.h"
#include "FIFOSamplePipe.h"
#include "FIFOSampleBuffer.h"
#include "STTypes.h"
namespace soundtouch
{
/// A common linear samplerate transposer class.
///
/// Note: Use function "RateTransposer::newInstance()" to create a new class
/// instance instead of the "new" operator; that function automatically
/// chooses a correct implementation depending on if integer or floating
/// arithmetics are to be used.
class RateTransposer : public FIFOProcessor
{
protected:
/// Anti-alias filter object
AAFilter *pAAFilter;
float fRate;
int numChannels;
/// Buffer for collecting samples to feed the anti-alias filter between
/// two batches
FIFOSampleBuffer storeBuffer;
/// Buffer for keeping samples between transposing & anti-alias filter
FIFOSampleBuffer tempBuffer;
/// Output sample buffer
FIFOSampleBuffer outputBuffer;
BOOL bUseAAFilter;
virtual void resetRegisters() = 0;
virtual uint transposeStereo(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) = 0;
virtual uint transposeMono(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples) = 0;
inline uint transpose(SAMPLETYPE *dest,
const SAMPLETYPE *src,
uint numSamples);
void downsample(const SAMPLETYPE *src,
uint numSamples);
void upsample(const SAMPLETYPE *src,
uint numSamples);
/// Transposes sample rate by applying anti-alias filter to prevent folding.
/// Returns amount of samples returned in the "dest" buffer.
/// The maximum amount of samples that can be returned at a time is set by
/// the 'set_returnBuffer_size' function.
void processSamples(const SAMPLETYPE *src,
uint numSamples);
public:
RateTransposer();
virtual ~RateTransposer();
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
/// depending on if we're to use integer or floating point arithmetics.
static void *operator new(size_t s);
/// Use this function instead of "new" operator to create a new instance of this class.
/// This function automatically chooses a correct implementation, depending on if
/// integer ot floating point arithmetics are to be used.
static RateTransposer *newInstance();
/// Returns the output buffer object
FIFOSamplePipe *getOutput() { return &outputBuffer; };
/// Returns the store buffer object
FIFOSamplePipe *getStore() { return &storeBuffer; };
/// Return anti-alias filter object
AAFilter *getAAFilter();
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
void enableAAFilter(BOOL newMode);
/// Returns nonzero if anti-alias filter is enabled.
BOOL isAAFilterEnabled() const;
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
/// rate, larger faster rates.
virtual void setRate(float newRate);
/// Sets the number of channels, 1 = mono, 2 = stereo
void setChannels(int channels);
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
/// the input of the object.
void putSamples(const SAMPLETYPE *samples, uint numSamples);
/// Clears all the samples in the object
void clear();
/// Returns nonzero if there aren't any samples available for outputting.
int isEmpty() const;
};
}
#endif

View File

@@ -8,6 +8,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-12-28 12:53:56 -0200 (sex, 28 dez 2012) $
// File revision : $Revision: 3 $
//
// $Id: STTypes.h 162 2012-12-28 14:53:56Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -53,25 +60,25 @@ typedef unsigned long ulong;
#include "soundtouch_config.h"
#endif
#ifndef _WINDEF_
// if these aren't defined already by Windows headers, define now
typedef int BOOL;
#define FALSE 0
#define TRUE 1
#endif // _WINDEF_
namespace soundtouch
{
/// Max allowed number of channels
#define SOUNDTOUCH_MAX_CHANNELS 16
/// Activate these undef's to overrule the possible sampletype
/// setting inherited from some other header file:
//#undef SOUNDTOUCH_INTEGER_SAMPLES
//#undef SOUNDTOUCH_FLOAT_SAMPLES
/// 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__) && defined(ANDROID))
#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
#undef SOUNDTOUCH_FLOAT_SAMPLES
@@ -139,10 +146,8 @@ namespace soundtouch
#endif // SOUNDTOUCH_FLOAT_SAMPLES
#ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
// Allow MMX optimizations (not available in X64 mode)
#if (!_M_X64)
#define SOUNDTOUCH_ALLOW_MMX 1
#endif
// Allow MMX optimizations
#define SOUNDTOUCH_ALLOW_MMX 1
#endif
#else
@@ -170,7 +175,6 @@ namespace soundtouch
#else
// use c++ standard exceptions
#include <stdexcept>
#include <string>
#define ST_THROW_RT_ERROR(x) {throw std::runtime_error(x);}
#endif

86
3rdparty/SoundTouch/SoundTouch.cbp vendored Normal file
View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="SoundTouch" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="../../deps/debug/libsoundtouch-dbg" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/debug" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-g" />
<Add option="-O0" />
</Compiler>
</Target>
<Target title="Devel">
<Option output="../../deps/devel/libsoundtouch-dev" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/devel" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-O1" />
<Add option="-W" />
<Add option="-g" />
<Add option="-DNDEBUG" />
</Compiler>
</Target>
<Target title="Release">
<Option output="../../deps/libsoundtouch" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/release" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
<Add option="-W" />
<Add option="-DNDEBUG" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-march=athlon-xp" />
<Add option="-march=prescott" />
</Compiler>
<Unit filename="AAFilter.cpp" />
<Unit filename="AAFilter.h" />
<Unit filename="BPMDetect.h" />
<Unit filename="FIFOSampleBuffer.cpp" />
<Unit filename="FIFOSampleBuffer.h" />
<Unit filename="FIFOSamplePipe.h" />
<Unit filename="FIRFilter.cpp" />
<Unit filename="FIRFilter.h" />
<Unit filename="RateTransposer.cpp" />
<Unit filename="RateTransposer.h" />
<Unit filename="STTypes.h" />
<Unit filename="SoundTouch.cpp" />
<Unit filename="SoundTouch.h" />
<Unit filename="TDStretch.cpp" />
<Unit filename="TDStretch.h" />
<Unit filename="WavFile.cpp" />
<Unit filename="WavFile.h" />
<Unit filename="cpu_detect.h" />
<Unit filename="cpu_detect_x86_gcc.cpp" />
<Unit filename="mmx_optimized.cpp" />
<Unit filename="soundtouch_config.h" />
<Unit filename="sse_optimized.cpp" />
<Extensions>
<envvars />
<code_completion />
<lib_finder disable_auto="1" />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

501
3rdparty/SoundTouch/SoundTouch.cpp vendored Normal file
View File

@@ -0,0 +1,501 @@
//////////////////////////////////////////////////////////////////////////////
///
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
///
/// Notes:
/// - Initialize the SoundTouch object instance by setting up the sound stream
/// parameters with functions 'setSampleRate' and 'setChannels', then set
/// desired tempo/pitch/rate settings with the corresponding functions.
///
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
/// samples that are to be processed are fed into one of the pipe by calling
/// function 'putSamples', while the ready processed samples can be read
/// from the other end of the pipeline with function 'receiveSamples'.
///
/// - The SoundTouch processing classes require certain sized 'batches' of
/// samples in order to process the sound. For this reason the classes buffer
/// incoming samples until there are enough of samples available for
/// processing, then they carry out the processing step and consequently
/// make the processed samples available for outputting.
///
/// - For the above reason, the processing routines introduce a certain
/// 'latency' between the input and output, so that the samples input to
/// SoundTouch may not be immediately available in the output, and neither
/// the amount of outputtable samples may not immediately be in direct
/// relationship with the amount of previously input samples.
///
/// - The tempo/pitch/rate control parameters can be altered during processing.
/// Please notice though that they aren't currently protected by semaphores,
/// so in multi-thread application external semaphore protection may be
/// required.
///
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
/// tempo and pitch in the same ratio) of the sound. The third available control
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
/// combining the two other controls.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
// File revision : $Revision: 4 $
//
// $Id: SoundTouch.cpp 143 2012-06-13 19:29:53Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <assert.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <stdio.h>
#include "SoundTouch.h"
#include "TDStretch.h"
#include "RateTransposer.h"
#include "cpu_detect.h"
using namespace soundtouch;
/// test if two floating point numbers are equal
#define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10)
/// Print library version string for autoconf
extern "C" void soundtouch_ac_test()
{
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
}
SoundTouch::SoundTouch()
{
// Initialize rate transposer and tempo changer instances
pRateTransposer = RateTransposer::newInstance();
pTDStretch = TDStretch::newInstance();
setOutPipe(pTDStretch);
rate = tempo = 0;
virtualPitch =
virtualRate =
virtualTempo = 1.0;
calcEffectiveRateAndTempo();
channels = 0;
bSrateSet = FALSE;
}
SoundTouch::~SoundTouch()
{
delete pRateTransposer;
delete pTDStretch;
}
/// Get SoundTouch library version string
const char *SoundTouch::getVersionString()
{
static const char *_version = SOUNDTOUCH_VERSION;
return _version;
}
/// Get SoundTouch library version Id
uint SoundTouch::getVersionId()
{
return SOUNDTOUCH_VERSION_ID;
}
// Sets the number of channels, 1 = mono, 2 = stereo
void SoundTouch::setChannels(uint numChannels)
{
if (numChannels != 1 && numChannels != 2)
{
ST_THROW_RT_ERROR("Illegal number of channels");
}
channels = numChannels;
pRateTransposer->setChannels((int)numChannels);
pTDStretch->setChannels((int)numChannels);
}
// Sets new rate control value. Normal rate = 1.0, smaller values
// represent slower rate, larger faster rates.
void SoundTouch::setRate(float newRate)
{
virtualRate = newRate;
calcEffectiveRateAndTempo();
}
// Sets new rate control value as a difference in percents compared
// to the original rate (-50 .. +100 %)
void SoundTouch::setRateChange(float newRate)
{
virtualRate = 1.0f + 0.01f * newRate;
calcEffectiveRateAndTempo();
}
// Sets new tempo control value. Normal tempo = 1.0, smaller values
// represent slower tempo, larger faster tempo.
void SoundTouch::setTempo(float newTempo)
{
virtualTempo = newTempo;
calcEffectiveRateAndTempo();
}
// Sets new tempo control value as a difference in percents compared
// to the original tempo (-50 .. +100 %)
void SoundTouch::setTempoChange(float newTempo)
{
virtualTempo = 1.0f + 0.01f * newTempo;
calcEffectiveRateAndTempo();
}
// Sets new pitch control value. Original pitch = 1.0, smaller values
// represent lower pitches, larger values higher pitch.
void SoundTouch::setPitch(float newPitch)
{
virtualPitch = newPitch;
calcEffectiveRateAndTempo();
}
// Sets pitch change in octaves compared to the original pitch
// (-1.00 .. +1.00)
void SoundTouch::setPitchOctaves(float newPitch)
{
virtualPitch = (float)exp(0.69314718056f * newPitch);
calcEffectiveRateAndTempo();
}
// Sets pitch change in semi-tones compared to the original pitch
// (-12 .. +12)
void SoundTouch::setPitchSemiTones(int newPitch)
{
setPitchOctaves((float)newPitch / 12.0f);
}
void SoundTouch::setPitchSemiTones(float newPitch)
{
setPitchOctaves(newPitch / 12.0f);
}
// Calculates 'effective' rate and tempo values from the
// nominal control values.
void SoundTouch::calcEffectiveRateAndTempo()
{
float oldTempo = tempo;
float oldRate = rate;
tempo = virtualTempo / virtualPitch;
rate = virtualPitch * virtualRate;
if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
if (rate <= 1.0f)
{
if (output != pTDStretch)
{
FIFOSamplePipe *tempoOut;
assert(output == pRateTransposer);
// move samples in the current output buffer to the output of pTDStretch
tempoOut = pTDStretch->getOutput();
tempoOut->moveSamples(*output);
// move samples in pitch transposer's store buffer to tempo changer's input
pTDStretch->moveSamples(*pRateTransposer->getStore());
output = pTDStretch;
}
}
else
#endif
{
if (output != pRateTransposer)
{
FIFOSamplePipe *transOut;
assert(output == pTDStretch);
// move samples in the current output buffer to the output of pRateTransposer
transOut = pRateTransposer->getOutput();
transOut->moveSamples(*output);
// move samples in tempo changer's input to pitch transposer's input
pRateTransposer->moveSamples(*pTDStretch->getInput());
output = pRateTransposer;
}
}
}
// Sets sample rate.
void SoundTouch::setSampleRate(uint srate)
{
bSrateSet = TRUE;
// set sample rate, leave other tempo changer parameters as they are.
pTDStretch->setParameters((int)srate);
}
// Adds 'numSamples' pcs of samples from the 'samples' memory position into
// the input of the object.
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
{
if (bSrateSet == FALSE)
{
ST_THROW_RT_ERROR("SoundTouch : Sample rate not defined");
}
else if (channels == 0)
{
ST_THROW_RT_ERROR("SoundTouch : Number of channels not defined");
}
// Transpose the rate of the new samples if necessary
/* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
if (rate == 1.0f)
{
// The rate value is same as the original, simply evaluate the tempo changer.
assert(output == pTDStretch);
if (pRateTransposer->isEmpty() == 0)
{
// yet flush the last samples in the pitch transposer buffer
// (may happen if 'rate' changes from a non-zero value to zero)
pTDStretch->moveSamples(*pRateTransposer);
}
pTDStretch->putSamples(samples, nSamples);
}
*/
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
else if (rate <= 1.0f)
{
// transpose the rate down, output the transposed sound to tempo changer buffer
assert(output == pTDStretch);
pRateTransposer->putSamples(samples, nSamples);
pTDStretch->moveSamples(*pRateTransposer);
}
else
#endif
{
// evaluate the tempo changer, then transpose the rate up,
assert(output == pRateTransposer);
pTDStretch->putSamples(samples, nSamples);
pRateTransposer->moveSamples(*pTDStretch);
}
}
// Flushes the last samples from the processing pipeline to the output.
// Clears also the internal processing buffers.
//
// Note: This function is meant for extracting the last samples of a sound
// stream. This function may introduce additional blank samples in the end
// of the sound stream, and thus it's not recommended to call this function
// in the middle of a sound stream.
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
// check how many samples still await processing, and scale
// that by tempo & rate to get expected output sample count
nUnprocessed = numUnprocessedSamples();
nUnprocessed = (int)((double)nUnprocessed / (tempo * rate) + 0.5);
nOut = numSamples(); // ready samples currently in buffer ...
nOut += nUnprocessed; // ... and how many we expect there to be in the end
memset(buff, 0, 64 * channels * sizeof(SAMPLETYPE));
// "Push" the last active samples out from the processing pipeline by
// feeding blank samples into the processing pipeline until new,
// processed samples appear in the output (not however, more than
// 8ksamples in any case)
for (i = 0; i < 128; i ++)
{
putSamples(buff, 64);
if ((int)numSamples() >= nOut)
{
// Enough new samples have appeared into the output!
// As samples come from processing with bigger chunks, now truncate it
// back to maximum "nOut" samples to improve duration accuracy
adjustAmountOfSamples(nOut);
// finish
break;
}
}
// Clear working buffers
pRateTransposer->clear();
pTDStretch->clearInput();
// yet leave the 'tempoChanger' output intouched as that's where the
// flushed samples are!
}
// Changes a setting controlling the processing system behaviour. See the
// 'SETTING_...' defines for available setting ID's.
BOOL SoundTouch::setSetting(int settingId, int value)
{
int sampleRate, sequenceMs, seekWindowMs, overlapMs;
// read current tdstretch routine parameters
pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
switch (settingId)
{
case SETTING_USE_AA_FILTER :
// enables / disabless anti-alias filter
pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
return TRUE;
case SETTING_AA_FILTER_LENGTH :
// sets anti-alias filter length
pRateTransposer->getAAFilter()->setLength(value);
return TRUE;
case SETTING_USE_QUICKSEEK :
// enables / disables tempo routine quick seeking algorithm
pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE);
return TRUE;
case SETTING_SEQUENCE_MS:
// change time-stretch sequence duration parameter
pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs);
return TRUE;
case SETTING_SEEKWINDOW_MS:
// change time-stretch seek window length parameter
pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
return TRUE;
case SETTING_OVERLAP_MS:
// change time-stretch overlap length parameter
pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
return TRUE;
default :
return FALSE;
}
}
// Reads a setting controlling the processing system behaviour. See the
// 'SETTING_...' defines for available setting ID's.
//
// Returns the setting value.
int SoundTouch::getSetting(int settingId) const
{
int temp;
switch (settingId)
{
case SETTING_USE_AA_FILTER :
return (uint)pRateTransposer->isAAFilterEnabled();
case SETTING_AA_FILTER_LENGTH :
return pRateTransposer->getAAFilter()->getLength();
case SETTING_USE_QUICKSEEK :
return (uint) pTDStretch->isQuickSeekEnabled();
case SETTING_SEQUENCE_MS:
pTDStretch->getParameters(NULL, &temp, NULL, NULL);
return temp;
case SETTING_SEEKWINDOW_MS:
pTDStretch->getParameters(NULL, NULL, &temp, NULL);
return temp;
case SETTING_OVERLAP_MS:
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
return temp;
case SETTING_NOMINAL_INPUT_SEQUENCE :
return pTDStretch->getInputSampleReq();
case SETTING_NOMINAL_OUTPUT_SEQUENCE :
return pTDStretch->getOutputBatchSize();
default :
return 0;
}
}
// Clears all the samples in the object's output and internal processing
// buffers.
void SoundTouch::clear()
{
pRateTransposer->clear();
pTDStretch->clear();
}
/// Returns number of samples currently unprocessed.
uint SoundTouch::numUnprocessedSamples() const
{
FIFOSamplePipe * psp;
if (pTDStretch)
{
psp = pTDStretch->getInput();
if (psp)
{
return psp->numSamples();
}
}
return 0;
}

277
3rdparty/SoundTouch/SoundTouch.h vendored Normal file
View File

@@ -0,0 +1,277 @@
//////////////////////////////////////////////////////////////////////////////
///
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
///
/// Notes:
/// - Initialize the SoundTouch object instance by setting up the sound stream
/// parameters with functions 'setSampleRate' and 'setChannels', then set
/// desired tempo/pitch/rate settings with the corresponding functions.
///
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
/// samples that are to be processed are fed into one of the pipe by calling
/// function 'putSamples', while the ready processed samples can be read
/// from the other end of the pipeline with function 'receiveSamples'.
///
/// - The SoundTouch processing classes require certain sized 'batches' of
/// samples in order to process the sound. For this reason the classes buffer
/// incoming samples until there are enough of samples available for
/// processing, then they carry out the processing step and consequently
/// make the processed samples available for outputting.
///
/// - For the above reason, the processing routines introduce a certain
/// 'latency' between the input and output, so that the samples input to
/// SoundTouch may not be immediately available in the output, and neither
/// the amount of outputtable samples may not immediately be in direct
/// relationship with the amount of previously input samples.
///
/// - The tempo/pitch/rate control parameters can be altered during processing.
/// Please notice though that they aren't currently protected by semaphores,
/// so in multi-thread application external semaphore protection may be
/// required.
///
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
/// tempo and pitch in the same ratio) of the sound. The third available control
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
/// combining the two other controls.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-12-28 17:32:59 -0200 (sex, 28 dez 2012) $
// File revision : $Revision: 4 $
//
// $Id: SoundTouch.h 163 2012-12-28 19:32:59Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef SoundTouch_H
#define SoundTouch_H
#include "FIFOSamplePipe.h"
#include "STTypes.h"
namespace soundtouch
{
/// Soundtouch library version string
#define SOUNDTOUCH_VERSION "1.7.1"
/// SoundTouch library version id
#define SOUNDTOUCH_VERSION_ID (10701)
//
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
/// Enable/disable anti-alias filter in pitch transposer (0 = disable)
#define SETTING_USE_AA_FILTER 0
/// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
#define SETTING_AA_FILTER_LENGTH 1
/// Enable/disable quick seeking algorithm in tempo changer routine
/// (enabling quick seeking lowers CPU utilization but causes a minor sound
/// quality compromising)
#define SETTING_USE_QUICKSEEK 2
/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
/// to how long sequences the original sound is chopped in the time-stretch algorithm.
/// See "STTypes.h" or README for more information.
#define SETTING_SEQUENCE_MS 3
/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
/// best possible overlapping location. This determines from how wide window the algorithm
/// may look for an optimal joining location when mixing the sound sequences back together.
/// See "STTypes.h" or README for more information.
#define SETTING_SEEKWINDOW_MS 4
/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
/// are mixed back together, to form a continuous sound stream, this parameter defines over
/// how long period the two consecutive sequences are let to overlap each other.
/// See "STTypes.h" or README for more information.
#define SETTING_OVERLAP_MS 5
/// Call "getSetting" with this ID to query nominal average processing sequence
/// size in samples. This value tells approcimate value how many input samples
/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
///
/// Notices:
/// - This is read-only parameter, i.e. setSetting ignores this parameter
/// - Returned value is approximate average value, exact processing batch
/// size may wary from time to time
/// - This parameter value is not constant but may change depending on
/// tempo/pitch/rate/samplerate settings.
#define SETTING_NOMINAL_INPUT_SEQUENCE 6
/// Call "getSetting" with this ID to query nominal average processing output
/// size in samples. This value tells approcimate value how many output samples
/// SoundTouch outputs once it does DSP processing run for a batch of input samples.
///
/// Notices:
/// - This is read-only parameter, i.e. setSetting ignores this parameter
/// - Returned value is approximate average value, exact processing batch
/// size may wary from time to time
/// - This parameter value is not constant but may change depending on
/// tempo/pitch/rate/samplerate settings.
#define SETTING_NOMINAL_OUTPUT_SEQUENCE 7
class SoundTouch : public FIFOProcessor
{
private:
/// Rate transposer class instance
class RateTransposer *pRateTransposer;
/// Time-stretch class instance
class TDStretch *pTDStretch;
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
float virtualRate;
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
float virtualTempo;
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
float virtualPitch;
/// Flag: Has sample rate been set?
BOOL bSrateSet;
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
/// 'virtualPitch' parameters.
void calcEffectiveRateAndTempo();
protected :
/// Number of channels
uint channels;
/// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
float rate;
/// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
float tempo;
public:
SoundTouch();
virtual ~SoundTouch();
/// Get SoundTouch library version string
static const char *getVersionString();
/// Get SoundTouch library version Id
static uint getVersionId();
/// Sets new rate control value. Normal rate = 1.0, smaller values
/// represent slower rate, larger faster rates.
void setRate(float newRate);
/// Sets new tempo control value. Normal tempo = 1.0, smaller values
/// represent slower tempo, larger faster tempo.
void setTempo(float newTempo);
/// Sets new rate control value as a difference in percents compared
/// to the original rate (-50 .. +100 %)
void setRateChange(float newRate);
/// Sets new tempo control value as a difference in percents compared
/// to the original tempo (-50 .. +100 %)
void setTempoChange(float newTempo);
/// Sets new pitch control value. Original pitch = 1.0, smaller values
/// represent lower pitches, larger values higher pitch.
void setPitch(float newPitch);
/// Sets pitch change in octaves compared to the original pitch
/// (-1.00 .. +1.00)
void setPitchOctaves(float newPitch);
/// Sets pitch change in semi-tones compared to the original pitch
/// (-12 .. +12)
void setPitchSemiTones(int newPitch);
void setPitchSemiTones(float newPitch);
/// Sets the number of channels, 1 = mono, 2 = stereo
void setChannels(uint numChannels);
/// Sets sample rate.
void setSampleRate(uint srate);
/// Flushes the last samples from the processing pipeline to the output.
/// Clears also the internal processing buffers.
//
/// Note: This function is meant for extracting the last samples of a sound
/// stream. This function may introduce additional blank samples in the end
/// of the sound stream, and thus it's not recommended to call this function
/// in the middle of a sound stream.
void flush();
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
/// the input of the object. Notice that sample rate _has_to_ be set before
/// calling this function, otherwise throws a runtime_error exception.
virtual void putSamples(
const SAMPLETYPE *samples, ///< Pointer to sample buffer.
uint numSamples ///< Number of samples in buffer. Notice
///< that in case of stereo-sound a single sample
///< contains data for both channels.
);
/// Clears all the samples in the object's output and internal processing
/// buffers.
virtual void clear();
/// Changes a setting controlling the processing system behaviour. See the
/// 'SETTING_...' defines for available setting ID's.
///
/// \return 'TRUE' if the setting was succesfully changed
BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines.
int value ///< New setting value.
);
/// Reads a setting controlling the processing system behaviour. See the
/// 'SETTING_...' defines for available setting ID's.
///
/// \return the setting value.
int getSetting(int settingId ///< Setting ID number, see SETTING_... defines.
) const;
/// Returns number of samples currently unprocessed.
virtual uint numUnprocessedSamples() const;
/// Other handy functions that are implemented in the ancestor classes (see
/// classes 'FIFOProcessor' and 'FIFOSamplePipe')
///
/// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
/// - numSamples() : Get number of 'ready' samples that can be received with
/// function 'receiveSamples()'
/// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
/// - clear() : Clears all samples from ready/processing buffers.
};
}
#endif

285
3rdparty/SoundTouch/SoundTouch.vcproj vendored Normal file
View File

@@ -0,0 +1,285 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="SoundTouch"
ProjectGUID="{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}"
RootNamespace="SoundTouch"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Devel|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\3dnow_win.cpp"
>
</File>
<File
RelativePath=".\AAFilter.cpp"
>
</File>
<File
RelativePath=".\cpu_detect_x86_win.cpp"
>
</File>
<File
RelativePath=".\FIFOSampleBuffer.cpp"
>
</File>
<File
RelativePath=".\FIRFilter.cpp"
>
</File>
<File
RelativePath=".\mmx_optimized.cpp"
>
</File>
<File
RelativePath=".\RateTransposer.cpp"
>
</File>
<File
RelativePath=".\SoundTouch.cpp"
>
</File>
<File
RelativePath=".\sse_optimized.cpp"
>
</File>
<File
RelativePath=".\TDStretch.cpp"
>
</File>
<File
RelativePath=".\WavFile.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\AAFilter.h"
>
</File>
<File
RelativePath=".\BPMDetect.h"
>
</File>
<File
RelativePath=".\cpu_detect.h"
>
</File>
<File
RelativePath=".\FIFOSampleBuffer.h"
>
</File>
<File
RelativePath=".\FIFOSamplePipe.h"
>
</File>
<File
RelativePath=".\FIRFilter.h"
>
</File>
<File
RelativePath=".\RateTransposer.h"
>
</File>
<File
RelativePath=".\SoundTouch.h"
>
</File>
<File
RelativePath=".\STTypes.h"
>
</File>
<File
RelativePath=".\TDStretch.h"
>
</File>
<File
RelativePath=".\WavFile.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

112
3rdparty/SoundTouch/SoundTouch.vcxproj vendored Normal file
View File

@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}</ProjectGuid>
<RootNamespace>SoundTouch</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp" />
<ClCompile Include="AAFilter.cpp" />
<ClCompile Include="cpu_detect_x86_win.cpp" />
<ClCompile Include="FIFOSampleBuffer.cpp" />
<ClCompile Include="FIRFilter.cpp" />
<ClCompile Include="mmx_optimized.cpp" />
<ClCompile Include="RateTransposer.cpp" />
<ClCompile Include="SoundTouch.cpp" />
<ClCompile Include="sse_optimized.cpp" />
<ClCompile Include="TDStretch.cpp" />
<ClCompile Include="WavFile.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h" />
<ClInclude Include="BPMDetect.h" />
<ClInclude Include="cpu_detect.h" />
<ClInclude Include="FIFOSampleBuffer.h" />
<ClInclude Include="FIFOSamplePipe.h" />
<ClInclude Include="FIRFilter.h" />
<ClInclude Include="RateTransposer.h" />
<ClInclude Include="SoundTouch.h" />
<ClInclude Include="STTypes.h" />
<ClInclude Include="TDStretch.h" />
<ClInclude Include="WavFile.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AAFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpu_detect_x86_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIFOSampleBuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIRFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mmx_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RateTransposer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundTouch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sse_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TDStretch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WavFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BPMDetect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu_detect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSampleBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSamplePipe.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIRFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RateTransposer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundTouch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="STTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TDStretch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WavFile.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}</ProjectGuid>
<RootNamespace>SoundTouch</RootNamespace>
<ProjectName>SoundTouch</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp" />
<ClCompile Include="AAFilter.cpp" />
<ClCompile Include="cpu_detect_x86_win.cpp" />
<ClCompile Include="FIFOSampleBuffer.cpp" />
<ClCompile Include="FIRFilter.cpp" />
<ClCompile Include="mmx_optimized.cpp" />
<ClCompile Include="RateTransposer.cpp" />
<ClCompile Include="SoundTouch.cpp" />
<ClCompile Include="sse_optimized.cpp" />
<ClCompile Include="TDStretch.cpp" />
<ClCompile Include="WavFile.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h" />
<ClInclude Include="BPMDetect.h" />
<ClInclude Include="cpu_detect.h" />
<ClInclude Include="FIFOSampleBuffer.h" />
<ClInclude Include="FIFOSamplePipe.h" />
<ClInclude Include="FIRFilter.h" />
<ClInclude Include="RateTransposer.h" />
<ClInclude Include="SoundTouch.h" />
<ClInclude Include="STTypes.h" />
<ClInclude Include="TDStretch.h" />
<ClInclude Include="WavFile.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AAFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpu_detect_x86_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIFOSampleBuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIRFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mmx_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RateTransposer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundTouch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sse_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TDStretch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WavFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BPMDetect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu_detect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSampleBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSamplePipe.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIRFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RateTransposer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundTouch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="STTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TDStretch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WavFile.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}</ProjectGuid>
<RootNamespace>SoundTouch</RootNamespace>
<ProjectName>SoundTouch</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp" />
<ClCompile Include="AAFilter.cpp" />
<ClCompile Include="cpu_detect_x86_win.cpp" />
<ClCompile Include="FIFOSampleBuffer.cpp" />
<ClCompile Include="FIRFilter.cpp" />
<ClCompile Include="mmx_optimized.cpp" />
<ClCompile Include="RateTransposer.cpp" />
<ClCompile Include="SoundTouch.cpp" />
<ClCompile Include="sse_optimized.cpp" />
<ClCompile Include="TDStretch.cpp" />
<ClCompile Include="WavFile.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h" />
<ClInclude Include="BPMDetect.h" />
<ClInclude Include="cpu_detect.h" />
<ClInclude Include="FIFOSampleBuffer.h" />
<ClInclude Include="FIFOSamplePipe.h" />
<ClInclude Include="FIRFilter.h" />
<ClInclude Include="RateTransposer.h" />
<ClInclude Include="SoundTouch.h" />
<ClInclude Include="STTypes.h" />
<ClInclude Include="TDStretch.h" />
<ClInclude Include="WavFile.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="3dnow_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AAFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cpu_detect_x86_win.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIFOSampleBuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FIRFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mmx_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RateTransposer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundTouch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sse_optimized.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TDStretch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WavFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AAFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BPMDetect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu_detect.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSampleBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIFOSamplePipe.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FIRFilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RateTransposer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundTouch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="STTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TDStretch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WavFile.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

808
3rdparty/SoundTouch/TDStretch.cpp vendored Normal file
View File

@@ -0,0 +1,808 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
/// while maintaining the original pitch by using a time domain WSOLA-like
/// method with several performance-increasing tweaks.
///
/// Note : MMX optimized functions reside in a separate, platform-specific
/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
// File revision : $Revision: 1.12 $
//
// $Id: TDStretch.cpp 160 2012-11-08 18:53:01Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include "STTypes.h"
#include "cpu_detect.h"
#include "TDStretch.h"
#include <stdio.h>
using namespace soundtouch;
#define max(x, y) (((x) > (y)) ? (x) : (y))
/*****************************************************************************
*
* Constant definitions
*
*****************************************************************************/
// Table for the hierarchical mixing position seeking algorithm
static const short _scanOffsets[5][24]={
{ 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806,
868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0},
{-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 121, 114, 97, 114, 98, 105, 108, 32, 104, 99, 117, 111,
116, 100, 110, 117, 111, 115, 0, 0, 0, 0, 0, 0}};
/*****************************************************************************
*
* Implementation of the class 'TDStretch'
*
*****************************************************************************/
TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
{
bQuickSeek = FALSE;
channels = 2;
pMidBuffer = NULL;
pMidBufferUnaligned = NULL;
overlapLength = 0;
bAutoSeqSetting = TRUE;
bAutoSeekSetting = TRUE;
// outDebt = 0;
skipFract = 0;
tempo = 1.0f;
setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
setTempo(1.0f);
clear();
}
TDStretch::~TDStretch()
{
delete[] pMidBufferUnaligned;
}
// Sets routine control parameters. These control are certain time constants
// defining how the sound is stretched to the desired duration.
//
// 'sampleRate' = sample rate of the sound
// 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
// 'seekwindowMS' = seeking window length for scanning the best overlapping
// position (default = 28 ms)
// 'overlapMS' = overlapping length (default = 12 ms)
void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
int aSeekWindowMS, int aOverlapMS)
{
// accept only positive parameter values - if zero or negative, use old values instead
if (aSampleRate > 0) this->sampleRate = aSampleRate;
if (aOverlapMS > 0) this->overlapMs = aOverlapMS;
if (aSequenceMS > 0)
{
this->sequenceMs = aSequenceMS;
bAutoSeqSetting = FALSE;
}
else if (aSequenceMS == 0)
{
// if zero, use automatic setting
bAutoSeqSetting = TRUE;
}
if (aSeekWindowMS > 0)
{
this->seekWindowMs = aSeekWindowMS;
bAutoSeekSetting = FALSE;
}
else if (aSeekWindowMS == 0)
{
// if zero, use automatic setting
bAutoSeekSetting = TRUE;
}
calcSeqParameters();
calculateOverlapLength(overlapMs);
// set tempo to recalculate 'sampleReq'
setTempo(tempo);
}
/// Get routine control parameters, see setParameters() function.
/// Any of the parameters to this function can be NULL, in such case corresponding parameter
/// value isn't returned.
void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWindowMs, int *pOverlapMs) const
{
if (pSampleRate)
{
*pSampleRate = sampleRate;
}
if (pSequenceMs)
{
*pSequenceMs = (bAutoSeqSetting) ? (USE_AUTO_SEQUENCE_LEN) : sequenceMs;
}
if (pSeekWindowMs)
{
*pSeekWindowMs = (bAutoSeekSetting) ? (USE_AUTO_SEEKWINDOW_LEN) : seekWindowMs;
}
if (pOverlapMs)
{
*pOverlapMs = overlapMs;
}
}
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
{
int i;
SAMPLETYPE m1, m2;
m1 = (SAMPLETYPE)0;
m2 = (SAMPLETYPE)overlapLength;
for (i = 0; i < overlapLength ; i ++)
{
pOutput[i] = (pInput[i] * m1 + pMidBuffer[i] * m2 ) / overlapLength;
m1 += 1;
m2 -= 1;
}
}
void TDStretch::clearMidBuffer()
{
memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
}
void TDStretch::clearInput()
{
inputBuffer.clear();
clearMidBuffer();
}
// Clears the sample buffers
void TDStretch::clear()
{
outputBuffer.clear();
clearInput();
}
// Enables/disables the quick position seeking algorithm. Zero to disable, nonzero
// to enable
void TDStretch::enableQuickSeek(BOOL enable)
{
bQuickSeek = enable;
}
// Returns nonzero if the quick seeking algorithm is enabled.
BOOL TDStretch::isQuickSeekEnabled() const
{
return bQuickSeek;
}
// Seeks for the optimal overlap-mixing position.
int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
{
if (bQuickSeek)
{
return seekBestOverlapPositionQuick(refPos);
}
else
{
return seekBestOverlapPositionFull(refPos);
}
}
// Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
// of 'ovlPos'.
inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
{
if (channels == 2)
{
// stereo sound
overlapStereo(pOutput, pInput + 2 * ovlPos);
} else {
// mono sound.
overlapMono(pOutput, pInput + ovlPos);
}
}
// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
// routine
//
// The best position is determined as the position where the two overlapped
// sample sequences are 'most alike', in terms of the highest cross-correlation
// value over the overlapping period
int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
{
int bestOffs;
double bestCorr, corr;
int i;
bestCorr = FLT_MIN;
bestOffs = 0;
// Scans for the best correlation value by testing each possible position
// over the permitted range.
for (i = 0; i < seekLength; i ++)
{
// Calculates correlation value for the mixing position corresponding
// to 'i'
corr = calcCrossCorr(refPos + channels * i, pMidBuffer);
// heuristic rule to slightly favour values close to mid of the range
double tmp = (double)(2 * i - seekLength) / (double)seekLength;
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
// Checks for the highest correlation value
if (corr > bestCorr)
{
bestCorr = corr;
bestOffs = i;
}
}
// clear cross correlation routine state if necessary (is so e.g. in MMX routines).
clearCrossCorrState();
return bestOffs;
}
// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
// routine
//
// The best position is determined as the position where the two overlapped
// sample sequences are 'most alike', in terms of the highest cross-correlation
// value over the overlapping period
int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
{
int j;
int bestOffs;
double bestCorr, corr;
int scanCount, corrOffset, tempOffset;
bestCorr = FLT_MIN;
bestOffs = _scanOffsets[0][0];
corrOffset = 0;
tempOffset = 0;
// Scans for the best correlation value using four-pass hierarchical search.
//
// The look-up table 'scans' has hierarchical position adjusting steps.
// In first pass the routine searhes for the highest correlation with
// relatively coarse steps, then rescans the neighbourhood of the highest
// correlation with better resolution and so on.
for (scanCount = 0;scanCount < 4; scanCount ++)
{
j = 0;
while (_scanOffsets[scanCount][j])
{
tempOffset = corrOffset + _scanOffsets[scanCount][j];
if (tempOffset >= seekLength) break;
// Calculates correlation value for the mixing position corresponding
// to 'tempOffset'
corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer);
// heuristic rule to slightly favour values close to mid of the range
double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
// Checks for the highest correlation value
if (corr > bestCorr)
{
bestCorr = corr;
bestOffs = tempOffset;
}
j ++;
}
corrOffset = bestOffs;
}
// clear cross correlation routine state if necessary (is so e.g. in MMX routines).
clearCrossCorrState();
return bestOffs;
}
/// clear cross correlation routine state if necessary
void TDStretch::clearCrossCorrState()
{
// default implementation is empty.
}
/// Calculates processing sequence length according to tempo setting
void TDStretch::calcSeqParameters()
{
// Adjust tempo param according to tempo, so that variating processing sequence length is used
// at varius tempo settings, between the given low...top limits
#define AUTOSEQ_TEMPO_LOW 0.5 // auto setting low tempo range (-50%)
#define AUTOSEQ_TEMPO_TOP 2.0 // auto setting top tempo range (+100%)
// sequence-ms setting values at above low & top tempo
#define AUTOSEQ_AT_MIN 125.0
#define AUTOSEQ_AT_MAX 50.0
#define AUTOSEQ_K ((AUTOSEQ_AT_MAX - AUTOSEQ_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
#define AUTOSEQ_C (AUTOSEQ_AT_MIN - (AUTOSEQ_K) * (AUTOSEQ_TEMPO_LOW))
// seek-window-ms setting values at above low & top tempo
#define AUTOSEEK_AT_MIN 25.0
#define AUTOSEEK_AT_MAX 15.0
#define AUTOSEEK_K ((AUTOSEEK_AT_MAX - AUTOSEEK_AT_MIN) / (AUTOSEQ_TEMPO_TOP - AUTOSEQ_TEMPO_LOW))
#define AUTOSEEK_C (AUTOSEEK_AT_MIN - (AUTOSEEK_K) * (AUTOSEQ_TEMPO_LOW))
#define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
double seq, seek;
if (bAutoSeqSetting)
{
seq = AUTOSEQ_C + AUTOSEQ_K * tempo;
seq = CHECK_LIMITS(seq, AUTOSEQ_AT_MAX, AUTOSEQ_AT_MIN);
sequenceMs = (int)(seq + 0.5);
}
if (bAutoSeekSetting)
{
seek = AUTOSEEK_C + AUTOSEEK_K * tempo;
seek = CHECK_LIMITS(seek, AUTOSEEK_AT_MAX, AUTOSEEK_AT_MIN);
seekWindowMs = (int)(seek + 0.5);
}
// Update seek window lengths
seekWindowLength = (sampleRate * sequenceMs) / 1000;
if (seekWindowLength < 2 * overlapLength)
{
seekWindowLength = 2 * overlapLength;
}
seekLength = (sampleRate * seekWindowMs) / 1000;
}
// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
// tempo, larger faster tempo.
void TDStretch::setTempo(float newTempo)
{
int intskip;
tempo = newTempo;
// Calculate new sequence duration
calcSeqParameters();
// Calculate ideal skip length (according to tempo value)
nominalSkip = tempo * (seekWindowLength - overlapLength);
intskip = (int)(nominalSkip + 0.5f);
// Calculate how many samples are needed in the 'inputBuffer' to
// process another batch of samples
//sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
}
// Sets the number of channels, 1 = mono, 2 = stereo
void TDStretch::setChannels(int numChannels)
{
assert(numChannels > 0);
if (channels == numChannels) return;
assert(numChannels == 1 || numChannels == 2);
channels = numChannels;
inputBuffer.setChannels(channels);
outputBuffer.setChannels(channels);
}
// nominal tempo, no need for processing, just pass the samples through
// to outputBuffer
/*
void TDStretch::processNominalTempo()
{
assert(tempo == 1.0f);
if (bMidBufferDirty)
{
// If there are samples in pMidBuffer waiting for overlapping,
// do a single sliding overlapping with them in order to prevent a
// clicking distortion in the output sound
if (inputBuffer.numSamples() < overlapLength)
{
// wait until we've got overlapLength input samples
return;
}
// Mix the samples in the beginning of 'inputBuffer' with the
// samples in 'midBuffer' using sliding overlapping
overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0);
outputBuffer.putSamples(overlapLength);
inputBuffer.receiveSamples(overlapLength);
clearMidBuffer();
// now we've caught the nominal sample flow and may switch to
// bypass mode
}
// Simply bypass samples from input to output
outputBuffer.moveSamples(inputBuffer);
}
*/
#include <stdio.h>
// Processes as many processing frames of the samples 'inputBuffer', store
// the result into 'outputBuffer'
void TDStretch::processSamples()
{
int ovlSkip, offset;
int temp;
/* Removed this small optimization - can introduce a click to sound when tempo setting
crosses the nominal value
if (tempo == 1.0f)
{
// tempo not changed from the original, so bypass the processing
processNominalTempo();
return;
}
*/
// Process samples as long as there are enough samples in 'inputBuffer'
// to form a processing frame.
while ((int)inputBuffer.numSamples() >= sampleReq)
{
// If tempo differs from the normal ('SCALE'), scan for the best overlapping
// position
offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
// Mix the samples in the 'inputBuffer' at position of 'offset' with the
// samples in 'midBuffer' using sliding overlapping
// ... first partially overlap with the end of the previous sequence
// (that's in 'midBuffer')
overlap(outputBuffer.ptrEnd((uint)overlapLength), inputBuffer.ptrBegin(), (uint)offset);
outputBuffer.putSamples((uint)overlapLength);
// ... then copy sequence samples from 'inputBuffer' to output:
// length of sequence
temp = (seekWindowLength - 2 * overlapLength);
// crosscheck that we don't have buffer overflow...
if ((int)inputBuffer.numSamples() < (offset + temp + overlapLength * 2))
{
continue; // just in case, shouldn't really happen
}
outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
// Copies the end of the current sequence from 'inputBuffer' to
// 'midBuffer' for being mixed with the beginning of the next
// processing sequence and so on
assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength),
channels * sizeof(SAMPLETYPE) * overlapLength);
// Remove the processed samples from the input buffer. Update
// the difference between integer & nominal skip step to 'skipFract'
// in order to prevent the error from accumulating over time.
skipFract += nominalSkip; // real skip size
ovlSkip = (int)skipFract; // rounded to integer skip
skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
inputBuffer.receiveSamples((uint)ovlSkip);
}
}
// Adds 'numsamples' pcs of samples from the 'samples' memory position into
// the input of the object.
void TDStretch::putSamples(const SAMPLETYPE *samples, uint nSamples)
{
// Add the samples into the input buffer
inputBuffer.putSamples(samples, nSamples);
// Process the samples in input buffer
processSamples();
}
/// Set new overlap length parameter & reallocate RefMidBuffer if necessary.
void TDStretch::acceptNewOverlapLength(int newOverlapLength)
{
int prevOvl;
assert(newOverlapLength >= 0);
prevOvl = overlapLength;
overlapLength = newOverlapLength;
if (overlapLength > prevOvl)
{
delete[] pMidBufferUnaligned;
pMidBufferUnaligned = new SAMPLETYPE[overlapLength * 2 + 16 / sizeof(SAMPLETYPE)];
// ensure that 'pMidBuffer' is aligned to 16 byte boundary for efficiency
pMidBuffer = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(pMidBufferUnaligned);
clearMidBuffer();
}
}
// Operator 'new' is overloaded so that it automatically creates a suitable instance
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
void * TDStretch::operator new(size_t s)
{
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
return newInstance();
}
TDStretch * TDStretch::newInstance()
{
uint uExtensions;
uExtensions = detectCPUextensions();
// Check if MMX/SSE instruction set extensions supported by CPU
#ifdef SOUNDTOUCH_ALLOW_MMX
// MMX routines available only with integer sample types
if (uExtensions & SUPPORT_MMX)
{
return ::new TDStretchMMX;
}
else
#endif // SOUNDTOUCH_ALLOW_MMX
#ifdef SOUNDTOUCH_ALLOW_SSE
if (uExtensions & SUPPORT_SSE)
{
// SSE support
return ::new TDStretchSSE;
}
else
#endif // SOUNDTOUCH_ALLOW_SSE
{
// ISA optimizations not supported, use plain C version
return ::new TDStretch;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Integer arithmetics specific algorithm implementations.
//
//////////////////////////////////////////////////////////////////////////////
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
// version of the routine.
void TDStretch::overlapStereo(short *poutput, const short *input) const
{
int i;
short temp;
int cnt2;
for (i = 0; i < overlapLength ; i ++)
{
temp = (short)(overlapLength - i);
cnt2 = 2 * i;
poutput[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength;
poutput[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
}
}
// Calculates the x having the closest 2^x value for the given value
static int _getClosest2Power(double value)
{
return (int)(log(value) / log(2.0) + 0.5);
}
/// Calculates overlap period length in samples.
/// Integer version rounds overlap length to closest power of 2
/// for a divide scaling operation.
void TDStretch::calculateOverlapLength(int aoverlapMs)
{
int newOvl;
assert(aoverlapMs >= 0);
// calculate overlap length so that it's power of 2 - thus it's easy to do
// integer division by right-shifting. Term "-1" at end is to account for
// the extra most significatnt bit left unused in result by signed multiplication
overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
if (overlapDividerBits > 9) overlapDividerBits = 9;
if (overlapDividerBits < 3) overlapDividerBits = 3;
newOvl = (int)pow(2.0, (int)overlapDividerBits + 1); // +1 => account for -1 above
acceptNewOverlapLength(newOvl);
// calculate sloping divider so that crosscorrelation operation won't
// overflow 32-bit register. Max. sum of the crosscorrelation sum without
// divider would be 2^30*(N^3-N)/3, where N = overlap length
slopingDivider = (newOvl * newOvl - 1) / 3;
}
double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare) const
{
long corr;
long norm;
int i;
corr = norm = 0;
// Same routine for stereo and mono. For stereo, unroll loop for better
// efficiency and gives slightly better resolution against rounding.
// For mono it same routine, just unrolls loop by factor of 4
for (i = 0; i < channels * overlapLength; i += 4)
{
corr += (mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1] +
mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
norm += (mixingPos[i] * mixingPos[i] +
mixingPos[i + 1] * mixingPos[i + 1] +
mixingPos[i + 2] * mixingPos[i + 2] +
mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
}
// Normalize result by dividing by sqrt(norm) - this step is easiest
// done using floating point operation
if (norm == 0) norm = 1; // to avoid div by zero
return (double)corr / sqrt((double)norm);
}
#endif // SOUNDTOUCH_INTEGER_SAMPLES
//////////////////////////////////////////////////////////////////////////////
//
// Floating point arithmetics specific algorithm implementations.
//
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
{
int i;
float fScale;
float f1;
float f2;
fScale = 1.0f / (float)overlapLength;
f1 = 0;
f2 = 1.0f;
for (i = 0; i < 2 * (int)overlapLength ; i += 2)
{
pOutput[i + 0] = pInput[i + 0] * f1 + pMidBuffer[i + 0] * f2;
pOutput[i + 1] = pInput[i + 1] * f1 + pMidBuffer[i + 1] * f2;
f1 += fScale;
f2 -= fScale;
}
}
/// Calculates overlapInMsec period length in samples.
void TDStretch::calculateOverlapLength(int overlapInMsec)
{
int newOvl;
assert(overlapInMsec >= 0);
newOvl = (sampleRate * overlapInMsec) / 1000;
if (newOvl < 16) newOvl = 16;
// must be divisible by 8
newOvl -= newOvl % 8;
acceptNewOverlapLength(newOvl);
}
double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare) const
{
double corr;
double norm;
int i;
corr = norm = 0;
// Same routine for stereo and mono. For Stereo, unroll by factor of 2.
// For mono it's same routine yet unrollsd by factor of 4.
for (i = 0; i < channels * overlapLength; i += 4)
{
corr += mixingPos[i] * compare[i] +
mixingPos[i + 1] * compare[i + 1];
norm += mixingPos[i] * mixingPos[i] +
mixingPos[i + 1] * mixingPos[i + 1];
// unroll the loop for better CPU efficiency:
corr += mixingPos[i + 2] * compare[i + 2] +
mixingPos[i + 3] * compare[i + 3];
norm += mixingPos[i + 2] * mixingPos[i + 2] +
mixingPos[i + 3] * mixingPos[i + 3];
}
if (norm < 1e-9) norm = 1.0; // to avoid div by zero
return corr / sqrt(norm);
}
#endif // SOUNDTOUCH_FLOAT_SAMPLES

View File

@@ -13,6 +13,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-04-01 16:49:30 -0300 (dom, 01 abr 2012) $
// File revision : $Revision: 4 $
//
// $Id: TDStretch.h 137 2012-04-01 19:49:30Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -105,57 +112,46 @@ class TDStretch : public FIFOProcessor
protected:
int channels;
int sampleReq;
float tempo;
SAMPLETYPE *pMidBuffer;
SAMPLETYPE *pMidBufferUnaligned;
int overlapLength;
int seekLength;
int seekWindowLength;
int overlapDividerBitsNorm;
int overlapDividerBitsPure;
int overlapDividerBits;
int slopingDivider;
float nominalSkip;
float skipFract;
FIFOSampleBuffer outputBuffer;
FIFOSampleBuffer inputBuffer;
BOOL bQuickSeek;
int sampleRate;
int sequenceMs;
int seekWindowMs;
int overlapMs;
unsigned long maxnorm;
float maxnormf;
double tempo;
double nominalSkip;
double skipFract;
bool bQuickSeek;
bool bAutoSeqSetting;
bool bAutoSeekSetting;
bool isBeginning;
SAMPLETYPE *pMidBuffer;
SAMPLETYPE *pMidBufferUnaligned;
FIFOSampleBuffer outputBuffer;
FIFOSampleBuffer inputBuffer;
BOOL bAutoSeqSetting;
BOOL bAutoSeekSetting;
void acceptNewOverlapLength(int newOverlapLength);
virtual void clearCrossCorrState();
void calculateOverlapLength(int overlapMs);
virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm);
virtual double calcCrossCorrAccumulate(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare, double &norm);
virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos);
virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos);
virtual int seekBestOverlapPosition(const SAMPLETYPE *refPos);
int seekBestOverlapPosition(const SAMPLETYPE *refPos);
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;
void calcSeqParameters();
void adaptNormalizer();
/// Changes the tempo of the given sound samples.
/// Returns amount of samples returned in the "output" buffer.
@@ -184,7 +180,7 @@ public:
/// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
/// tempo, larger faster tempo.
void setTempo(double newTempo);
void setTempo(float newTempo);
/// Returns nonzero if there aren't any samples available for outputting.
virtual void clear();
@@ -197,10 +193,10 @@ public:
/// Enables/disables the quick position seeking algorithm. Zero to disable,
/// nonzero to enable
void enableQuickSeek(bool enable);
void enableQuickSeek(BOOL enable);
/// Returns nonzero if the quick seeking algorithm is enabled.
bool isQuickSeekEnabled() const;
BOOL isQuickSeekEnabled() const;
/// Sets routine control parameters. These control are certain time constants
/// defining how the sound is stretched to the desired duration.
@@ -240,15 +236,10 @@ public:
{
return seekWindowLength - overlapLength;
}
/// return approximate initial input-output latency
int getLatency() const
{
return sampleReq;
}
};
// Implementation-specific class declarations:
#ifdef SOUNDTOUCH_ALLOW_MMX
@@ -256,8 +247,7 @@ public:
class TDStretchMMX : public TDStretch
{
protected:
double calcCrossCorr(const short *mixingPos, const short *compare, double &norm);
double calcCrossCorrAccumulate(const short *mixingPos, const short *compare, double &norm);
double calcCrossCorr(const short *mixingPos, const short *compare) const;
virtual void overlapStereo(short *output, const short *input) const;
virtual void clearCrossCorrState();
};
@@ -269,8 +259,7 @@ public:
class TDStretchSSE : public TDStretch
{
protected:
double calcCrossCorr(const float *mixingPos, const float *compare, double &norm);
double calcCrossCorrAccumulate(const float *mixingPos, const float *compare, double &norm);
double calcCrossCorr(const float *mixingPos, const float *compare) const;
};
#endif /// SOUNDTOUCH_ALLOW_SSE

745
3rdparty/SoundTouch/WavFile.cpp vendored Normal file
View File

@@ -0,0 +1,745 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Classes for easy reading & writing of WAV sound files.
///
/// For big-endian CPU, define _BIG_ENDIAN_ during compile-time to correctly
/// parse the WAV files with such processors.
///
/// Admittingly, more complete WAV reader routines may exist in public domain,
/// but the reason for 'yet another' one is that those generic WAV reader
/// libraries are exhaustingly large and cumbersome! Wanted to have something
/// simpler here, i.e. something that's not already larger than rest of the
/// SoundTouch/SoundStretch program...
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
// File revision : $Revision: 4 $
//
// $Id: WavFile.cpp 63 2009-02-21 16:00:14Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdexcept>
#include <string>
#include <cstring>
#include <assert.h>
#include <limits.h>
#include "WavFile.h"
using namespace std;
static const char riffStr[] = "RIFF";
static const char waveStr[] = "WAVE";
static const char fmtStr[] = "fmt ";
static const char dataStr[] = "data";
//////////////////////////////////////////////////////////////////////////////
//
// Helper functions for swapping byte order to correctly read/write WAV files
// with big-endian CPU's: Define compile-time definition _BIG_ENDIAN_ to
// turn-on the conversion if it appears necessary.
//
// For example, Intel x86 is little-endian and doesn't require conversion,
// while PowerPC of Mac's and many other RISC cpu's are big-endian.
#ifdef BYTE_ORDER
// In gcc compiler detect the byte order automatically
#if BYTE_ORDER == BIG_ENDIAN
// big-endian platform.
#define _BIG_ENDIAN_
#endif
#endif
#ifdef _BIG_ENDIAN_
// big-endian CPU, swap bytes in 16 & 32 bit words
// helper-function to swap byte-order of 32bit integer
static inline void _swap32(unsigned int &dwData)
{
dwData = ((dwData >> 24) & 0x000000FF) |
((dwData >> 8) & 0x0000FF00) |
((dwData << 8) & 0x00FF0000) |
((dwData << 24) & 0xFF000000);
}
// helper-function to swap byte-order of 16bit integer
static inline void _swap16(unsigned short &wData)
{
wData = ((wData >> 8) & 0x00FF) |
((wData << 8) & 0xFF00);
}
// helper-function to swap byte-order of buffer of 16bit integers
static inline void _swap16Buffer(unsigned short *pData, unsigned int dwNumWords)
{
unsigned long i;
for (i = 0; i < dwNumWords; i ++)
{
_swap16(pData[i]);
}
}
#else // BIG_ENDIAN
// little-endian CPU, WAV file is ok as such
// dummy helper-function
static inline void _swap32(unsigned int &dwData)
{
// do nothing
}
// dummy helper-function
static inline void _swap16(unsigned short &wData)
{
// do nothing
}
// dummy helper-function
static inline void _swap16Buffer(unsigned short *pData, unsigned int dwNumBytes)
{
// do nothing
}
#endif // BIG_ENDIAN
//////////////////////////////////////////////////////////////////////////////
//
// Class WavInFile
//
WavInFile::WavInFile(const char *fileName)
{
// Try to open the file for reading
fptr = fopen(fileName, "rb");
if (fptr == NULL)
{
// didn't succeed
string msg = "Error : Unable to open file \"";
msg += fileName;
msg += "\" for reading.";
throw runtime_error(msg);
}
init();
}
WavInFile::WavInFile(FILE *file)
{
// Try to open the file for reading
fptr = file;
if (!file)
{
// didn't succeed
string msg = "Error : Unable to access input stream for reading";
throw runtime_error(msg);
}
init();
}
/// Init the WAV file stream
void WavInFile::init()
{
int hdrsOk;
// assume file stream is already open
assert(fptr);
// Read the file headers
hdrsOk = readWavHeaders();
if (hdrsOk != 0)
{
// Something didn't match in the wav file headers
string msg = "Input file is corrupt or not a WAV file";
throw runtime_error(msg);
}
if (header.format.fixed != 1)
{
string msg = "Input file uses unsupported encoding.";
throw runtime_error(msg);
}
dataRead = 0;
}
WavInFile::~WavInFile()
{
if (fptr) fclose(fptr);
fptr = NULL;
}
void WavInFile::rewind()
{
int hdrsOk;
fseek(fptr, 0, SEEK_SET);
hdrsOk = readWavHeaders();
assert(hdrsOk == 0);
dataRead = 0;
}
int WavInFile::checkCharTags() const
{
// header.format.fmt should equal to 'fmt '
if (memcmp(fmtStr, header.format.fmt, 4) != 0) return -1;
// header.data.data_field should equal to 'data'
if (memcmp(dataStr, header.data.data_field, 4) != 0) return -1;
return 0;
}
int WavInFile::read(char *buffer, int maxElems)
{
int numBytes;
uint afterDataRead;
// ensure it's 8 bit format
if (header.format.bits_per_sample != 8)
{
throw runtime_error("Error: WavInFile::read(char*, int) works only with 8bit samples.");
}
assert(sizeof(char) == 1);
numBytes = maxElems;
afterDataRead = dataRead + numBytes;
if (afterDataRead > header.data.data_len)
{
// Don't read more samples than are marked available in header
numBytes = (int)header.data.data_len - (int)dataRead;
assert(numBytes >= 0);
}
assert(buffer);
numBytes = fread(buffer, 1, numBytes, fptr);
dataRead += numBytes;
return numBytes;
}
int WavInFile::read(short *buffer, int maxElems)
{
unsigned int afterDataRead;
int numBytes;
int numElems;
assert(buffer);
if (header.format.bits_per_sample == 8)
{
// 8 bit format
char *temp = new char[maxElems];
int i;
numElems = read(temp, maxElems);
// convert from 8 to 16 bit
for (i = 0; i < numElems; i ++)
{
buffer[i] = temp[i] << 8;
}
delete[] temp;
}
else
{
// 16 bit format
assert(header.format.bits_per_sample == 16);
assert(sizeof(short) == 2);
numBytes = maxElems * 2;
afterDataRead = dataRead + numBytes;
if (afterDataRead > header.data.data_len)
{
// Don't read more samples than are marked available in header
numBytes = (int)header.data.data_len - (int)dataRead;
assert(numBytes >= 0);
}
numBytes = fread(buffer, 1, numBytes, fptr);
dataRead += numBytes;
numElems = numBytes / 2;
// 16bit samples, swap byte order if necessary
_swap16Buffer((unsigned short *)buffer, numElems);
}
return numElems;
}
int WavInFile::read(float *buffer, int maxElems)
{
short *temp = new short[maxElems];
int num;
int i;
double fscale;
num = read(temp, maxElems);
fscale = 1.0 / 32768.0;
// convert to floats, scale to range [-1..+1[
for (i = 0; i < num; i ++)
{
buffer[i] = (float)(fscale * (double)temp[i]);
}
delete[] temp;
return num;
}
int WavInFile::eof() const
{
// return true if all data has been read or file eof has reached
return (dataRead == header.data.data_len || feof(fptr));
}
// test if character code is between a white space ' ' and little 'z'
static int isAlpha(char c)
{
return (c >= ' ' && c <= 'z') ? 1 : 0;
}
// test if all characters are between a white space ' ' and little 'z'
static int isAlphaStr(const char *str)
{
char c;
c = str[0];
while (c)
{
if (isAlpha(c) == 0) return 0;
str ++;
c = str[0];
}
return 1;
}
int WavInFile::readRIFFBlock()
{
if (fread(&(header.riff), sizeof(WavRiff), 1, fptr) != 1) return -1;
// swap 32bit data byte order if necessary
_swap32((unsigned int &)header.riff.package_len);
// header.riff.riff_char should equal to 'RIFF');
if (memcmp(riffStr, header.riff.riff_char, 4) != 0) return -1;
// header.riff.wave should equal to 'WAVE'
if (memcmp(waveStr, header.riff.wave, 4) != 0) return -1;
return 0;
}
int WavInFile::readHeaderBlock()
{
char label[5];
string sLabel;
// lead label string
if (fread(label, 1, 4, fptr) !=4) return -1;
label[4] = 0;
if (isAlphaStr(label) == 0) return -1; // not a valid label
// Decode blocks according to their label
if (strcmp(label, fmtStr) == 0)
{
int nLen, nDump;
// 'fmt ' block
memcpy(header.format.fmt, fmtStr, 4);
// read length of the format field
if (fread(&nLen, sizeof(int), 1, fptr) != 1) return -1;
// swap byte order if necessary
_swap32((unsigned int &)nLen); // int format_len;
header.format.format_len = nLen;
// calculate how much length differs from expected
nDump = nLen - ((int)sizeof(header.format) - 8);
// if format_len is larger than expected, read only as much data as we've space for
if (nDump > 0)
{
nLen = sizeof(header.format) - 8;
}
// read data
if (fread(&(header.format.fixed), nLen, 1, fptr) != 1) return -1;
// swap byte order if necessary
_swap16((unsigned short &)header.format.fixed); // short int fixed;
_swap16((unsigned short &)header.format.channel_number); // short int channel_number;
_swap32((unsigned int &)header.format.sample_rate); // int sample_rate;
_swap32((unsigned int &)header.format.byte_rate); // int byte_rate;
_swap16((unsigned short &)header.format.byte_per_sample); // short int byte_per_sample;
_swap16((unsigned short &)header.format.bits_per_sample); // short int bits_per_sample;
// if format_len is larger than expected, skip the extra data
if (nDump > 0)
{
fseek(fptr, nDump, SEEK_CUR);
}
return 0;
}
else if (strcmp(label, dataStr) == 0)
{
// 'data' block
memcpy(header.data.data_field, dataStr, 4);
if (fread(&(header.data.data_len), sizeof(uint), 1, fptr) != 1) return -1;
// swap byte order if necessary
_swap32((unsigned int &)header.data.data_len);
return 1;
}
else
{
uint len, i;
uint temp;
// unknown block
// read length
if (fread(&len, sizeof(len), 1, fptr) != 1) return -1;
// scan through the block
for (i = 0; i < len; i ++)
{
if (fread(&temp, 1, 1, fptr) != 1) return -1;
if (feof(fptr)) return -1; // unexpected eof
}
}
return 0;
}
int WavInFile::readWavHeaders()
{
int res;
memset(&header, 0, sizeof(header));
res = readRIFFBlock();
if (res) return 1;
// read header blocks until data block is found
do
{
// read header blocks
res = readHeaderBlock();
if (res < 0) return 1; // error in file structure
} while (res == 0);
// check that all required tags are legal
return checkCharTags();
}
uint WavInFile::getNumChannels() const
{
return header.format.channel_number;
}
uint WavInFile::getNumBits() const
{
return header.format.bits_per_sample;
}
uint WavInFile::getBytesPerSample() const
{
return getNumChannels() * getNumBits() / 8;
}
uint WavInFile::getSampleRate() const
{
return header.format.sample_rate;
}
uint WavInFile::getDataSizeInBytes() const
{
return header.data.data_len;
}
uint WavInFile::getNumSamples() const
{
if (header.format.byte_per_sample == 0) return 0;
return header.data.data_len / (unsigned short)header.format.byte_per_sample;
}
uint WavInFile::getLengthMS() const
{
uint numSamples;
uint sampleRate;
numSamples = getNumSamples();
sampleRate = getSampleRate();
assert(numSamples < UINT_MAX / 1000);
return (1000 * numSamples / sampleRate);
}
//////////////////////////////////////////////////////////////////////////////
//
// Class WavOutFile
//
WavOutFile::WavOutFile(const char *fileName, int sampleRate, int bits, int channels)
{
bytesWritten = 0;
fptr = fopen(fileName, "wb");
if (fptr == NULL)
{
string msg = "Error : Unable to open file \"";
msg += fileName;
msg += "\" for writing.";
//pmsg = msg.c_str;
throw runtime_error(msg);
}
fillInHeader(sampleRate, bits, channels);
writeHeader();
}
WavOutFile::WavOutFile(FILE *file, int sampleRate, int bits, int channels)
{
bytesWritten = 0;
fptr = file;
if (fptr == NULL)
{
string msg = "Error : Unable to access output file stream.";
throw runtime_error(msg);
}
fillInHeader(sampleRate, bits, channels);
writeHeader();
}
WavOutFile::~WavOutFile()
{
finishHeader();
if (fptr) fclose(fptr);
fptr = NULL;
}
void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
{
// fill in the 'riff' part..
// copy string 'RIFF' to riff_char
memcpy(&(header.riff.riff_char), riffStr, 4);
// package_len unknown so far
header.riff.package_len = 0;
// copy string 'WAVE' to wave
memcpy(&(header.riff.wave), waveStr, 4);
// fill in the 'format' part..
// copy string 'fmt ' to fmt
memcpy(&(header.format.fmt), fmtStr, 4);
header.format.format_len = 0x10;
header.format.fixed = 1;
header.format.channel_number = (short)channels;
header.format.sample_rate = (int)sampleRate;
header.format.bits_per_sample = (short)bits;
header.format.byte_per_sample = (short)(bits * channels / 8);
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
header.format.sample_rate = (int)sampleRate;
// fill in the 'data' part..
// copy string 'data' to data_field
memcpy(&(header.data.data_field), dataStr, 4);
// data_len unknown so far
header.data.data_len = 0;
}
void WavOutFile::finishHeader()
{
// supplement the file length into the header structure
header.riff.package_len = bytesWritten + 36;
header.data.data_len = bytesWritten;
writeHeader();
}
void WavOutFile::writeHeader()
{
WavHeader hdrTemp;
int res;
// swap byte order if necessary
hdrTemp = header;
_swap32((unsigned int &)hdrTemp.riff.package_len);
_swap32((unsigned int &)hdrTemp.format.format_len);
_swap16((unsigned short &)hdrTemp.format.fixed);
_swap16((unsigned short &)hdrTemp.format.channel_number);
_swap32((unsigned int &)hdrTemp.format.sample_rate);
_swap32((unsigned int &)hdrTemp.format.byte_rate);
_swap16((unsigned short &)hdrTemp.format.byte_per_sample);
_swap16((unsigned short &)hdrTemp.format.bits_per_sample);
_swap32((unsigned int &)hdrTemp.data.data_len);
// write the supplemented header in the beginning of the file
fseek(fptr, 0, SEEK_SET);
res = fwrite(&hdrTemp, sizeof(hdrTemp), 1, fptr);
if (res != 1)
{
throw runtime_error("Error while writing to a wav file.");
}
// jump back to the end of the file
fseek(fptr, 0, SEEK_END);
}
void WavOutFile::write(const char *buffer, int numElems)
{
int res;
if (header.format.bits_per_sample != 8)
{
throw runtime_error("Error: WavOutFile::write(const char*, int) accepts only 8bit samples.");
}
assert(sizeof(char) == 1);
res = fwrite(buffer, 1, numElems, fptr);
if (res != numElems)
{
throw runtime_error("Error while writing to a wav file.");
}
bytesWritten += numElems;
}
void WavOutFile::write(const short *buffer, int numElems)
{
int res;
// 16 bit samples
if (numElems < 1) return; // nothing to do
if (header.format.bits_per_sample == 8)
{
int i;
char *temp = new char[numElems];
// convert from 16bit format to 8bit format
for (i = 0; i < numElems; i ++)
{
temp[i] = buffer[i] >> 8;
}
// write in 8bit format
write(temp, numElems);
delete[] temp;
}
else
{
// 16bit format
unsigned short *pTemp = new unsigned short[numElems];
assert(header.format.bits_per_sample == 16);
// allocate temp buffer to swap byte order if necessary
memcpy(pTemp, buffer, numElems * 2);
_swap16Buffer(pTemp, numElems);
res = fwrite(pTemp, 2, numElems, fptr);
delete[] pTemp;
if (res != numElems)
{
throw runtime_error("Error while writing to a wav file.");
}
bytesWritten += 2 * numElems;
}
}
void WavOutFile::write(const float *buffer, int numElems)
{
int i;
short *temp = new short[numElems];
int iTemp;
// convert to 16 bit integer
for (i = 0; i < numElems; i ++)
{
// convert to integer
iTemp = (int)(32768.0f * buffer[i]);
// saturate
if (iTemp < -32768) iTemp = -32768;
if (iTemp > 32767) iTemp = 32767;
temp[i] = (short)iTemp;
}
write(temp, numElems);
delete[] temp;
}

View File

@@ -4,10 +4,10 @@
///
/// For big-endian CPU, define BIG_ENDIAN during compile-time to correctly
/// parse the WAV files with such processors.
///
/// Admittingly, more complete WAV reader routines may exist in public domain, but
///
/// Admittingly, more complete WAV reader routines may exist in public domain, but
/// the reason for 'yet another' one is that those generic WAV reader libraries are
/// exhaustingly large and cumbersome! Wanted to have something simpler here, i.e.
/// exhaustingly large and cumbersome! Wanted to have something simpler here, i.e.
/// something that's not already larger than rest of the SoundTouch/SoundStretch program...
///
/// Author : Copyright (c) Olli Parviainen
@@ -16,6 +16,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
// File revision : $Revision: 4 $
//
// $Id: WavFile.h 63 2009-02-21 16:00:14Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -44,40 +51,32 @@
#ifndef uint
typedef unsigned int uint;
#endif
#endif
/// WAV audio file 'riff' section header
typedef struct
typedef struct
{
char riff_char[4];
uint package_len;
int package_len;
char wave[4];
} WavRiff;
/// WAV audio file 'format' section header
typedef struct
typedef struct
{
char fmt[4];
unsigned int format_len;
unsigned short fixed;
unsigned short channel_number;
unsigned int sample_rate;
unsigned int byte_rate;
unsigned short byte_per_sample;
unsigned short bits_per_sample;
int format_len;
short fixed;
short channel_number;
int sample_rate;
int byte_rate;
short byte_per_sample;
short bits_per_sample;
} WavFormat;
/// WAV audio file 'fact' section header
typedef struct
{
char fact_field[4];
uint fact_len;
uint fact_sample_len;
} WavFact;
/// WAV audio file 'data' section header
typedef struct
typedef struct
{
char data_field[4];
uint data_len;
@@ -85,44 +84,23 @@ typedef struct
/// WAV audio file header
typedef struct
typedef struct
{
WavRiff riff;
WavFormat format;
WavFact fact;
WavData data;
} WavHeader;
/// Base class for processing WAV audio files.
class WavFileBase
{
private:
/// Conversion working buffer;
char *convBuff;
int convBuffSize;
protected:
WavFileBase();
virtual ~WavFileBase();
/// Get pointer to conversion buffer of at min. given size
void *getConvBuffer(int sizeByte);
};
/// Class for reading WAV audio files.
class WavInFile : protected WavFileBase
class WavInFile
{
private:
/// File pointer.
FILE *fptr;
/// Position within the audio stream
long position;
/// Counter of how many bytes of sample data have been read from the file.
long dataRead;
uint dataRead;
/// WAV header information
WavHeader header;
@@ -164,7 +142,7 @@ public:
/// Get number of bits per sample, i.e. 8 or 16.
uint getNumBits() const;
/// Get sample data size in bytes. Ahem, this should return same information as
/// Get sample data size in bytes. Ahem, this should return same information as
/// 'getBytesPerSample'...
uint getDataSizeInBytes() const;
@@ -173,27 +151,22 @@ public:
/// Get number of bytes per audio sample (e.g. 16bit stereo = 4 bytes/sample)
uint getBytesPerSample() const;
/// Get number of audio channels in the file (1=mono, 2=stereo)
uint getNumChannels() const;
/// Get the audio file length in milliseconds
uint getLengthMS() const;
/// Returns how many milliseconds of audio have so far been read from the file
///
/// \return elapsed duration in milliseconds
uint getElapsedMS() const;
/// Reads audio samples from the WAV file. This routine works only for 8 bit samples.
/// Reads given number of elements from the file or if end-of-file reached, as many
/// Reads given number of elements from the file or if end-of-file reached, as many
/// elements as are left in the file.
///
/// \return Number of 8-bit integers read from the file.
int read(unsigned char *buffer, int maxElems);
int read(char *buffer, int maxElems);
/// Reads audio samples from the WAV file to 16 bit integer format. Reads given number
/// of elements from the file or if end-of-file reached, as many elements as are
/// Reads audio samples from the WAV file to 16 bit integer format. Reads given number
/// of elements from the file or if end-of-file reached, as many elements as are
/// left in the file.
///
/// \return Number of 16-bit integers read from the file.
@@ -201,10 +174,9 @@ public:
int maxElems ///< Size of 'buffer' array (number of array elements).
);
/// Reads audio samples from the WAV file to floating point format, converting
/// Reads audio samples from the WAV file to floating point format, converting
/// sample values to range [-1,1[. Reads given number of elements from the file
/// or if end-of-file reached, as many elements as are left in the file.
/// Notice that reading in float format supports 8/16/24/32bit sample formats.
///
/// \return Number of elements read from the file.
int read(float *buffer, ///< Pointer to buffer where to read data.
@@ -218,8 +190,9 @@ public:
};
/// Class for writing WAV audio files.
class WavOutFile : protected WavFileBase
class WavOutFile
{
private:
/// Pointer to the WAV file
@@ -242,7 +215,7 @@ private:
void writeHeader();
public:
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
/// if file creation fails.
WavOutFile(const char *fileName, ///< Filename
int sampleRate, ///< Sample rate (e.g. 44100 etc)
@@ -255,10 +228,10 @@ public:
/// Destructor: Finalizes & closes the WAV file.
~WavOutFile();
/// Write data to WAV file. This function works only with 8bit samples.
/// Write data to WAV file. This function works only with 8bit samples.
/// Throws a 'runtime_error' exception if writing to file fails.
void write(const unsigned char *buffer, ///< Pointer to sample data buffer.
int numElems ///< How many array items are to be written to file.
void write(const char *buffer, ///< Pointer to sample data buffer.
int numElems ///< How many array items are to be written to file.
);
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to

28
3rdparty/SoundTouch/build.sh vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/sh
curdir=`pwd`
echo -----------------
echo Building SoundTouch
echo -----------------
if [ $# -gt 0 ] && [ $1 = "all" ]
then
aclocal
automake -a
autoconf
./configure
make clean
make install
else
make $@
fi
if [ $? -ne 0 ]
then
exit 1
fi
#cp libZeroSPU2*.so* ${PCSX2PLUGINS}

37
3rdparty/SoundTouch/configure.ac vendored Normal file
View File

@@ -0,0 +1,37 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
#AC_PREREQ([2.63])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([BPMDetect.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB
CFLAGS=
CPPFLAGS=
CXXFLAGS=
CCASFLAGS=
CFLAGS+=" -m32 "
CPPFLAGS+=" -m32 "
CXXFLAGS+=" -m32 "
CCASFLAGS+=" -m32 "
# Checks for header files.
AC_CHECK_HEADERS([limits.h memory.h stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_C_RESTRICT
AC_TYPE_SIZE_T
AC_HEADER_STDBOOL
# Checks for library functions.
AC_CHECK_FUNCS([memmove memset])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@@ -12,6 +12,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2008-02-10 14:26:55 -0200 (dom, 10 fev 2008) $
// File revision : $Revision: 4 $
//
// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library

View File

@@ -1,130 +1,137 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Generic version of the x86 CPU extension detection routine.
///
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
/// for the Microsoft compiler version.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#include "STTypes.h"
#if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
#if defined(__GNUC__) && defined(__i386__)
// gcc
#include "cpuid.h"
#elif defined(_M_IX86)
// windows non-gcc
#include <intrin.h>
#endif
#define bit_MMX (1 << 23)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
#endif
//////////////////////////////////////////////////////////////////////////////
//
// processor instructions extension detection routines
//
//////////////////////////////////////////////////////////////////////////////
// Flag variable indicating whick ISA extensions are disabled (for debugging)
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
// Disables given set of instruction extensions. See SUPPORT_... defines.
void disableExtensions(uint dwDisableMask)
{
_dwDisabledISA = dwDisableMask;
}
/// Checks which instruction set extensions are supported by the CPU.
uint detectCPUextensions(void)
{
/// If building for a 64bit system (no Itanium) and the user wants optimizations.
/// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19.
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
#if ((defined(__GNUC__) && defined(__x86_64__)) \
|| defined(_M_X64)) \
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
return 0x19 & ~_dwDisabledISA;
/// If building for a 32bit system and the user wants optimizations.
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
#elif ((defined(__GNUC__) && defined(__i386__)) \
|| defined(_M_IX86)) \
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
if (_dwDisabledISA == 0xffffffff) return 0;
uint res = 0;
#if defined(__GNUC__)
// GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support.
uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable.
// Check if no cpuid support.
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions.
if (edx & bit_MMX) res = res | SUPPORT_MMX;
if (edx & bit_SSE) res = res | SUPPORT_SSE;
if (edx & bit_SSE2) res = res | SUPPORT_SSE2;
#else
// Window / VS version of cpuid. Notice that Visual Studio 2005 or later required
// for __cpuid intrinsic support.
int reg[4] = {-1};
// Check if no cpuid support.
__cpuid(reg,0);
if ((unsigned int)reg[0] == 0) return 0; // always disable extensions.
__cpuid(reg,1);
if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX;
if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE;
if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2;
#endif
return res & ~_dwDisabledISA;
#else
/// One of these is true:
/// 1) We don't want optimizations.
/// 2) Using an unsupported compiler.
/// 3) Running on a non-x86 platform.
return 0;
#endif
}
////////////////////////////////////////////////////////////////////////////////
///
/// Generic version of the x86 CPU extension detection routine.
///
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
/// for the Microsoft compiler version.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-11-08 16:44:37 -0200 (qui, 08 nov 2012) $
// File revision : $Revision: 4 $
//
// $Id: cpu_detect_x86.cpp 159 2012-11-08 18:44:37Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#include "STTypes.h"
#if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
#if defined(__GNUC__) && defined(__i386__)
// gcc
#include "cpuid.h"
#elif defined(_M_IX86)
// windows non-gcc
#include <intrin.h>
#define bit_MMX (1 << 23)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
//
// processor instructions extension detection routines
//
//////////////////////////////////////////////////////////////////////////////
// Flag variable indicating whick ISA extensions are disabled (for debugging)
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
// Disables given set of instruction extensions. See SUPPORT_... defines.
void disableExtensions(uint dwDisableMask)
{
_dwDisabledISA = dwDisableMask;
}
/// Checks which instruction set extensions are supported by the CPU.
uint detectCPUextensions(void)
{
/// If building for a 64bit system (no Itanium) and the user wants optimizations.
/// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19.
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
#if ((defined(__GNUC__) && defined(__x86_64__)) \
|| defined(_M_X64)) \
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
return 0x19 & ~_dwDisabledISA;
/// If building for a 32bit system and the user wants optimizations.
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
#elif ((defined(__GNUC__) && defined(__i386__)) \
|| defined(_M_IX86)) \
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
if (_dwDisabledISA == 0xffffffff) return 0;
uint res = 0;
#if defined(__GNUC__)
// GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support.
uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable.
// Check if no cpuid support.
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions.
if (edx & bit_MMX) res = res | SUPPORT_MMX;
if (edx & bit_SSE) res = res | SUPPORT_SSE;
if (edx & bit_SSE2) res = res | SUPPORT_SSE2;
#else
// Window / VS version of cpuid. Notice that Visual Studio 2005 or later required
// for __cpuid intrinsic support.
int reg[4] = {-1};
// Check if no cpuid support.
__cpuid(reg,0);
if ((unsigned int)reg[0] == 0) return 0; // always disable extensions.
__cpuid(reg,1);
if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX;
if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE;
if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2;
#endif
return res & ~_dwDisabledISA;
#else
/// One of these is true:
/// 1) We don't want optimizations.
/// 2) Using an unsupported compiler.
/// 3) Running on a non-x86 platform.
return 0;
#endif
}

View File

@@ -0,0 +1,134 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Generic version of the x86 CPU extension detection routine.
///
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
/// for the Microsoft compiler version.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
// File revision : $Revision: 4 $
//
// $Id: cpu_detect_x86_gcc.cpp 131 2011-09-02 18:56:11Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#include "STTypes.h"
//////////////////////////////////////////////////////////////////////////////
//
// processor instructions extension detection routines
//
//////////////////////////////////////////////////////////////////////////////
// Flag variable indicating whick ISA extensions are disabled (for debugging)
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
// Disables given set of instruction extensions. See SUPPORT_... defines.
void disableExtensions(uint dwDisableMask)
{
_dwDisabledISA = dwDisableMask;
}
/// Checks which instruction set extensions are supported by the CPU.
uint detectCPUextensions(void)
{
#if (!(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) || !(__GNUC__))
return 0; // always disable extensions on non-x86 platforms.
#else
uint res = 0;
if (_dwDisabledISA == 0xffffffff) return 0;
asm volatile(
#ifndef __x86_64__
// Check if 'cpuid' instructions is available by toggling eflags bit 21.
// Skip this for x86-64 as they always have cpuid while stack manipulation
// differs from 16/32bit ISA.
"\n\txor %%esi, %%esi" // clear %%esi = result register
"\n\tpushf" // save eflags to stack
"\n\tmovl (%%esp), %%eax" // load eax from stack (with eflags)
"\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx
"\n\txor $0x00200000, %%eax" // toggle bit 21
"\n\tmovl %%eax, (%%esp)" // store toggled eflags to stack
"\n\tpopf" // load eflags from stack
"\n\tpushf" // save updated eflags to stack
"\n\tmovl (%%esp), %%eax" // load eax from stack
"\n\tpopf" // pop stack to restore esp
"\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
"\n\tcmp %%ecx, %%eax" // compare to original eflags values
"\n\tjz end" // jumps to 'end' if cpuid not present
#endif // __x86_64__
// cpuid instruction available, test for presence of mmx instructions
"\n\tmovl $1, %%eax"
"\n\tcpuid"
"\n\ttest $0x00800000, %%edx"
"\n\tjz end" // branch if MMX not available
"\n\tor $0x01, %%esi" // otherwise add MMX support bit
"\n\ttest $0x02000000, %%edx"
"\n\tjz test3DNow" // branch if SSE not available
"\n\tor $0x08, %%esi" // otherwise add SSE support bit
"\n\ttest3DNow:"
// test for precense of AMD extensions
"\n\tmov $0x80000000, %%eax"
"\n\tcpuid"
"\n\tcmp $0x80000000, %%eax"
"\n\tjbe end" // branch if no AMD extensions detected
// test for precense of 3DNow! extension
"\n\tmov $0x80000001, %%eax"
"\n\tcpuid"
"\n\ttest $0x80000000, %%edx"
"\n\tjz end" // branch if 3DNow! not detected
"\n\tor $0x02, %%esi" // otherwise add 3DNow support bit
"\n\tend:"
"\n\tmov %%esi, %0"
: "=r" (res)
: /* no inputs */
: "%edx", "%eax", "%ecx", "%esi" );
return res & ~_dwDisabledISA;
#endif
}

View File

@@ -0,0 +1,137 @@
////////////////////////////////////////////////////////////////////////////////
///
/// Win32 version of the x86 CPU detect routine.
///
/// This file is to be compiled in Windows platform with Microsoft Visual C++
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
/// for all GNU platforms.
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2011-07-17 07:58:40 -0300 (dom, 17 jul 2011) $
// File revision : $Revision: 4 $
//
// $Id: cpu_detect_x86_win.cpp 127 2011-07-17 10:58:40Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "cpu_detect.h"
#include "STTypes.h"
//////////////////////////////////////////////////////////////////////////////
//
// processor instructions extension detection routines
//
//////////////////////////////////////////////////////////////////////////////
// Flag variable indicating whick ISA extensions are disabled (for debugging)
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
// Disables given set of instruction extensions. See SUPPORT_... defines.
void disableExtensions(uint dwDisableMask)
{
_dwDisabledISA = dwDisableMask;
}
/// Checks which instruction set extensions are supported by the CPU.
uint detectCPUextensions(void)
{
uint res = 0;
if (_dwDisabledISA == 0xffffffff) return 0;
#ifndef _M_X64
// 32bit compilation, detect CPU capabilities with inline assembler.
__asm
{
; check if 'cpuid' instructions is available by toggling eflags bit 21
;
xor esi, esi ; clear esi = result register
pushfd ; save eflags to stack
mov eax,dword ptr [esp] ; load eax from stack (with eflags)
mov ecx, eax ; save the original eflags values to ecx
xor eax, 0x00200000 ; toggle bit 21
mov dword ptr [esp],eax ; store toggled eflags to stack
popfd ; load eflags from stack
pushfd ; save updated eflags to stack
mov eax,dword ptr [esp] ; load eax from stack
popfd ; pop stack to restore stack pointer
xor edx, edx ; clear edx for defaulting no mmx
cmp eax, ecx ; compare to original eflags values
jz end ; jumps to 'end' if cpuid not present
; cpuid instruction available, test for presence of mmx instructions
mov eax, 1
cpuid
test edx, 0x00800000
jz end ; branch if MMX not available
or esi, SUPPORT_MMX ; otherwise add MMX support bit
test edx, 0x02000000
jz test3DNow ; branch if SSE not available
or esi, SUPPORT_SSE ; otherwise add SSE support bit
test3DNow:
; test for precense of AMD extensions
mov eax, 0x80000000
cpuid
cmp eax, 0x80000000
jbe end ; branch if no AMD extensions detected
; test for precense of 3DNow! extension
mov eax, 0x80000001
cpuid
test edx, 0x80000000
jz end ; branch if 3DNow! not detected
or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit
end:
mov res, esi
}
#else
// Visual C++ 64bit compilation doesn't support inline assembler. However,
// all x64 compatible CPUs support MMX & SSE extensions.
res = SUPPORT_MMX | SUPPORT_SSE | SUPPORT_SSE2;
#endif
return res & ~_dwDisabledISA;
}

1
3rdparty/SoundTouch/depcomp vendored Symbolic link
View File

@@ -0,0 +1 @@
/usr/share/automake-1.10/depcomp

1
3rdparty/SoundTouch/install-sh vendored Symbolic link
View File

@@ -0,0 +1 @@
/usr/share/automake-1.10/install-sh

1
3rdparty/SoundTouch/missing vendored Symbolic link
View File

@@ -0,0 +1 @@
/usr/share/automake-1.10/missing

317
3rdparty/SoundTouch/mmx_optimized.cpp vendored Normal file
View File

@@ -0,0 +1,317 @@
////////////////////////////////////////////////////////////////////////////////
///
/// MMX optimized routines. All MMX optimized functions have been gathered into
/// this single source code file, regardless to their class or original source
/// code file, in order to ease porting the library to other compiler and
/// processor platforms.
///
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
/// should compile with both toolsets.
///
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
/// is available for download at Microsoft Developers Network, see here:
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
///
/// Author : Copyright (c) Olli Parviainen
/// Author e-mail : oparviai 'at' iki.fi
/// SoundTouch WWW: http://www.surina.net/soundtouch
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
// File revision : $Revision: 4 $
//
// $Id: mmx_optimized.cpp 160 2012-11-08 18:53:01Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
// Copyright (c) Olli Parviainen
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////
#include "STTypes.h"
#ifdef SOUNDTOUCH_ALLOW_MMX
// MMX routines available only with integer sample type
using namespace soundtouch;
//////////////////////////////////////////////////////////////////////////////
//
// implementation of MMX optimized functions of class 'TDStretchMMX'
//
//////////////////////////////////////////////////////////////////////////////
#include "TDStretch.h"
#include <mmintrin.h>
#include <limits.h>
#include <math.h>
// Calculates cross correlation of two buffers
double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2) const
{
const __m64 *pVec1, *pVec2;
__m64 shifter;
__m64 accu, normaccu;
long corr, norm;
int i;
pVec1 = (__m64*)pV1;
pVec2 = (__m64*)pV2;
shifter = _m_from_int(overlapDividerBits);
normaccu = accu = _mm_setzero_si64();
// Process 4 parallel sets of 2 * stereo samples or 4 * mono samples
// during each round for improved CPU-level parallellization.
for (i = 0; i < channels * overlapLength / 16; i ++)
{
__m64 temp, temp2;
// dictionary of instructions:
// _m_pmaddwd : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
// _mm_add_pi32 : 2*32bit add
// _m_psrad : 32bit right-shift
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]),
_mm_madd_pi16(pVec1[1], pVec2[1]));
temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec1[0]),
_mm_madd_pi16(pVec1[1], pVec1[1]));
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]),
_mm_madd_pi16(pVec1[3], pVec2[3]));
temp2 = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec1[2]),
_mm_madd_pi16(pVec1[3], pVec1[3]));
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
normaccu = _mm_add_pi32(normaccu, _mm_sra_pi32(temp2, shifter));
pVec1 += 4;
pVec2 += 4;
}
// copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
// and finally store the result into the variable "corr"
accu = _mm_add_pi32(accu, _mm_srli_si64(accu, 32));
corr = _m_to_int(accu);
normaccu = _mm_add_pi32(normaccu, _mm_srli_si64(normaccu, 32));
norm = _m_to_int(normaccu);
// Clear MMS state
_m_empty();
// Normalize result by dividing by sqrt(norm) - this step is easiest
// done using floating point operation
if (norm == 0) norm = 1; // to avoid div by zero
return (double)corr / sqrt((double)norm);
// Note: Warning about the missing EMMS instruction is harmless
// as it'll be called elsewhere.
}
void TDStretchMMX::clearCrossCorrState()
{
// Clear MMS state
_m_empty();
//_asm EMMS;
}
// MMX-optimized version of the function overlapStereo
void TDStretchMMX::overlapStereo(short *output, const short *input) const
{
const __m64 *pVinput, *pVMidBuf;
__m64 *pVdest;
__m64 mix1, mix2, adder, shifter;
int i;
pVinput = (const __m64*)input;
pVMidBuf = (const __m64*)pMidBuffer;
pVdest = (__m64*)output;
// mix1 = mixer values for 1st stereo sample
// mix1 = mixer values for 2nd stereo sample
// adder = adder for updating mixer values after each round
mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
adder = _mm_set_pi16(1, -1, 1, -1);
mix2 = _mm_add_pi16(mix1, adder);
adder = _mm_add_pi16(adder, adder);
// Overlaplength-division by shifter. "+1" is to account for "-1" deduced in
// overlapDividerBits calculation earlier.
shifter = _m_from_int(overlapDividerBits + 1);
for (i = 0; i < overlapLength / 4; i ++)
{
__m64 temp1, temp2;
// load & shuffle data so that input & mixbuffer data samples are paired
temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
// temp = (temp .* mix) >> shifter
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
pVdest[0] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
// update mix += adder
mix1 = _mm_add_pi16(mix1, adder);
mix2 = _mm_add_pi16(mix2, adder);
// --- second round begins here ---
// load & shuffle data so that input & mixbuffer data samples are paired
temp1 = _mm_unpacklo_pi16(pVMidBuf[1], pVinput[1]); // = i2l m2l i2r m2r
temp2 = _mm_unpackhi_pi16(pVMidBuf[1], pVinput[1]); // = i3l m3l i3r m3r
// temp = (temp .* mix) >> shifter
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
pVdest[1] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
// update mix += adder
mix1 = _mm_add_pi16(mix1, adder);
mix2 = _mm_add_pi16(mix2, adder);
pVinput += 2;
pVMidBuf += 2;
pVdest += 2;
}
_m_empty(); // clear MMS state
}
//////////////////////////////////////////////////////////////////////////////
//
// implementation of MMX optimized functions of class 'FIRFilter'
//
//////////////////////////////////////////////////////////////////////////////
#include "FIRFilter.h"
FIRFilterMMX::FIRFilterMMX() : FIRFilter()
{
filterCoeffsUnalign = NULL;
}
FIRFilterMMX::~FIRFilterMMX()
{
delete[] filterCoeffsUnalign;
}
// (overloaded) Calculates filter coefficients for MMX routine
void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor)
{
uint i;
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
// Ensure that filter coeffs array is aligned to 16-byte boundary
delete[] filterCoeffsUnalign;
filterCoeffsUnalign = new short[2 * newLength + 8];
filterCoeffsAlign = (short *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign);
// rearrange the filter coefficients for mmx routines
for (i = 0;i < length; i += 4)
{
filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
filterCoeffsAlign[2 * i + 2] = coeffs[i + 0];
filterCoeffsAlign[2 * i + 3] = coeffs[i + 2];
filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];
filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];
filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];
filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];
}
}
// mmx-optimized version of the filter routine for stereo sound
uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numSamples) const
{
// Create stack copies of the needed member variables for asm routines :
uint i, j;
__m64 *pVdest = (__m64*)dest;
if (length < 2) return 0;
for (i = 0; i < (numSamples - length) / 2; i ++)
{
__m64 accu1;
__m64 accu2;
const __m64 *pVsrc = (const __m64*)src;
const __m64 *pVfilter = (const __m64*)filterCoeffsAlign;
accu1 = accu2 = _mm_setzero_si64();
for (j = 0; j < lengthDiv8 * 2; j ++)
{
__m64 temp1, temp2;
temp1 = _mm_unpacklo_pi16(pVsrc[0], pVsrc[1]); // = l2 l0 r2 r0
temp2 = _mm_unpackhi_pi16(pVsrc[0], pVsrc[1]); // = l3 l1 r3 r1
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp1, pVfilter[0])); // += l2*f2+l0*f0 r2*f2+r0*f0
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp2, pVfilter[1])); // += l3*f3+l1*f1 r3*f3+r1*f1
temp1 = _mm_unpacklo_pi16(pVsrc[1], pVsrc[2]); // = l4 l2 r4 r2
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp2, pVfilter[0])); // += l3*f2+l1*f0 r3*f2+r1*f0
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp1, pVfilter[1])); // += l4*f3+l2*f1 r4*f3+r2*f1
// accu1 += l2*f2+l0*f0 r2*f2+r0*f0
// += l3*f3+l1*f1 r3*f3+r1*f1
// accu2 += l3*f2+l1*f0 r3*f2+r1*f0
// l4*f3+l2*f1 r4*f3+r2*f1
pVfilter += 2;
pVsrc += 2;
}
// accu >>= resultDivFactor
accu1 = _mm_srai_pi32(accu1, resultDivFactor);
accu2 = _mm_srai_pi32(accu2, resultDivFactor);
// pack 2*2*32bits => 4*16 bits
pVdest[0] = _mm_packs_pi32(accu1, accu2);
src += 4;
pVdest ++;
}
_m_empty(); // clear emms state
return (numSamples & 0xfffffffe) - length;
}
#endif // SOUNDTOUCH_ALLOW_MMX

View File

@@ -0,0 +1,7 @@
#ifndef SOUNDTOUCH_CONFIG_H_INCLUDED
#define SOUNDTOUCH_CONFIG_H_INCLUDED
#endif // SOUNDTOUCH_CONFIG_H_INCLUDED

View File

@@ -23,6 +23,13 @@
///
////////////////////////////////////////////////////////////////////////////////
//
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
// File revision : $Revision: 4 $
//
// $Id: sse_optimized.cpp 160 2012-11-08 18:53:01Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
// License :
//
// SoundTouch audio processing library
@@ -64,7 +71,7 @@ using namespace soundtouch;
#include <math.h>
// Calculates cross correlation of two buffers
double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &anorm)
double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2) const
{
int i;
const float *pVec1;
@@ -134,11 +141,11 @@ double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &a
// return value = vSum[0] + vSum[1] + vSum[2] + vSum[3]
float *pvNorm = (float*)&vNorm;
float norm = (pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]);
anorm = norm;
double norm = sqrt(pvNorm[0] + pvNorm[1] + pvNorm[2] + pvNorm[3]);
if (norm < 1e-9) norm = 1.0; // to avoid div by zero
float *pvSum = (float*)&vSum;
return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / sqrt(norm < 1e-9 ? 1.0 : norm);
return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]) / norm;
/* This is approximately corresponding routine in C-language yet without normalization:
double corr, norm;
@@ -175,16 +182,6 @@ double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2, double &a
}
double TDStretchSSE::calcCrossCorrAccumulate(const float *pV1, const float *pV2, double &norm)
{
// call usual calcCrossCorr function because SSE does not show big benefit of
// accumulating "norm" value, and also the "norm" rolling algorithm would get
// complicated due to SSE-specific alignment-vs-nonexact correlation rules.
return calcCrossCorr(pV1, pV2, norm);
}
//////////////////////////////////////////////////////////////////////////////
//
// implementation of SSE optimized functions of class 'FIRFilter'
@@ -252,17 +249,14 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
assert(((ulongptr)filterCoeffsAlign) % 16 == 0);
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
#pragma omp parallel for
for (j = 0; j < count; j += 2)
{
const float *pSrc;
float *pDest;
const __m128 *pFil;
__m128 sum1, sum2;
uint i;
pSrc = (const float*)source + j * 2; // source audio data
pDest = dest + j * 2; // destination audio data
pSrc = (const float*)source; // source audio data
pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
// are aligned to 16-byte boundary
sum1 = sum2 = _mm_setzero_ps();
@@ -295,10 +289,12 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
// to sum the two hi- and lo-floats of these registers together.
// post-shuffle & add the filtered values and store to dest.
_mm_storeu_ps(pDest, _mm_add_ps(
_mm_storeu_ps(dest, _mm_add_ps(
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1,0,3,2)), // s2_1 s2_0 s1_3 s1_2
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3,2,1,0)) // s2_3 s2_2 s1_1 s1_0
));
source += 4;
dest += 4;
}
// Ideas for further improvement:

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,111 +0,0 @@
//------------------------------------------------------------------------------
// File: AMExtra.cpp
//
// Desc: DirectShow base classes - implements CRenderedInputPin class.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h> // DirectShow base class definitions
#include <mmsystem.h> // Needed for definition of timeGetTime
#include <limits.h> // Standard data type limit definitions
#include <measure.h> // Used for time critical log functions
#include "amextra.h"
#pragma warning(disable:4355)
// Implements CRenderedInputPin class
CRenderedInputPin::CRenderedInputPin(__in_opt LPCTSTR pObjectName,
__in CBaseFilter *pFilter,
__in CCritSec *pLock,
__inout HRESULT *phr,
__in_opt LPCWSTR pName) :
CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
m_bAtEndOfStream(FALSE),
m_bCompleteNotified(FALSE)
{
}
#ifdef UNICODE
CRenderedInputPin::CRenderedInputPin(__in_opt LPCSTR pObjectName,
__in CBaseFilter *pFilter,
__in CCritSec *pLock,
__inout HRESULT *phr,
__in_opt LPCWSTR pName) :
CBaseInputPin(pObjectName, pFilter, pLock, phr, pName),
m_bAtEndOfStream(FALSE),
m_bCompleteNotified(FALSE)
{
}
#endif
// Flush end of stream condition - caller should do any
// necessary stream level locking before calling this
STDMETHODIMP CRenderedInputPin::EndOfStream()
{
HRESULT hr = CheckStreaming();
// Do EC_COMPLETE handling for rendered pins
if (S_OK == hr && !m_bAtEndOfStream) {
m_bAtEndOfStream = TRUE;
FILTER_STATE fs;
EXECUTE_ASSERT(SUCCEEDED(m_pFilter->GetState(0, &fs)));
if (fs == State_Running) {
DoCompleteHandling();
}
}
return hr;
}
// Called to complete the flush
STDMETHODIMP CRenderedInputPin::EndFlush()
{
CAutoLock lck(m_pLock);
// Clean up renderer state
m_bAtEndOfStream = FALSE;
m_bCompleteNotified = FALSE;
return CBaseInputPin::EndFlush();
}
// Notify of Run() from filter
HRESULT CRenderedInputPin::Run(REFERENCE_TIME tStart)
{
UNREFERENCED_PARAMETER(tStart);
m_bCompleteNotified = FALSE;
if (m_bAtEndOfStream) {
DoCompleteHandling();
}
return S_OK;
}
// Clear status on going into paused state
HRESULT CRenderedInputPin::Active()
{
m_bAtEndOfStream = FALSE;
m_bCompleteNotified = FALSE;
return CBaseInputPin::Active();
}
// Do stuff to deliver end of stream
void CRenderedInputPin::DoCompleteHandling()
{
ASSERT(m_bAtEndOfStream);
if (!m_bCompleteNotified) {
m_bCompleteNotified = TRUE;
m_pFilter->NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)m_pFilter);
}
}

View File

@@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
// File: AMExtra.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __AMEXTRA__
#define __AMEXTRA__
// Simple rendered input pin
//
// NOTE if your filter queues stuff before rendering then it may not be
// appropriate to use this class
//
// In that case queue the end of stream condition until the last sample
// is actually rendered and flush the condition appropriately
class CRenderedInputPin : public CBaseInputPin
{
public:
CRenderedInputPin(__in_opt LPCTSTR pObjectName,
__in CBaseFilter *pFilter,
__in CCritSec *pLock,
__inout HRESULT *phr,
__in_opt LPCWSTR pName);
#ifdef UNICODE
CRenderedInputPin(__in_opt LPCSTR pObjectName,
__in CBaseFilter *pFilter,
__in CCritSec *pLock,
__inout HRESULT *phr,
__in_opt LPCWSTR pName);
#endif
// Override methods to track end of stream state
STDMETHODIMP EndOfStream();
STDMETHODIMP EndFlush();
HRESULT Active();
HRESULT Run(REFERENCE_TIME tStart);
protected:
// Member variables to track state
BOOL m_bAtEndOfStream; // Set by EndOfStream
BOOL m_bCompleteNotified; // Set when we notify for EC_COMPLETE
private:
void DoCompleteHandling();
};
#endif // __AMEXTRA__

View File

@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{27F17499-A372-4408-8AFA-4F9F4584FBD3}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="..\..\3rdparty\DefaultProjectRootDir.props" />
<Import Project="..\..\3rdparty\3rdparty.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="..\..\common\vsprops\CodeGen_Release.props" />
<Import Condition="!$(Configuration.Contains(Release))" Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>streams.h</PrecompiledHeaderFile>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="amextra.h" />
<ClInclude Include="amfilter.h" />
<ClInclude Include="cache.h" />
<ClInclude Include="combase.h" />
<ClInclude Include="ctlutil.h" />
<ClInclude Include="ddmm.h" />
<ClInclude Include="fourcc.h" />
<ClInclude Include="measure.h" />
<ClInclude Include="msgthrd.h" />
<ClInclude Include="mtype.h" />
<ClInclude Include="outputq.h" />
<ClInclude Include="pstream.h" />
<ClInclude Include="pullpin.h" />
<ClInclude Include="refclock.h" />
<ClInclude Include="reftime.h" />
<ClInclude Include="renbase.h" />
<ClInclude Include="schedule.h" />
<ClInclude Include="seekpt.h" />
<ClInclude Include="source.h" />
<ClInclude Include="streams.h" />
<ClInclude Include="strmctl.h" />
<ClInclude Include="sysclock.h" />
<ClInclude Include="transfrm.h" />
<ClInclude Include="transip.h" />
<ClInclude Include="vtrans.h" />
<ClInclude Include="wxdebug.h" />
<ClInclude Include="wxlist.h" />
<ClInclude Include="wxutil.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="amextra.cpp" />
<ClCompile Include="amfilter.cpp" />
<ClCompile Include="amvideo.cpp" />
<ClCompile Include="combase.cpp" />
<ClCompile Include="ctlutil.cpp" />
<ClCompile Include="ddmm.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="mtype.cpp" />
<ClCompile Include="outputq.cpp" />
<ClCompile Include="pstream.cpp" />
<ClCompile Include="pullpin.cpp" />
<ClCompile Include="refclock.cpp" />
<ClCompile Include="renbase.cpp" />
<ClCompile Include="schedule.cpp" />
<ClCompile Include="seekpt.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="source.cpp" />
<ClCompile Include="strmctl.cpp" />
<ClCompile Include="sysclock.cpp" />
<ClCompile Include="transfrm.cpp" />
<ClCompile Include="transip.cpp" />
<ClCompile Include="vtrans.cpp" />
<ClCompile Include="wxdebug.cpp" />
<ClCompile Include="wxlist.cpp" />
<ClCompile Include="wxutil.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@@ -1,174 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="amextra.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="amfilter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cache.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="combase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ctlutil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ddmm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="fourcc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="msgthrd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="reftime.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="refclock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pullpin.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pstream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="outputq.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mtype.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="measure.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="renbase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="schedule.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="seekpt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="streams.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="strmctl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sysclock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="transfrm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="transip.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="vtrans.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wxdebug.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wxlist.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wxutil.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="amextra.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="amfilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="amvideo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="combase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ctlutil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ddmm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mtype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="outputq.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pstream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pullpin.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="refclock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="renbase.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="schedule.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="seekpt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="strmctl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sysclock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="transfrm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="transip.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="vtrans.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wxdebug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wxlist.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wxutil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -1,923 +0,0 @@
//------------------------------------------------------------------------------
// File: CtlUtil.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Base classes implementing IDispatch parsing for the basic control dual
// interfaces. Derive from these and implement just the custom method and
// property methods. We also implement CPosPassThru that can be used by
// renderers and transforms to pass by IMediaPosition and IMediaSeeking
#ifndef __CTLUTIL__
#define __CTLUTIL__
// OLE Automation has different ideas of TRUE and FALSE
#define OATRUE (-1)
#define OAFALSE (0)
// It's possible that we could replace this class with CreateStdDispatch
class CBaseDispatch
{
ITypeInfo * m_pti;
public:
CBaseDispatch() : m_pti(NULL) {}
~CBaseDispatch();
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
REFIID riid,
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
};
class AM_NOVTABLE CMediaControl :
public IMediaControl,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaControl(const TCHAR *, LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
};
class AM_NOVTABLE CMediaEvent :
public IMediaEventEx,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaEvent(__in_opt LPCTSTR, __in_opt LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
};
class AM_NOVTABLE CMediaPosition :
public IMediaPosition,
public CUnknown
{
CBaseDispatch m_basedisp;
public:
CMediaPosition(__in_opt LPCTSTR, __in_opt LPUNKNOWN);
CMediaPosition(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT *phr);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
};
// OA-compatibility means that we must use double as the RefTime value,
// and REFERENCE_TIME (essentially a LONGLONG) within filters.
// this class converts between the two
class COARefTime : public CRefTime {
public:
COARefTime() {
};
COARefTime(CRefTime t)
: CRefTime(t)
{
};
COARefTime(REFERENCE_TIME t)
: CRefTime(t)
{
};
COARefTime(double d) {
m_time = (LONGLONG) (d * 10000000);
};
operator double() {
return double(m_time) / 10000000;
};
operator REFERENCE_TIME() {
return m_time;
};
COARefTime& operator=(const double& rd) {
m_time = (LONGLONG) (rd * 10000000);
return *this;
}
COARefTime& operator=(const REFERENCE_TIME& rt) {
m_time = rt;
return *this;
}
inline BOOL operator==(const COARefTime& rt)
{
return m_time == rt.m_time;
};
inline BOOL operator!=(const COARefTime& rt)
{
return m_time != rt.m_time;
};
inline BOOL operator < (const COARefTime& rt)
{
return m_time < rt.m_time;
};
inline BOOL operator > (const COARefTime& rt)
{
return m_time > rt.m_time;
};
inline BOOL operator >= (const COARefTime& rt)
{
return m_time >= rt.m_time;
};
inline BOOL operator <= (const COARefTime& rt)
{
return m_time <= rt.m_time;
};
inline COARefTime operator+(const COARefTime& rt)
{
return COARefTime(m_time + rt.m_time);
};
inline COARefTime operator-(const COARefTime& rt)
{
return COARefTime(m_time - rt.m_time);
};
inline COARefTime operator*(LONG l)
{
return COARefTime(m_time * l);
};
inline COARefTime operator/(LONG l)
{
return COARefTime(m_time / l);
};
private:
// Prevent bugs from constructing from LONG (which gets
// converted to double and then multiplied by 10000000
COARefTime(LONG);
LONG operator=(LONG);
};
// A utility class that handles IMediaPosition and IMediaSeeking on behalf
// of single-input pin renderers, or transform filters.
//
// Renderers will expose this from the filter; transform filters will
// expose it from the output pin and not the renderer.
//
// Create one of these, giving it your IPin* for your input pin, and delegate
// all IMediaPosition methods to it. It will query the input pin for
// IMediaPosition and respond appropriately.
//
// Call ForceRefresh if the pin connection changes.
//
// This class no longer caches the upstream IMediaPosition or IMediaSeeking
// it acquires it on each method call. This means ForceRefresh is not needed.
// The method is kept for source compatibility and to minimise the changes
// if we need to put it back later for performance reasons.
class CPosPassThru : public IMediaSeeking, public CMediaPosition
{
IPin *m_pPin;
HRESULT GetPeer(__deref_out IMediaPosition **ppMP);
HRESULT GetPeerSeeking(__deref_out IMediaSeeking **ppMS);
public:
CPosPassThru(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, IPin *);
DECLARE_IUNKNOWN
HRESULT ForceRefresh() {
return S_OK;
};
// override to return an accurate current position
virtual HRESULT GetMediaTime(__out LONGLONG *pStartTime, __out_opt LONGLONG *pEndTime) {
return E_FAIL;
}
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv);
// IMediaSeeking methods
STDMETHODIMP GetCapabilities( __out DWORD * pCapabilities );
STDMETHODIMP CheckCapabilities( __inout DWORD * pCapabilities );
STDMETHODIMP SetTimeFormat(const GUID * pFormat);
STDMETHODIMP GetTimeFormat(__out GUID *pFormat);
STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
STDMETHODIMP IsFormatSupported( const GUID * pFormat);
STDMETHODIMP QueryPreferredFormat( __out GUID *pFormat);
STDMETHODIMP ConvertTimeFormat(__out LONGLONG * pTarget,
__in_opt const GUID * pTargetFormat,
LONGLONG Source,
__in_opt const GUID * pSourceFormat );
STDMETHODIMP SetPositions( __inout_opt LONGLONG * pCurrent, DWORD CurrentFlags
, __inout_opt LONGLONG * pStop, DWORD StopFlags );
STDMETHODIMP GetPositions( __out_opt LONGLONG * pCurrent, __out_opt LONGLONG * pStop );
STDMETHODIMP GetCurrentPosition( __out LONGLONG * pCurrent );
STDMETHODIMP GetStopPosition( __out LONGLONG * pStop );
STDMETHODIMP SetRate( double dRate);
STDMETHODIMP GetRate( __out double * pdRate);
STDMETHODIMP GetDuration( __out LONGLONG *pDuration);
STDMETHODIMP GetAvailable( __out_opt LONGLONG *pEarliest, __out_opt LONGLONG *pLatest );
STDMETHODIMP GetPreroll( __out LONGLONG *pllPreroll );
// IMediaPosition properties
STDMETHODIMP get_Duration(__out REFTIME * plength);
STDMETHODIMP put_CurrentPosition(REFTIME llTime);
STDMETHODIMP get_StopTime(__out REFTIME * pllTime);
STDMETHODIMP put_StopTime(REFTIME llTime);
STDMETHODIMP get_PrerollTime(__out REFTIME * pllTime);
STDMETHODIMP put_PrerollTime(REFTIME llTime);
STDMETHODIMP get_Rate(__out double * pdRate);
STDMETHODIMP put_Rate(double dRate);
STDMETHODIMP get_CurrentPosition(__out REFTIME * pllTime);
STDMETHODIMP CanSeekForward(__out LONG *pCanSeekForward);
STDMETHODIMP CanSeekBackward(__out LONG *pCanSeekBackward);
private:
HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ),
__out LONGLONG * pll );
};
// Adds the ability to return a current position
class CRendererPosPassThru : public CPosPassThru
{
CCritSec m_PositionLock; // Locks access to our position
LONGLONG m_StartMedia; // Start media time last seen
LONGLONG m_EndMedia; // And likewise the end media
BOOL m_bReset; // Have media times been set
public:
// Used to help with passing media times through graph
CRendererPosPassThru(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, IPin *);
HRESULT RegisterMediaTime(IMediaSample *pMediaSample);
HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime);
HRESULT GetMediaTime(__out LONGLONG *pStartTime,__out_opt LONGLONG *pEndTime);
HRESULT ResetMediaTime();
HRESULT EOS();
};
STDAPI CreatePosPassThru(
__in_opt LPUNKNOWN pAgg,
BOOL bRenderer,
IPin *pPin,
__deref_out IUnknown **ppPassThru
);
// A class that handles the IDispatch part of IBasicAudio and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBasicAudio : public IBasicAudio, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBasicAudio(__in_opt LPCTSTR, __in_opt LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
};
// A class that handles the IDispatch part of IBasicVideo and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBaseBasicVideo : public IBasicVideo2, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBaseBasicVideo(__in_opt LPCTSTR, __in_opt LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
STDMETHODIMP GetPreferredAspectRatio(
__out long *plAspectX,
__out long *plAspectY)
{
return E_NOTIMPL;
}
};
// A class that handles the IDispatch part of IVideoWindow and leaves the
// properties and methods themselves pure virtual.
class AM_NOVTABLE CBaseVideoWindow : public IVideoWindow, public CUnknown
{
CBaseDispatch m_basedisp;
public:
CBaseVideoWindow(__in_opt LPCTSTR, __in_opt LPUNKNOWN);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
/* IDispatch methods */
STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);
STDMETHODIMP GetTypeInfo(
UINT itinfo,
LCID lcid,
__deref_out ITypeInfo ** pptinfo);
STDMETHODIMP GetIDsOfNames(
REFIID riid,
__in_ecount(cNames) LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
__out_ecount(cNames) DISPID * rgdispid);
STDMETHODIMP Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
__in DISPPARAMS * pdispparams,
__out_opt VARIANT * pvarResult,
__out_opt EXCEPINFO * pexcepinfo,
__out_opt UINT * puArgErr);
};
// abstract class to help source filters with their implementation
// of IMediaPosition. Derive from this and set the duration (and stop
// position). Also override NotifyChange to do something when the properties
// change.
class AM_NOVTABLE CSourcePosition : public CMediaPosition
{
public:
CSourcePosition(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, __in CCritSec *);
// IMediaPosition methods
STDMETHODIMP get_Duration(__out REFTIME * plength);
STDMETHODIMP put_CurrentPosition(REFTIME llTime);
STDMETHODIMP get_StopTime(__out REFTIME * pllTime);
STDMETHODIMP put_StopTime(REFTIME llTime);
STDMETHODIMP get_PrerollTime(__out REFTIME * pllTime);
STDMETHODIMP put_PrerollTime(REFTIME llTime);
STDMETHODIMP get_Rate(__out double * pdRate);
STDMETHODIMP put_Rate(double dRate);
STDMETHODIMP CanSeekForward(__out LONG *pCanSeekForward);
STDMETHODIMP CanSeekBackward(__out LONG *pCanSeekBackward);
// override if you can return the data you are actually working on
STDMETHODIMP get_CurrentPosition(__out REFTIME * pllTime) {
return E_NOTIMPL;
};
protected:
// we call this to notify changes. Override to handle them
virtual HRESULT ChangeStart() PURE;
virtual HRESULT ChangeStop() PURE;
virtual HRESULT ChangeRate() PURE;
COARefTime m_Duration;
COARefTime m_Start;
COARefTime m_Stop;
double m_Rate;
CCritSec * m_pLock;
};
class AM_NOVTABLE CSourceSeeking :
public IMediaSeeking,
public CUnknown
{
public:
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
// IMediaSeeking methods
STDMETHODIMP IsFormatSupported(const GUID * pFormat);
STDMETHODIMP QueryPreferredFormat(__out GUID *pFormat);
STDMETHODIMP SetTimeFormat(const GUID * pFormat);
STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
STDMETHODIMP GetTimeFormat(__out GUID *pFormat);
STDMETHODIMP GetDuration(__out LONGLONG *pDuration);
STDMETHODIMP GetStopPosition(__out LONGLONG *pStop);
STDMETHODIMP GetCurrentPosition(__out LONGLONG *pCurrent);
STDMETHODIMP GetCapabilities( __out DWORD * pCapabilities );
STDMETHODIMP CheckCapabilities( __inout DWORD * pCapabilities );
STDMETHODIMP ConvertTimeFormat( __out LONGLONG * pTarget,
__in_opt const GUID * pTargetFormat,
LONGLONG Source,
__in_opt const GUID * pSourceFormat );
STDMETHODIMP SetPositions( __inout_opt LONGLONG * pCurrent, DWORD CurrentFlags
, __inout_opt LONGLONG * pStop, DWORD StopFlags );
STDMETHODIMP GetPositions( __out_opt LONGLONG * pCurrent, __out_opt LONGLONG * pStop );
STDMETHODIMP GetAvailable( __out_opt LONGLONG * pEarliest, __out_opt LONGLONG * pLatest );
STDMETHODIMP SetRate( double dRate);
STDMETHODIMP GetRate( __out double * pdRate);
STDMETHODIMP GetPreroll(__out LONGLONG *pPreroll);
protected:
// ctor
CSourceSeeking(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, __in CCritSec *);
// we call this to notify changes. Override to handle them
virtual HRESULT ChangeStart() PURE;
virtual HRESULT ChangeStop() PURE;
virtual HRESULT ChangeRate() PURE;
CRefTime m_rtDuration; // length of stream
CRefTime m_rtStart; // source will start here
CRefTime m_rtStop; // source will stop here
double m_dRateSeeking;
// seeking capabilities
DWORD m_dwSeekingCaps;
CCritSec * m_pLock;
};
// Base classes supporting Deferred commands.
// Deferred commands are queued by calls to methods on the IQueueCommand
// interface, exposed by the filtergraph and by some filters. A successful
// call to one of these methods will return an IDeferredCommand interface
// representing the queued command.
//
// A CDeferredCommand object represents a single deferred command, and exposes
// the IDeferredCommand interface as well as other methods permitting time
// checks and actual execution. It contains a reference to the CCommandQueue
// object on which it is queued.
//
// CCommandQueue is a base class providing a queue of CDeferredCommand
// objects, and methods to add, remove, check status and invoke the queued
// commands. A CCommandQueue object would be part of an object that
// implemented IQueueCommand.
class CCmdQueue;
// take a copy of the params and store them. Release any allocated
// memory in destructor
class CDispParams : public DISPPARAMS
{
public:
CDispParams(UINT nArgs, __in_ecount(nArgs) VARIANT* pArgs, __inout_opt HRESULT *phr = NULL);
~CDispParams();
};
// CDeferredCommand lifetime is controlled by refcounts. Caller of
// InvokeAt.. gets a refcounted interface pointer, and the CCmdQueue
// object also holds a refcount on us. Calling Cancel or Invoke takes
// us off the CCmdQueue and thus reduces the refcount by 1. Once taken
// off the queue we cannot be put back on the queue.
class CDeferredCommand
: public CUnknown,
public IDeferredCommand
{
public:
CDeferredCommand(
__inout CCmdQueue * pQ,
__in_opt LPUNKNOWN pUnk, // aggregation outer unk
__inout HRESULT * phr,
__in LPUNKNOWN pUnkExecutor, // object that will execute this cmd
REFTIME time,
__in GUID* iid,
long dispidMethod,
short wFlags,
long cArgs,
__in_ecount(cArgs) VARIANT* pDispParams,
__out VARIANT* pvarResult,
__out short* puArgErr,
BOOL bStream
);
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __out void **ppv);
// IDeferredCommand methods
STDMETHODIMP Cancel();
STDMETHODIMP Confidence(
__out LONG* pConfidence);
STDMETHODIMP Postpone(
REFTIME newtime);
STDMETHODIMP GetHResult(
__out HRESULT* phrResult);
// other public methods
HRESULT Invoke();
// access methods
// returns TRUE if streamtime, FALSE if presentation time
BOOL IsStreamTime() {
return m_bStream;
};
CRefTime GetTime() {
return m_time;
};
REFIID GetIID() {
return *m_iid;
};
long GetMethod() {
return m_dispidMethod;
};
short GetFlags() {
return m_wFlags;
};
DISPPARAMS* GetParams() {
return &m_DispParams;
};
VARIANT* GetResult() {
return m_pvarResult;
};
protected:
CCmdQueue* m_pQueue;
// pUnk for the interface that we will execute the command on
LPUNKNOWN m_pUnk;
// stored command data
REFERENCE_TIME m_time;
GUID* m_iid;
long m_dispidMethod;
short m_wFlags;
VARIANT* m_pvarResult;
BOOL m_bStream;
CDispParams m_DispParams;
DISPID m_DispId; // For get and put
// we use this for ITypeInfo access
CBaseDispatch m_Dispatch;
// save retval here
HRESULT m_hrResult;
};
// a list of CDeferredCommand objects. this is a base class providing
// the basics of access to the list. If you want to use CDeferredCommand
// objects then your queue needs to be derived from this class.
class AM_NOVTABLE CCmdQueue
{
public:
CCmdQueue(__inout_opt HRESULT *phr = NULL);
virtual ~CCmdQueue();
// returns a new CDeferredCommand object that will be initialised with
// the parameters and will be added to the queue during construction.
// returns S_OK if successfully created otherwise an error and
// no object has been queued.
virtual HRESULT New(
__out CDeferredCommand **ppCmd,
__in LPUNKNOWN pUnk,
REFTIME time,
__in GUID* iid,
long dispidMethod,
short wFlags,
long cArgs,
__in_ecount(cArgs) VARIANT* pDispParams,
__out VARIANT* pvarResult,
__out short* puArgErr,
BOOL bStream
);
// called by the CDeferredCommand object to add and remove itself
// from the queue
virtual HRESULT Insert(__in CDeferredCommand* pCmd);
virtual HRESULT Remove(__in CDeferredCommand* pCmd);
// Command-Due Checking
//
// There are two schemes of synchronisation: coarse and accurate. In
// coarse mode, you wait till the time arrives and then execute the cmd.
// In accurate mode, you wait until you are processing the sample that
// will appear at the time, and then execute the command. It's up to the
// filter which one it will implement. The filtergraph will always
// implement coarse mode for commands queued at the filtergraph.
//
// If you want coarse sync, you probably want to wait until there is a
// command due, and then execute it. You can do this by calling
// GetDueCommand. If you have several things to wait for, get the
// event handle from GetDueHandle() and when this is signalled then call
// GetDueCommand. Stream time will only advance between calls to Run and
// EndRun. Note that to avoid an extra thread there is no guarantee that
// if the handle is set there will be a command ready. Each time the
// event is signalled, call GetDueCommand (probably with a 0 timeout);
// This may return E_ABORT.
//
// If you want accurate sync, you must call GetCommandDueFor, passing
// as a parameter the stream time of the samples you are about to process.
// This will return:
// -- a stream-time command due at or before that stream time
// -- a presentation-time command due at or before the
// time that stream time will be presented (only between Run
// and EndRun calls, since outside of this, the mapping from
// stream time to presentation time is not known.
// -- any presentation-time command due now.
// This means that if you want accurate synchronisation on samples that
// might be processed during Paused mode, you need to use
// stream-time commands.
//
// In all cases, commands remain queued until Invoked or Cancelled. The
// setting and resetting of the event handle is managed entirely by this
// queue object.
// set the clock used for timing
virtual HRESULT SetSyncSource(__in_opt IReferenceClock*);
// switch to run mode. Streamtime to Presentation time mapping known.
virtual HRESULT Run(REFERENCE_TIME tStreamTimeOffset);
// switch to Stopped or Paused mode. Time mapping not known.
virtual HRESULT EndRun();
// return a pointer to the next due command. Blocks for msTimeout
// milliseconds until there is a due command.
// Stream-time commands will only become due between Run and Endrun calls.
// The command remains queued until invoked or cancelled.
// Returns E_ABORT if timeout occurs, otherwise S_OK (or other error).
// Returns an AddRef-ed object
virtual HRESULT GetDueCommand(__out CDeferredCommand ** ppCmd, long msTimeout);
// return the event handle that will be signalled whenever
// there are deferred commands due for execution (when GetDueCommand
// will not block).
HANDLE GetDueHandle() {
return HANDLE(m_evDue);
};
// return a pointer to a command that will be due for a given time.
// Pass in a stream time here. The stream time offset will be passed
// in via the Run method.
// Commands remain queued until invoked or cancelled.
// This method will not block. It will report VFW_E_NOT_FOUND if there
// are no commands due yet.
// Returns an AddRef-ed object
virtual HRESULT GetCommandDueFor(REFERENCE_TIME tStream, __out CDeferredCommand**ppCmd);
// check if a given time is due (TRUE if it is due yet)
BOOL CheckTime(CRefTime time, BOOL bStream) {
// if no clock, nothing is due!
if (!m_pClock) {
return FALSE;
}
// stream time
if (bStream) {
// not valid if not running
if (!m_bRunning) {
return FALSE;
}
// add on known stream time offset to get presentation time
time += m_StreamTimeOffset;
}
CRefTime Now;
m_pClock->GetTime((REFERENCE_TIME*)&Now);
return (time <= Now);
};
protected:
// protect access to lists etc
CCritSec m_Lock;
// commands queued in presentation time are stored here
CGenericList<CDeferredCommand> m_listPresentation;
// commands queued in stream time are stored here
CGenericList<CDeferredCommand> m_listStream;
// set when any commands are due
CAMEvent m_evDue;
// creates an advise for the earliest time required, if any
void SetTimeAdvise(void);
// advise id from reference clock (0 if no outstanding advise)
DWORD_PTR m_dwAdvise;
// advise time is for this presentation time
CRefTime m_tCurrentAdvise;
// the reference clock we are using (addrefed)
IReferenceClock* m_pClock;
// true when running
BOOL m_bRunning;
// contains stream time offset when m_bRunning is true
CRefTime m_StreamTimeOffset;
};
#endif // __CTLUTIL__

View File

@@ -1,28 +0,0 @@
//------------------------------------------------------------------------------
// File: DDMM.h
//
// Desc: DirectShow base classes - efines routines for using DirectDraw
// on a multimonitor system.
//
// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
// DDRAW.H might not include these
#ifndef DDENUM_ATTACHEDSECONDARYDEVICES
#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L
#endif
typedef HRESULT (*PDRAWCREATE)(IID *,LPDIRECTDRAW *,LPUNKNOWN);
typedef HRESULT (*PDRAWENUM)(LPDDENUMCALLBACKA, LPVOID);
IDirectDraw * DirectDrawCreateFromDevice(__in_opt LPSTR, PDRAWCREATE, PDRAWENUM);
IDirectDraw * DirectDrawCreateFromDeviceEx(__in_opt LPSTR, PDRAWCREATE, LPDIRECTDRAWENUMERATEEXA);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -1,402 +0,0 @@
//------------------------------------------------------------------------------
// File: RefClock.cpp
//
// Desc: DirectShow base classes - implements the IReferenceClock interface.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include <limits.h>
#ifdef DXMPERF
#include "dxmperf.h"
#endif // DXMPERF
// 'this' used in constructor list
#pragma warning(disable:4355)
STDMETHODIMP CBaseReferenceClock::NonDelegatingQueryInterface(
REFIID riid,
__deref_out void ** ppv)
{
HRESULT hr;
if (riid == IID_IReferenceClock)
{
hr = GetInterface((IReferenceClock *) this, ppv);
}
else if (riid == IID_IReferenceClockTimerControl)
{
hr = GetInterface((IReferenceClockTimerControl *) this, ppv);
}
else
{
hr = CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
return hr;
}
CBaseReferenceClock::~CBaseReferenceClock()
{
#ifdef DXMPERF
PERFLOG_DTOR( L"CBaseReferenceClock", (IReferenceClock *) this );
#endif // DXMPERF
if (m_TimerResolution) timeEndPeriod(m_TimerResolution);
if (m_pSchedule)
{
m_pSchedule->DumpLinkedList();
}
if (m_hThread)
{
m_bAbort = TRUE;
TriggerThread();
WaitForSingleObject( m_hThread, INFINITE );
EXECUTE_ASSERT( CloseHandle(m_hThread) );
m_hThread = 0;
EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
delete m_pSchedule;
}
}
// A derived class may supply a hThreadEvent if it has its own thread that will take care
// of calling the schedulers Advise method. (Refere to CBaseReferenceClock::AdviseThread()
// to see what such a thread has to do.)
CBaseReferenceClock::CBaseReferenceClock( __in_opt LPCTSTR pName,
__inout_opt LPUNKNOWN pUnk,
__inout HRESULT *phr,
__inout_opt CAMSchedule * pShed )
: CUnknown( pName, pUnk )
, m_rtLastGotTime(0)
, m_TimerResolution(0)
, m_bAbort( FALSE )
, m_pSchedule( pShed ? pShed : new CAMSchedule(CreateEvent(NULL, FALSE, FALSE, NULL)) )
, m_hThread(0)
{
#ifdef DXMPERF
PERFLOG_CTOR( pName ? pName : L"CBaseReferenceClock", (IReferenceClock *) this );
#endif // DXMPERF
ASSERT(m_pSchedule);
if (!m_pSchedule)
{
*phr = E_OUTOFMEMORY;
}
else
{
// Set up the highest resolution timer we can manage
TIMECAPS tc;
m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))
? tc.wPeriodMin
: 1;
timeBeginPeriod(m_TimerResolution);
/* Initialise our system times - the derived clock should set the right values */
m_dwPrevSystemTime = timeGetTime();
m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime;
#ifdef PERF
m_idGetSystemTime = MSR_REGISTER(TEXT("CBaseReferenceClock::GetTime"));
#endif
if ( !pShed )
{
DWORD ThreadID;
m_hThread = ::CreateThread(NULL, // Security attributes
(DWORD) 0, // Initial stack size
AdviseThreadFunction, // Thread start address
(LPVOID) this, // Thread parameter
(DWORD) 0, // Creation flags
&ThreadID); // Thread identifier
if (m_hThread)
{
SetThreadPriority( m_hThread, THREAD_PRIORITY_TIME_CRITICAL );
}
else
{
*phr = E_FAIL;
EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) );
delete m_pSchedule;
m_pSchedule = NULL;
}
}
}
}
void CBaseReferenceClock::Restart (IN REFERENCE_TIME rtMinTime)
{
Lock();
m_rtLastGotTime = rtMinTime ;
Unlock();
}
STDMETHODIMP CBaseReferenceClock::GetTime(__out REFERENCE_TIME *pTime)
{
HRESULT hr;
if (pTime)
{
REFERENCE_TIME rtNow;
Lock();
rtNow = GetPrivateTime();
if (rtNow > m_rtLastGotTime)
{
m_rtLastGotTime = rtNow;
hr = S_OK;
}
else
{
hr = S_FALSE;
}
*pTime = m_rtLastGotTime;
Unlock();
MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) );
#ifdef DXMPERF
PERFLOG_GETTIME( (IReferenceClock *) this, *pTime );
#endif // DXMPERF
}
else hr = E_POINTER;
return hr;
}
/* Ask for an async notification that a time has elapsed */
STDMETHODIMP CBaseReferenceClock::AdviseTime(
REFERENCE_TIME baseTime, // base reference time
REFERENCE_TIME streamTime, // stream offset time
HEVENT hEvent, // advise via this event
__out DWORD_PTR *pdwAdviseCookie)// where your cookie goes
{
CheckPointer(pdwAdviseCookie, E_POINTER);
*pdwAdviseCookie = 0;
// Check that the event is not already set
ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0));
HRESULT hr;
const REFERENCE_TIME lRefTime = baseTime + streamTime;
if ( lRefTime <= 0 || lRefTime == MAX_TIME )
{
hr = E_INVALIDARG;
}
else
{
*pdwAdviseCookie = m_pSchedule->AddAdvisePacket( lRefTime, 0, HANDLE(hEvent), FALSE );
hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
}
return hr;
}
/* Ask for an asynchronous periodic notification that a time has elapsed */
STDMETHODIMP CBaseReferenceClock::AdvisePeriodic(
REFERENCE_TIME StartTime, // starting at this time
REFERENCE_TIME PeriodTime, // time between notifications
HSEMAPHORE hSemaphore, // advise via a semaphore
__out DWORD_PTR *pdwAdviseCookie) // where your cookie goes
{
CheckPointer(pdwAdviseCookie, E_POINTER);
*pdwAdviseCookie = 0;
HRESULT hr;
if (StartTime > 0 && PeriodTime > 0 && StartTime != MAX_TIME )
{
*pdwAdviseCookie = m_pSchedule->AddAdvisePacket( StartTime, PeriodTime, HANDLE(hSemaphore), TRUE );
hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY;
}
else hr = E_INVALIDARG;
return hr;
}
STDMETHODIMP CBaseReferenceClock::Unadvise(DWORD_PTR dwAdviseCookie)
{
return m_pSchedule->Unadvise(dwAdviseCookie);
}
REFERENCE_TIME CBaseReferenceClock::GetPrivateTime()
{
CAutoLock cObjectLock(this);
/* If the clock has wrapped then the current time will be less than
* the last time we were notified so add on the extra milliseconds
*
* The time period is long enough so that the likelihood of
* successive calls spanning the clock cycle is not considered.
*/
DWORD dwTime = timeGetTime();
{
m_rtPrivateTime += Int32x32To64(UNITS / MILLISECONDS, (DWORD)(dwTime - m_dwPrevSystemTime));
m_dwPrevSystemTime = dwTime;
}
return m_rtPrivateTime;
}
/* Adjust the current time by the input value. This allows an
external time source to work out some of the latency of the clock
system and adjust the "current" time accordingly. The intent is
that the time returned to the user is synchronised to a clock
source and allows drift to be catered for.
For example: if the clock source detects a drift it can pass a delta
to the current time rather than having to set an explicit time.
*/
STDMETHODIMP CBaseReferenceClock::SetTimeDelta(const REFERENCE_TIME & TimeDelta)
{
#ifdef DEBUG
// Just break if passed an improper time delta value
LONGLONG llDelta = TimeDelta > 0 ? TimeDelta : -TimeDelta;
if (llDelta > UNITS * 1000) {
DbgLog((LOG_TRACE, 0, TEXT("Bad Time Delta")));
//DebugBreak();
}
// We're going to calculate a "severity" for the time change. Max -1
// min 8. We'll then use this as the debug logging level for a
// debug log message.
const LONG usDelta = LONG(TimeDelta/10); // Delta in micro-secs
DWORD delta = abs(usDelta); // varying delta
// Severity == 8 - ceil(log<base 8>(abs( micro-secs delta)))
int Severity = 8;
while ( delta > 0 )
{
delta >>= 3; // div 8
Severity--;
}
// Sev == 0 => > 2 second delta!
DbgLog((LOG_TIMING, Severity < 0 ? 0 : Severity,
TEXT("Sev %2i: CSystemClock::SetTimeDelta(%8ld us) %lu -> %lu ms."),
Severity, usDelta, DWORD(ConvertToMilliseconds(m_rtPrivateTime)),
DWORD(ConvertToMilliseconds(TimeDelta+m_rtPrivateTime)) ));
// Don't want the DbgBreak to fire when running stress on debug-builds.
#ifdef BREAK_ON_SEVERE_TIME_DELTA
if (Severity < 0)
DbgBreakPoint(TEXT("SetTimeDelta > 16 seconds!"),
TEXT(__FILE__),__LINE__);
#endif
#endif
CAutoLock cObjectLock(this);
m_rtPrivateTime += TimeDelta;
// If time goes forwards, and we have advises, then we need to
// trigger the thread so that it can re-evaluate its wait time.
// Since we don't want the cost of the thread switches if the change
// is really small, only do it if clock goes forward by more than
// 0.5 millisecond. If the time goes backwards, the thread will
// wake up "early" (relativly speaking) and will re-evaluate at
// that time.
if ( TimeDelta > 5000 && m_pSchedule->GetAdviseCount() > 0 ) TriggerThread();
return NOERROR;
}
// Thread stuff
DWORD __stdcall CBaseReferenceClock::AdviseThreadFunction(__in LPVOID p)
{
return DWORD(reinterpret_cast<CBaseReferenceClock*>(p)->AdviseThread());
}
HRESULT CBaseReferenceClock::AdviseThread()
{
DWORD dwWait = INFINITE;
// The first thing we do is wait until something interesting happens
// (meaning a first advise or shutdown). This prevents us calling
// GetPrivateTime immediately which is goodness as that is a virtual
// routine and the derived class may not yet be constructed. (This
// thread is created in the base class constructor.)
while ( !m_bAbort )
{
// Wait for an interesting event to happen
DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait ));
WaitForSingleObject(m_pSchedule->GetEvent(), dwWait);
if (m_bAbort) break;
// There are several reasons why we need to work from the internal
// time, mainly to do with what happens when time goes backwards.
// Mainly, it stop us looping madly if an event is just about to
// expire when the clock goes backward (i.e. GetTime stop for a
// while).
const REFERENCE_TIME rtNow = GetPrivateTime();
DbgLog((LOG_TIMING, 3,
TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"),
ConvertToMilliseconds(rtNow) ));
// We must add in a millisecond, since this is the resolution of our
// WaitForSingleObject timer. Failure to do so will cause us to loop
// franticly for (approx) 1 a millisecond.
m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow );
LONGLONG llWait = m_rtNextAdvise - rtNow;
ASSERT( llWait > 0 );
llWait = ConvertToMilliseconds(llWait);
// DON'T replace this with a max!! (The type's of these things is VERY important)
dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait);
};
return NOERROR;
}
HRESULT CBaseReferenceClock::SetDefaultTimerResolution(
REFERENCE_TIME timerResolution // in 100ns
)
{
CAutoLock cObjectLock(this);
if( 0 == timerResolution ) {
if( m_TimerResolution ) {
timeEndPeriod( m_TimerResolution );
m_TimerResolution = 0;
}
} else {
TIMECAPS tc;
DWORD dwMinResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc)))
? tc.wPeriodMin
: 1;
DWORD dwResolution = max( dwMinResolution, DWORD(timerResolution / 10000) );
if( dwResolution != m_TimerResolution ) {
timeEndPeriod(m_TimerResolution);
m_TimerResolution = dwResolution;
timeBeginPeriod( m_TimerResolution );
}
}
return S_OK;
}
HRESULT CBaseReferenceClock::GetDefaultTimerResolution(
__out REFERENCE_TIME* pTimerResolution // in 100ns
)
{
if( !pTimerResolution ) {
return E_POINTER;
}
CAutoLock cObjectLock(this);
*pTimerResolution = m_TimerResolution * 10000;
return S_OK;
}

View File

@@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// File: SeekPT.h
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __seekpt_h__
#define __seekpt_h__
class CSeekingPassThru : public ISeekingPassThru, public CUnknown
{
public:
static CUnknown *CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
CSeekingPassThru(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
~CSeekingPassThru();
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
STDMETHODIMP Init(BOOL bSupportRendering, IPin *pPin);
private:
CPosPassThru *m_pPosPassThru;
};
#endif

View File

@@ -1,197 +0,0 @@
//------------------------------------------------------------------------------
// File: Streams.h
//
// Desc: DirectShow base classes - defines overall streams architecture.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __STREAMS__
#define __STREAMS__
#ifdef _MSC_VER
// disable some level-4 warnings, use #pragma warning(enable:###) to re-enable
#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter
#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated
#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated
#pragma warning(disable:4514) // warning C4514: "unreferenced inline function has been removed"
#if _MSC_VER>=1100
#define AM_NOVTABLE __declspec(novtable)
#else
#define AM_NOVTABLE
#endif
#endif // MSC_VER
// Because of differences between Visual C++ and older Microsoft SDKs,
// you may have defined _DEBUG without defining DEBUG. This logic
// ensures that both will be set if Visual C++ sets _DEBUG.
#ifdef _DEBUG
#ifndef DEBUG
#define DEBUG
#endif
#endif
#include <windows.h>
#include <windowsx.h>
#include <olectl.h>
#include <ddraw.h>
#include <mmsystem.h>
#ifndef NUMELMS
#if _WIN32_WINNT < 0x0600
#define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0]))
#else
#define NUMELMS(aa) ARRAYSIZE(aa)
#endif
#endif
///////////////////////////////////////////////////////////////////////////
// The following definitions come from the Platform SDK and are required if
// the applicaiton is being compiled with the headers from Visual C++ 6.0.
///////////////////////////////////////////////////////////////////////////
#ifndef InterlockedExchangePointer
#define InterlockedExchangePointer(Target, Value) \
(PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))
#endif
#ifndef _WAVEFORMATEXTENSIBLE_
#define _WAVEFORMATEXTENSIBLE_
typedef struct {
WAVEFORMATEX Format;
union {
WORD wValidBitsPerSample; /* bits of precision */
WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */
WORD wReserved; /* If neither applies, set to zero. */
} Samples;
DWORD dwChannelMask; /* which channels are */
/* present in stream */
GUID SubFormat;
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
#endif // !_WAVEFORMATEXTENSIBLE_
#if !defined(WAVE_FORMAT_EXTENSIBLE)
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
#endif // !defined(WAVE_FORMAT_EXTENSIBLE)
#ifndef GetWindowLongPtr
#define GetWindowLongPtrA GetWindowLongA
#define GetWindowLongPtrW GetWindowLongW
#ifdef UNICODE
#define GetWindowLongPtr GetWindowLongPtrW
#else
#define GetWindowLongPtr GetWindowLongPtrA
#endif // !UNICODE
#endif // !GetWindowLongPtr
#ifndef SetWindowLongPtr
#define SetWindowLongPtrA SetWindowLongA
#define SetWindowLongPtrW SetWindowLongW
#ifdef UNICODE
#define SetWindowLongPtr SetWindowLongPtrW
#else
#define SetWindowLongPtr SetWindowLongPtrA
#endif // !UNICODE
#endif // !SetWindowLongPtr
#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC (-4)
#endif
#ifndef GWLP_HINSTANCE
#define GWLP_HINSTANCE (-6)
#endif
#ifndef GWLP_HWNDPARENT
#define GWLP_HWNDPARENT (-8)
#endif
#ifndef GWLP_USERDATA
#define GWLP_USERDATA (-21)
#endif
#ifndef GWLP_ID
#define GWLP_ID (-12)
#endif
#ifndef DWLP_MSGRESULT
#define DWLP_MSGRESULT 0
#endif
#ifndef DWLP_DLGPROC
#define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT)
#endif
#ifndef DWLP_USER
#define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC)
#endif
#pragma warning(push)
#pragma warning(disable: 4312 4244)
// _GetWindowLongPtr
// Templated version of GetWindowLongPtr, to suppress spurious compiler warning.
template <class T>
T _GetWindowLongPtr(HWND hwnd, int nIndex)
{
return (T)GetWindowLongPtr(hwnd, nIndex);
}
// _SetWindowLongPtr
// Templated version of SetWindowLongPtr, to suppress spurious compiler warning.
template <class T>
LONG_PTR _SetWindowLongPtr(HWND hwnd, int nIndex, T p)
{
return SetWindowLongPtr(hwnd, nIndex, (LONG_PTR)p);
}
#pragma warning(pop)
///////////////////////////////////////////////////////////////////////////
// End Platform SDK definitions
///////////////////////////////////////////////////////////////////////////
#include <strmif.h> // Generated IDL header file for streams interfaces
#include <intsafe.h> // required by amvideo.h
#include <reftime.h> // Helper class for REFERENCE_TIME management
#include <wxdebug.h> // Debug support for logging and ASSERTs
#include <amvideo.h> // ActiveMovie video interfaces and definitions
//include amaudio.h explicitly if you need it. it requires the DX SDK.
//#include <amaudio.h> // ActiveMovie audio interfaces and definitions
#include <wxutil.h> // General helper classes for threads etc
#include <combase.h> // Base COM classes to support IUnknown
#include <measure.h> // Performance measurement
#include <comlite.h> // Light weight com function prototypes
#include <cache.h> // Simple cache container class
#include <wxlist.h> // Non MFC generic list class
#include <msgthrd.h> // CMsgThread
#include <mtype.h> // Helper class for managing media types
#include <fourcc.h> // conversions between FOURCCs and GUIDs
#include <control.h> // generated from control.odl
#include <ctlutil.h> // control interface utility classes
#include <evcode.h> // event code definitions
#include <amfilter.h> // Main streams architecture class hierachy
#include <transfrm.h> // Generic transform filter
#include <transip.h> // Generic transform-in-place filter
#include <uuids.h> // declaration of type GUIDs and well-known clsids
#include <source.h> // Generic source filter
#include <outputq.h> // Output pin queueing
#include <errors.h> // HRESULT status and error definitions
#include <renbase.h> // Base class for writing ActiveX renderers
#include <refclock.h> // Base clock class
#include <sysclock.h> // System clock
#include <pstream.h> // IPersistStream helper class
#include <vtrans.h> // Video Transform Filter base class
#include <amextra.h>
#include <strmctl.h> // IAMStreamControl support
#include <edevdefs.h> // External device control interface defines
#include <audevcod.h> // audio filter device error event codes
#else
#ifdef DEBUG
#pragma message("STREAMS.H included TWICE")
#endif
#endif // __STREAMS__

View File

@@ -1,39 +0,0 @@
//------------------------------------------------------------------------------
// File: SysClock.h
//
// Desc: DirectShow base classes - defines a system clock implementation of
// IReferenceClock.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __SYSTEMCLOCK__
#define __SYSTEMCLOCK__
//
// Base clock. Uses timeGetTime ONLY
// Uses most of the code in the base reference clock.
// Provides GetTime
//
class CSystemClock : public CBaseReferenceClock, public IAMClockAdjust, public IPersist
{
public:
// We must be able to create an instance of ourselves
static CUnknown * WINAPI CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
CSystemClock(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr);
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
// Yield up our class id so that we can be persisted
// Implement required Ipersist method
STDMETHODIMP GetClassID(__out CLSID *pClsID);
// IAMClockAdjust methods
STDMETHODIMP SetClockDelta(REFERENCE_TIME rtDelta);
}; //CSystemClock
#endif /* __SYSTEMCLOCK__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,767 +0,0 @@
//------------------------------------------------------------------------------
// File: WXUtil.cpp
//
// Desc: DirectShow base classes - implements helper classes for building
// multimedia filters.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
// --- CAMEvent -----------------------
CAMEvent::CAMEvent(BOOL fManualReset, __inout_opt HRESULT *phr)
{
m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);
if (NULL == m_hEvent) {
if (NULL != phr && SUCCEEDED(*phr)) {
*phr = E_OUTOFMEMORY;
}
}
}
CAMEvent::CAMEvent(__inout_opt HRESULT *phr)
{
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == m_hEvent) {
if (NULL != phr && SUCCEEDED(*phr)) {
*phr = E_OUTOFMEMORY;
}
}
}
CAMEvent::~CAMEvent()
{
if (m_hEvent) {
EXECUTE_ASSERT(CloseHandle(m_hEvent));
}
}
// --- CAMMsgEvent -----------------------
// One routine. The rest is handled in CAMEvent
CAMMsgEvent::CAMMsgEvent(__inout_opt HRESULT *phr) : CAMEvent(FALSE, phr)
{
}
BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout)
{
// wait for the event to be signalled, or for the
// timeout (in MS) to expire. allow SENT messages
// to be processed while we wait
DWORD dwWait;
DWORD dwStartTime;
// set the waiting period.
DWORD dwWaitTime = dwTimeout;
// the timeout will eventually run down as we iterate
// processing messages. grab the start time so that
// we can calculate elapsed times.
if (dwWaitTime != INFINITE) {
dwStartTime = timeGetTime();
}
do {
dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE);
if (dwWait == WAIT_OBJECT_0 + 1) {
MSG Message;
PeekMessage(&Message,NULL,0,0,PM_NOREMOVE);
// If we have an explicit length of time to wait calculate
// the next wake up point - which might be now.
// If dwTimeout is INFINITE, it stays INFINITE
if (dwWaitTime != INFINITE) {
DWORD dwElapsed = timeGetTime()-dwStartTime;
dwWaitTime =
(dwElapsed >= dwTimeout)
? 0 // wake up with WAIT_TIMEOUT
: dwTimeout-dwElapsed;
}
}
} while (dwWait == WAIT_OBJECT_0 + 1);
// return TRUE if we woke on the event handle,
// FALSE if we timed out.
return (dwWait == WAIT_OBJECT_0);
}
// --- CAMThread ----------------------
CAMThread::CAMThread(__inout_opt HRESULT *phr)
: m_EventSend(TRUE, phr), // must be manual-reset for CheckRequest()
m_EventComplete(FALSE, phr)
{
m_hThread = NULL;
}
CAMThread::~CAMThread() {
Close();
}
// when the thread starts, it calls this function. We unwrap the 'this'
//pointer and call ThreadProc.
DWORD WINAPI
CAMThread::InitialThreadProc(__inout LPVOID pv)
{
HRESULT hrCoInit = CAMThread::CoInitializeHelper();
if(FAILED(hrCoInit)) {
DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed.")));
}
CAMThread * pThread = (CAMThread *) pv;
HRESULT hr = pThread->ThreadProc();
if(SUCCEEDED(hrCoInit)) {
CoUninitialize();
}
return hr;
}
BOOL
CAMThread::Create()
{
DWORD threadid;
CAutoLock lock(&m_AccessLock);
if (ThreadExists()) {
return FALSE;
}
m_hThread = CreateThread(
NULL,
0,
CAMThread::InitialThreadProc,
this,
0,
&threadid);
if (!m_hThread) {
return FALSE;
}
return TRUE;
}
DWORD
CAMThread::CallWorker(DWORD dwParam)
{
// lock access to the worker thread for scope of this object
CAutoLock lock(&m_AccessLock);
if (!ThreadExists()) {
return (DWORD) E_FAIL;
}
// set the parameter
m_dwParam = dwParam;
// signal the worker thread
m_EventSend.Set();
// wait for the completion to be signalled
m_EventComplete.Wait();
// done - this is the thread's return value
return m_dwReturnVal;
}
// Wait for a request from the client
DWORD
CAMThread::GetRequest()
{
m_EventSend.Wait();
return m_dwParam;
}
// is there a request?
BOOL
CAMThread::CheckRequest(__out_opt DWORD * pParam)
{
if (!m_EventSend.Check()) {
return FALSE;
} else {
if (pParam) {
*pParam = m_dwParam;
}
return TRUE;
}
}
// reply to the request
void
CAMThread::Reply(DWORD dw)
{
m_dwReturnVal = dw;
// The request is now complete so CheckRequest should fail from
// now on
//
// This event should be reset BEFORE we signal the client or
// the client may Set it before we reset it and we'll then
// reset it (!)
m_EventSend.Reset();
// Tell the client we're finished
m_EventComplete.Set();
}
HRESULT CAMThread::CoInitializeHelper()
{
// call CoInitializeEx and tell OLE not to create a window (this
// thread probably won't dispatch messages and will hang on
// broadcast msgs o/w).
//
// If CoInitEx is not available, threads that don't call CoCreate
// aren't affected. Threads that do will have to handle the
// failure. Perhaps we should fall back to CoInitialize and risk
// hanging?
//
// older versions of ole32.dll don't have CoInitializeEx
HRESULT hr = E_FAIL;
HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll"));
if(hOle)
{
typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)(
LPVOID pvReserved, DWORD dwCoInit);
PCoInitializeEx pCoInitializeEx =
(PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx"));
if(pCoInitializeEx)
{
hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE );
}
}
else
{
// caller must load ole32.dll
DbgBreak("couldn't locate ole32.dll");
}
return hr;
}
// destructor for CMsgThread - cleans up any messages left in the
// queue when the thread exited
CMsgThread::~CMsgThread()
{
if (m_hThread != NULL) {
WaitForSingleObject(m_hThread, INFINITE);
EXECUTE_ASSERT(CloseHandle(m_hThread));
}
POSITION pos = m_ThreadQueue.GetHeadPosition();
while (pos) {
CMsg * pMsg = m_ThreadQueue.GetNext(pos);
delete pMsg;
}
m_ThreadQueue.RemoveAll();
if (m_hSem != NULL) {
EXECUTE_ASSERT(CloseHandle(m_hSem));
}
}
BOOL
CMsgThread::CreateThread(
)
{
m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
if (m_hSem == NULL) {
return FALSE;
}
m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc,
(LPVOID)this, 0, &m_ThreadId);
return m_hThread != NULL;
}
// This is the threads message pump. Here we get and dispatch messages to
// clients thread proc until the client refuses to process a message.
// The client returns a non-zero value to stop the message pump, this
// value becomes the threads exit code.
DWORD WINAPI
CMsgThread::DefaultThreadProc(
__inout LPVOID lpParam
)
{
CMsgThread *lpThis = (CMsgThread *)lpParam;
CMsg msg;
LRESULT lResult;
// !!!
CoInitialize(NULL);
// allow a derived class to handle thread startup
lpThis->OnThreadInit();
do {
lpThis->GetThreadMsg(&msg);
lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags,
msg.lpParam, msg.pEvent);
} while (lResult == 0L);
// !!!
CoUninitialize();
return (DWORD)lResult;
}
// Block until the next message is placed on the list m_ThreadQueue.
// copies the message to the message pointed to by *pmsg
void
CMsgThread::GetThreadMsg(__out CMsg *msg)
{
CMsg * pmsg = NULL;
// keep trying until a message appears
while (TRUE) {
{
CAutoLock lck(&m_Lock);
pmsg = m_ThreadQueue.RemoveHead();
if (pmsg == NULL) {
m_lWaiting++;
} else {
break;
}
}
// the semaphore will be signalled when it is non-empty
WaitForSingleObject(m_hSem, INFINITE);
}
// copy fields to caller's CMsg
*msg = *pmsg;
// this CMsg was allocated by the 'new' in PutThreadMsg
delete pmsg;
}
// Helper function - convert int to WSTR
void WINAPI IntToWstr(int i, __out_ecount(12) LPWSTR wstr)
{
#ifdef UNICODE
if (FAILED(StringCchPrintf(wstr, 12, L"%d", i))) {
wstr[0] = 0;
}
#else
TCHAR temp[12];
if (FAILED(StringCchPrintf(temp, NUMELMS(temp), "%d", i))) {
wstr[0] = 0;
} else {
MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 12);
}
#endif
} // IntToWstr
#define MEMORY_ALIGNMENT 4
#define MEMORY_ALIGNMENT_LOG2 2
#define MEMORY_ALIGNMENT_MASK MEMORY_ALIGNMENT - 1
void * __stdcall memmoveInternal(void * dst, const void * src, size_t count)
{
void * ret = dst;
#ifdef _X86_
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
_asm {
mov esi,src
mov edi,dst
mov ecx,count
cld
mov edx,ecx
and edx,MEMORY_ALIGNMENT_MASK
shr ecx,MEMORY_ALIGNMENT_LOG2
rep movsd
or ecx,edx
jz memmove_done
rep movsb
memmove_done:
}
}
else {
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
_asm {
mov esi,src
mov edi,dst
mov ecx,count
std
add esi,ecx
add edi,ecx
dec esi
dec edi
rep movsb
cld
}
}
#else
MoveMemory(dst, src, count);
#endif
return ret;
}
HRESULT AMSafeMemMoveOffset(
__in_bcount(dst_size) void * dst,
__in size_t dst_size,
__in DWORD cb_dst_offset,
__in_bcount(src_size) const void * src,
__in size_t src_size,
__in DWORD cb_src_offset,
__in size_t count)
{
// prevent read overruns
if( count + cb_src_offset < count || // prevent integer overflow
count + cb_src_offset > src_size) // prevent read overrun
{
return E_INVALIDARG;
}
// prevent write overruns
if( count + cb_dst_offset < count || // prevent integer overflow
count + cb_dst_offset > dst_size) // prevent write overrun
{
return E_INVALIDARG;
}
memmoveInternal( (BYTE *)dst+cb_dst_offset, (BYTE *)src+cb_src_offset, count);
return S_OK;
}
#ifdef DEBUG
/******************************Public*Routine******************************\
* Debug CCritSec helpers
*
* We provide debug versions of the Constructor, destructor, Lock and Unlock
* routines. The debug code tracks who owns each critical section by
* maintaining a depth count.
*
* History:
*
\**************************************************************************/
CCritSec::CCritSec()
{
InitializeCriticalSection(&m_CritSec);
m_currentOwner = m_lockCount = 0;
m_fTrace = FALSE;
}
CCritSec::~CCritSec()
{
DeleteCriticalSection(&m_CritSec);
}
void CCritSec::Lock()
{
UINT tracelevel=3;
DWORD us = GetCurrentThreadId();
DWORD currentOwner = m_currentOwner;
if (currentOwner && (currentOwner != us)) {
// already owned, but not by us
if (m_fTrace) {
DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"),
GetCurrentThreadId(), &m_CritSec, currentOwner));
tracelevel=2;
// if we saw the message about waiting for the critical
// section we ensure we see the message when we get the
// critical section
}
}
EnterCriticalSection(&m_CritSec);
if (0 == m_lockCount++) {
// we now own it for the first time. Set owner information
m_currentOwner = us;
if (m_fTrace) {
DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec));
}
}
}
void CCritSec::Unlock() {
if (0 == --m_lockCount) {
// about to be unowned
if (m_fTrace) {
DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec));
}
m_currentOwner = 0;
}
LeaveCriticalSection(&m_CritSec);
}
void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace)
{
pcCrit->m_fTrace = fTrace;
}
BOOL WINAPI CritCheckIn(CCritSec * pcCrit)
{
return (GetCurrentThreadId() == pcCrit->m_currentOwner);
}
BOOL WINAPI CritCheckIn(const CCritSec * pcCrit)
{
return (GetCurrentThreadId() == pcCrit->m_currentOwner);
}
BOOL WINAPI CritCheckOut(CCritSec * pcCrit)
{
return (GetCurrentThreadId() != pcCrit->m_currentOwner);
}
BOOL WINAPI CritCheckOut(const CCritSec * pcCrit)
{
return (GetCurrentThreadId() != pcCrit->m_currentOwner);
}
#endif
STDAPI WriteBSTR(__deref_out BSTR *pstrDest, LPCWSTR szSrc)
{
*pstrDest = SysAllocString( szSrc );
if( !(*pstrDest) ) return E_OUTOFMEMORY;
return NOERROR;
}
STDAPI FreeBSTR(__deref_in BSTR* pstr)
{
if( (PVOID)*pstr == NULL ) return S_FALSE;
SysFreeString( *pstr );
return NOERROR;
}
// Return a wide string - allocating memory for it
// Returns:
// S_OK - no error
// E_POINTER - ppszReturn == NULL
// E_OUTOFMEMORY - can't allocate memory for returned string
STDAPI AMGetWideString(LPCWSTR psz, __deref_out LPWSTR *ppszReturn)
{
CheckPointer(ppszReturn, E_POINTER);
ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR));
*ppszReturn = NULL;
size_t nameLen;
HRESULT hr = StringCbLengthW(psz, 100000, &nameLen);
if (FAILED(hr)) {
return hr;
}
*ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen + sizeof(WCHAR));
if (*ppszReturn == NULL) {
return E_OUTOFMEMORY;
}
CopyMemory(*ppszReturn, psz, nameLen + sizeof(WCHAR));
return NOERROR;
}
// Waits for the HANDLE hObject. While waiting messages sent
// to windows on our thread by SendMessage will be processed.
// Using this function to do waits and mutual exclusion
// avoids some deadlocks in objects with windows.
// Return codes are the same as for WaitForSingleObject
DWORD WINAPI WaitDispatchingMessages(
HANDLE hObject,
DWORD dwWait,
HWND hwnd,
UINT uMsg,
HANDLE hEvent)
{
BOOL bPeeked = FALSE;
DWORD dwResult;
DWORD dwStart;
DWORD dwThreadPriority;
static UINT uMsgId = 0;
HANDLE hObjects[2] = { hObject, hEvent };
if (dwWait != INFINITE && dwWait != 0) {
dwStart = GetTickCount();
}
for (; ; ) {
DWORD nCount = NULL != hEvent ? 2 : 1;
// Minimize the chance of actually dispatching any messages
// by seeing if we can lock immediately.
dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0);
if (dwResult < WAIT_OBJECT_0 + nCount) {
break;
}
DWORD dwTimeOut = dwWait;
if (dwTimeOut > 10) {
dwTimeOut = 10;
}
dwResult = MsgWaitForMultipleObjects(
nCount,
hObjects,
FALSE,
dwTimeOut,
hwnd == NULL ? QS_SENDMESSAGE :
QS_SENDMESSAGE + QS_POSTMESSAGE);
if (dwResult == WAIT_OBJECT_0 + nCount ||
dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) {
MSG msg;
if (hwnd != NULL) {
while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) {
DispatchMessage(&msg);
}
}
// Do this anyway - the previous peek doesn't flush out the
// messages
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
if (dwWait != INFINITE && dwWait != 0) {
DWORD dwNow = GetTickCount();
// Working with differences handles wrap-around
DWORD dwDiff = dwNow - dwStart;
if (dwDiff > dwWait) {
dwWait = 0;
} else {
dwWait -= dwDiff;
}
dwStart = dwNow;
}
if (!bPeeked) {
// Raise our priority to prevent our message queue
// building up
dwThreadPriority = GetThreadPriority(GetCurrentThread());
if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) {
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
}
bPeeked = TRUE;
}
} else {
break;
}
}
if (bPeeked) {
SetThreadPriority(GetCurrentThread(), dwThreadPriority);
if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
if (uMsgId == 0) {
uMsgId = RegisterWindowMessage(TEXT("AMUnblock"));
}
if (uMsgId != 0) {
MSG msg;
// Remove old ones
while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) {
}
}
PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0);
}
}
return dwResult;
}
HRESULT AmGetLastErrorToHResult()
{
DWORD dwLastError = GetLastError();
if(dwLastError != 0)
{
return HRESULT_FROM_WIN32(dwLastError);
}
else
{
return E_FAIL;
}
}
IUnknown* QzAtlComPtrAssign(__deref_inout_opt IUnknown** pp, __in_opt IUnknown* lp)
{
if (lp != NULL)
lp->AddRef();
if (*pp)
(*pp)->Release();
*pp = lp;
return lp;
}
/******************************************************************************
CompatibleTimeSetEvent
CompatibleTimeSetEvent() sets the TIME_KILL_SYNCHRONOUS flag before calling
timeSetEvent() if the current operating system supports it. TIME_KILL_SYNCHRONOUS
is supported on Windows XP and later operating systems.
Parameters:
- The same parameters as timeSetEvent(). See timeSetEvent()'s documentation in
the Platform SDK for more information.
Return Value:
- The same return value as timeSetEvent(). See timeSetEvent()'s documentation in
the Platform SDK for more information.
******************************************************************************/
MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, __in LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent )
{
#if WINVER >= 0x0501
{
static bool fCheckedVersion = false;
static bool fTimeKillSynchronousFlagAvailable = false;
if( !fCheckedVersion ) {
fTimeKillSynchronousFlagAvailable = TimeKillSynchronousFlagAvailable();
fCheckedVersion = true;
}
if( fTimeKillSynchronousFlagAvailable ) {
fuEvent = fuEvent | TIME_KILL_SYNCHRONOUS;
}
}
#endif // WINVER >= 0x0501
return timeSetEvent( uDelay, uResolution, lpTimeProc, dwUser, fuEvent );
}
bool TimeKillSynchronousFlagAvailable( void )
{
OSVERSIONINFO osverinfo;
osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
if( GetVersionEx( &osverinfo ) ) {
// Windows XP's major version is 5 and its' minor version is 1.
// timeSetEvent() started supporting the TIME_KILL_SYNCHRONOUS flag
// in Windows XP.
if( (osverinfo.dwMajorVersion > 5) ||
( (osverinfo.dwMajorVersion == 5) && (osverinfo.dwMinorVersion >= 1) ) ) {
return true;
}
}
return false;
}

55
3rdparty/bzip2/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,55 @@
# bzip2 library
# library name
set(Output pcsx2_bzip2)
set(CommonFlags
-march=athlon-xp
-march=prescott
)
set(OptimizationFlags
-Os
-W
)
# Debug - Build
if(CMAKE_BUILD_TYPE STREQUAL Debug)
# add defines
add_definitions(${CommonFlags} -g)
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
# Devel - Build
if(CMAKE_BUILD_TYPE STREQUAL Devel)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags} -g)
endif(CMAKE_BUILD_TYPE STREQUAL Devel)
# Release - Build
if(CMAKE_BUILD_TYPE STREQUAL Release)
# add defines
add_definitions(${CommonFlags} ${OptimizationFlags})
endif(CMAKE_BUILD_TYPE STREQUAL Release)
# variable with all sources of this library
set(bzip2Sources
blocksort.c
bzlib.c
compress.c
crctable.c
decompress.c
huffman.c
randtable.c)
# variable with all headers of this library
set(bzip2Headers
bzlib.h
bzlib_private.h)
# add library
add_library(${Output} STATIC ${bzip2Sources} ${bzip2Headers})
# User flags options
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
endif(NOT USER_CMAKE_LD_FLAGS STREQUAL "")

43
3rdparty/bzip2/LICENSE vendored Normal file
View File

@@ -0,0 +1,43 @@
--------------------------------------------------------------------------
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2006 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, Cambridge, UK.
jseward@bzip.org
bzip2/libbzip2 version 1.0.4 of 20 December 2006
--------------------------------------------------------------------------

205
3rdparty/bzip2/README vendored Normal file
View File

@@ -0,0 +1,205 @@
This is the README for bzip2/libzip2.
This version is fully compatible with the previous public releases.
------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------
Complete documentation is available in Postscript form (manual.ps),
PDF (manual.pdf) or html (manual.html). A plain-text version of the
manual page is available as bzip2.txt.
HOW TO BUILD -- UNIX
Type 'make'. This builds the library libbz2.a and then the programs
bzip2 and bzip2recover. Six self-tests are run. If the self-tests
complete ok, carry on to installation:
To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
/usr/local/include, type
make install
To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
make install PREFIX=/xxx/yyy
If you are (justifiably) paranoid and want to see what 'make install'
is going to do, you can first do
make -n install or
make -n install PREFIX=/xxx/yyy respectively.
The -n instructs make to show the commands it would execute, but not
actually execute them.
HOW TO BUILD -- UNIX, shared library libbz2.so.
Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims
that it works for any other platform, though I suspect it probably
will work for most platforms employing both ELF and gcc.
bzip2-shared, a client of the shared library, is also built, but not
self-tested. So I suggest you also build using the normal Makefile,
since that conducts a self-test. A second reason to prefer the
version statically linked to the library is that, on x86 platforms,
building shared objects makes a valuable register (%ebx) unavailable
to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
Important note for people upgrading .so's from 0.9.0/0.9.5 to version
1.0.X. All the functions in the library have been renamed, from (eg)
bzCompress to BZ2_bzCompress, to avoid namespace pollution.
Unfortunately this means that the libbz2.so created by
Makefile-libbz2_so will not work with any program which used an older
version of the library. I do encourage library clients to make the
effort to upgrade to use version 1.0, since it is both faster and more
robust than previous versions.
HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
It's difficult for me to support compilation on all these platforms.
My approach is to collect binaries for these platforms, and put them
on the master web site (http://www.bzip.org). Look there. However
(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
unmodified with MS Visual C. If you have difficulties building, you
might want to read README.COMPILATION.PROBLEMS.
At least using MS Visual C++ 6, you can build from the unmodified
sources by issuing, in a command shell:
nmake -f makefile.msc
(you may need to first run the MSVC-provided script VCVARS32.BAT
so as to set up paths to the MSVC tools correctly).
VALIDATION
Correct operation, in the sense that a compressed file can always be
decompressed to reproduce the original, is obviously of paramount
importance. To validate bzip2, I used a modified version of Mark
Nelson's churn program. Churn is an automated test driver which
recursively traverses a directory structure, using bzip2 to compress
and then decompress each file it encounters, and checking that the
decompressed data is the same as the original.
Please read and be aware of the following:
WARNING:
This program and library (attempts to) compress data by
performing several non-trivial transformations on it.
Unless you are 100% familiar with *all* the algorithms
contained herein, and with the consequences of modifying them,
you should NOT meddle with the compression or decompression
machinery. Incorrect changes can and very likely *will*
lead to disastrous loss of data.
DISCLAIMER:
I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
Every compression of a file implies an assumption that the
compressed file can be decompressed to reproduce the original.
Great efforts in design, coding and testing have been made to
ensure that this program works correctly. However, the complexity
of the algorithms, and, in particular, the presence of various
special cases in the code which occur with very low but non-zero
probability make it impossible to rule out the possibility of bugs
remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS
PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
That is not to say this program is inherently unreliable.
Indeed, I very much hope the opposite is true. bzip2/libbzip2
has been carefully constructed and extensively tested.
PATENTS:
To the best of my knowledge, bzip2/libbzip2 does not use any
patented algorithms. However, I do not have the resources
to carry out a patent search. Therefore I cannot give any
guarantee of the above statement.
WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
* Approx 10% faster compression, 30% faster decompression
* -t (test mode) is a lot quicker
* Can decompress concatenated compressed files
* Programming interface, so programs can directly read/write .bz2 files
* Less restrictive (BSD-style) licensing
* Flag handling more compatible with GNU gzip
* Much more documentation, i.e., a proper user manual
* Hopefully, improved portability (at least of the library)
WHAT'S NEW IN 0.9.5 ?
* Compression speed is much less sensitive to the input
data than in previous versions. Specifically, the very
slow performance caused by repetitive data is fixed.
* Many small improvements in file and flag handling.
* A Y2K statement.
WHAT'S NEW IN 1.0.0 ?
See the CHANGES file.
WHAT'S NEW IN 1.0.2 ?
See the CHANGES file.
WHAT'S NEW IN 1.0.3 ?
See the CHANGES file.
WHAT'S NEW IN 1.0.4 ?
See the CHANGES file.
I hope you find bzip2 useful. Feel free to contact me at
jseward@bzip.org
if you have any suggestions or queries. Many people mailed me with
comments, suggestions and patches after the releases of bzip-0.15,
bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
feedback. I thank you for your comments.
bzip2's "home" is http://www.bzip.org/
Julian Seward
jseward@bzip.org
Cambridge, UK.
18 July 1996 (version 0.15)
25 August 1996 (version 0.21)
7 August 1997 (bzip2, version 0.1)
29 August 1997 (bzip2, version 0.1pl2)
23 August 1998 (bzip2, version 0.9.0)
8 June 1999 (bzip2, version 0.9.5)
4 Sept 1999 (bzip2, version 0.9.5d)
5 May 2000 (bzip2, version 1.0pre8)
30 December 2001 (bzip2, version 1.0.2pre1)
15 February 2005 (bzip2, version 1.0.3)
20 December 2006 (bzip2, version 1.0.4)

1094
3rdparty/bzip2/blocksort.c vendored Normal file

File diff suppressed because it is too large Load Diff

87
3rdparty/bzip2/bzip2.cbp vendored Normal file
View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="bzip2" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="../../deps/debug/libbzip2" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/debug" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-g" />
<Add option="-O0" />
</Compiler>
</Target>
<Target title="Devel">
<Option output="../../deps/devel/libbzip2" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/devel" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-O1" />
<Add option="-W" />
<Add option="-g" />
<Add option="-DNDEBUG" />
</Compiler>
</Target>
<Target title="Release">
<Option output="../../deps/release/libbzip2" prefix_auto="1" extension_auto="1" />
<Option working_dir="" />
<Option object_output="./.objs/release" />
<Option type="2" />
<Option compiler="gcc" />
<Option createDefFile="1" />
<Compiler>
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
<Add option="-W" />
<Add option="-DNDEBUG" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-march=athlon-xp" />
<Add option="-march=prescott" />
</Compiler>
<Unit filename="blocksort.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="bzlib.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="bzlib.h" />
<Unit filename="bzlib_private.h" />
<Unit filename="compress.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="crctable.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="decompress.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="huffman.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="randtable.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<envvars />
<code_completion />
<lib_finder disable_auto="1" />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

231
3rdparty/bzip2/bzip2.vcproj vendored Normal file
View File

@@ -0,0 +1,231 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="bzip2"
ProjectGUID="{F4EB4AB2-C595-4B05-8BC0-059024BC796C}"
RootNamespace="bzip2"
TargetFrameworkVersion="0"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Devel|Win32"
ConfigurationType="4"
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\blocksort.c"
>
</File>
<File
RelativePath=".\bzlib.c"
>
</File>
<File
RelativePath=".\compress.c"
>
</File>
<File
RelativePath=".\crctable.c"
>
</File>
<File
RelativePath=".\decompress.c"
>
</File>
<File
RelativePath=".\huffman.c"
>
</File>
<File
RelativePath=".\randtable.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\bzlib.h"
>
</File>
<File
RelativePath=".\bzlib_private.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

92
3rdparty/bzip2/bzip2.vcxproj vendored Normal file
View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F4EB4AB2-C595-4B05-8BC0-059024BC796C}</ProjectGuid>
<RootNamespace>bzip2</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="blocksort.c" />
<ClCompile Include="bzlib.c" />
<ClCompile Include="compress.c" />
<ClCompile Include="crctable.c" />
<ClCompile Include="decompress.c" />
<ClCompile Include="huffman.c" />
<ClCompile Include="randtable.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h" />
<ClInclude Include="bzlib_private.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

44
3rdparty/bzip2/bzip2.vcxproj.filters vendored Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="blocksort.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bzlib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="compress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="crctable.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decompress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="huffman.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="randtable.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bzlib_private.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

96
3rdparty/bzip2/bzip2_vs2012.vcxproj vendored Normal file
View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F4EB4AB2-C595-4B05-8BC0-059024BC796C}</ProjectGuid>
<RootNamespace>bzip2</RootNamespace>
<ProjectName>bzip2</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v110_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="blocksort.c" />
<ClCompile Include="bzlib.c" />
<ClCompile Include="compress.c" />
<ClCompile Include="crctable.c" />
<ClCompile Include="decompress.c" />
<ClCompile Include="huffman.c" />
<ClCompile Include="randtable.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h" />
<ClInclude Include="bzlib_private.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="blocksort.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bzlib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="compress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="crctable.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decompress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="huffman.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="randtable.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bzlib_private.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

96
3rdparty/bzip2/bzip2_vs2013.vcxproj vendored Normal file
View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Devel|Win32">
<Configuration>Devel</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F4EB4AB2-C595-4B05-8BC0-059024BC796C}</ProjectGuid>
<RootNamespace>bzip2</RootNamespace>
<ProjectName>bzip2</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">$(ProjectName)-dev</TargetName>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="blocksort.c" />
<ClCompile Include="bzlib.c" />
<ClCompile Include="compress.c" />
<ClCompile Include="crctable.c" />
<ClCompile Include="decompress.c" />
<ClCompile Include="huffman.c" />
<ClCompile Include="randtable.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h" />
<ClInclude Include="bzlib_private.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="blocksort.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bzlib.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="compress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="crctable.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decompress.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="huffman.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="randtable.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="bzlib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bzlib_private.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

1571
3rdparty/bzip2/bzlib.c vendored Normal file

File diff suppressed because it is too large Load Diff

282
3rdparty/bzip2/bzlib.h vendored Normal file
View File

@@ -0,0 +1,282 @@
/*-------------------------------------------------------------*/
/*--- Public header file for the library. ---*/
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_H
#define _BZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#define BZ_RUN 0
#define BZ_FLUSH 1
#define BZ_FINISH 2
#define BZ_OK 0
#define BZ_RUN_OK 1
#define BZ_FLUSH_OK 2
#define BZ_FINISH_OK 3
#define BZ_STREAM_END 4
#define BZ_SEQUENCE_ERROR (-1)
#define BZ_PARAM_ERROR (-2)
#define BZ_MEM_ERROR (-3)
#define BZ_DATA_ERROR (-4)
#define BZ_DATA_ERROR_MAGIC (-5)
#define BZ_IO_ERROR (-6)
#define BZ_UNEXPECTED_EOF (-7)
#define BZ_OUTBUFF_FULL (-8)
#define BZ_CONFIG_ERROR (-9)
typedef
struct {
char *next_in;
unsigned int avail_in;
unsigned int total_in_lo32;
unsigned int total_in_hi32;
char *next_out;
unsigned int avail_out;
unsigned int total_out_lo32;
unsigned int total_out_hi32;
void *state;
void *(*bzalloc)(void *,int,int);
void (*bzfree)(void *,void *);
void *opaque;
}
bz_stream;
#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif
#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif
#ifdef _WIN32
# include <windows.h>
# ifdef small
/* windows.h define small to char */
# undef small
# endif
# ifdef BZ_EXPORT
# define BZ_API(func) WINAPI func
# define BZ_EXTERN extern
# else
/* import windows dll dynamically */
# define BZ_API(func) (WINAPI * func)
# define BZ_EXTERN
# endif
#else
# define BZ_API(func) func
# define BZ_EXTERN extern
#endif
/*-- Core (low-level) library functions --*/
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
bz_stream* strm,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
bz_stream* strm,
int action
);
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
bz_stream *strm,
int verbosity,
int small
);
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
bz_stream *strm
);
/*-- High(er) level library functions --*/
#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000
typedef void BZFILE;
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused
);
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
int* bzerror,
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
int* bzerror,
BZFILE* b,
void** unused,
int* nUnused
);
BZ_EXTERN int BZ_API(BZ2_bzRead) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in_lo32,
unsigned int* nbytes_in_hi32,
unsigned int* nbytes_out_lo32,
unsigned int* nbytes_out_hi32
);
#endif
/*-- Utility functions --*/
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity
);
/*--
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
void
);
#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
const char *path,
const char *mode
);
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
int fd,
const char *mode
);
BZ_EXTERN int BZ_API(BZ2_bzread) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzflush) (
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzclose) (
BZFILE* b
);
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
BZFILE *b,
int *errnum
);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.h ---*/
/*-------------------------------------------------------------*/

503
3rdparty/bzip2/bzlib_private.h vendored Normal file
View File

@@ -0,0 +1,503 @@
/*-------------------------------------------------------------*/
/*--- Private header file for the library. ---*/
/*--- bzlib_private.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#ifndef _BZLIB_PRIVATE_H
#define _BZLIB_PRIVATE_H
#include <stdlib.h>
#ifndef BZ_NO_STDIO
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#endif
#include "bzlib.h"
/*-- General stuff. --*/
#define BZ_VERSION "1.0.4, 20-Dec-2006"
typedef char Char;
typedef unsigned char Bool;
typedef unsigned char UChar;
typedef int Int32;
typedef unsigned int UInt32;
typedef short Int16;
typedef unsigned short UInt16;
#define True ((Bool)1)
#define False ((Bool)0)
#ifndef __GNUC__
#define __inline__ /* */
#endif
#ifndef BZ_NO_STDIO
extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
#if BZ_DEBUG
#define AssertD(cond,msg) \
{ if (!(cond)) { \
fprintf ( stderr, \
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
exit(1); \
}}
#else
#define AssertD(cond,msg) /* */
#endif
#define VPrintf0(zf) \
fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
fprintf(stderr,zf,za1)
#define VPrintf2(zf,za1,za2) \
fprintf(stderr,zf,za1,za2)
#define VPrintf3(zf,za1,za2,za3) \
fprintf(stderr,zf,za1,za2,za3)
#define VPrintf4(zf,za1,za2,za3,za4) \
fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
fprintf(stderr,zf,za1,za2,za3,za4,za5)
#else
extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) bz_internal_error ( errcode ); }
#define AssertD(cond,msg) do { } while (0)
#define VPrintf0(zf) do { } while (0)
#define VPrintf1(zf,za1) do { } while (0)
#define VPrintf2(zf,za1,za2) do { } while (0)
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
#endif
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
/*-- Header bytes. --*/
#define BZ_HDR_B 0x42 /* 'B' */
#define BZ_HDR_Z 0x5a /* 'Z' */
#define BZ_HDR_h 0x68 /* 'h' */
#define BZ_HDR_0 0x30 /* '0' */
/*-- Constants for the back end. --*/
#define BZ_MAX_ALPHA_SIZE 258
#define BZ_MAX_CODE_LEN 23
#define BZ_RUNA 0
#define BZ_RUNB 1
#define BZ_N_GROUPS 6
#define BZ_G_SIZE 50
#define BZ_N_ITERS 4
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
/*-- Stuff for randomising repetitive blocks. --*/
extern Int32 BZ2_rNums[512];
#define BZ_RAND_DECLS \
Int32 rNToGo; \
Int32 rTPos \
#define BZ_RAND_INIT_MASK \
s->rNToGo = 0; \
s->rTPos = 0 \
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
#define BZ_RAND_UPD_MASK \
if (s->rNToGo == 0) { \
s->rNToGo = BZ2_rNums[s->rTPos]; \
s->rTPos++; \
if (s->rTPos == 512) s->rTPos = 0; \
} \
s->rNToGo--;
/*-- Stuff for doing CRCs. --*/
extern UInt32 BZ2_crc32Table[256];
#define BZ_INITIALISE_CRC(crcVar) \
{ \
crcVar = 0xffffffffL; \
}
#define BZ_FINALISE_CRC(crcVar) \
{ \
crcVar = ~(crcVar); \
}
#define BZ_UPDATE_CRC(crcVar,cha) \
{ \
crcVar = (crcVar << 8) ^ \
BZ2_crc32Table[(crcVar >> 24) ^ \
((UChar)cha)]; \
}
/*-- States and modes for compression. --*/
#define BZ_M_IDLE 1
#define BZ_M_RUNNING 2
#define BZ_M_FLUSHING 3
#define BZ_M_FINISHING 4
#define BZ_S_OUTPUT 1
#define BZ_S_INPUT 2
#define BZ_N_RADIX 2
#define BZ_N_QSORT 12
#define BZ_N_SHELL 18
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
/*-- Structure holding all the compression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* mode this stream is in, and whether inputting */
/* or outputting data */
Int32 mode;
Int32 state;
/* remembers avail_in when flush/finish requested */
UInt32 avail_in_expect;
/* for doing the block sorting */
UInt32* arr1;
UInt32* arr2;
UInt32* ftab;
Int32 origPtr;
/* aliases for arr1 and arr2 */
UInt32* ptr;
UChar* block;
UInt16* mtfv;
UChar* zbits;
/* for deciding when to use the fallback sorting algorithm */
Int32 workFactor;
/* run-length-encoding of the input */
UInt32 state_in_ch;
Int32 state_in_len;
BZ_RAND_DECLS;
/* input and output limits and current posns */
Int32 nblock;
Int32 nblockMAX;
Int32 numZ;
Int32 state_out_pos;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
UChar unseqToSeq[256];
/* the buffer for bit stream creation */
UInt32 bsBuff;
Int32 bsLive;
/* block and combined CRCs */
UInt32 blockCRC;
UInt32 combinedCRC;
/* misc administratium */
Int32 verbosity;
Int32 blockNo;
Int32 blockSize100k;
/* stuff for coding the MTF values */
Int32 nMTF;
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
/* second dimension: only 3 needed; 4 makes index calculations faster */
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
}
EState;
/*-- externs for compression. --*/
extern void
BZ2_blockSort ( EState* );
extern void
BZ2_compressBlock ( EState*, Bool );
extern void
BZ2_bsInitWrite ( EState* );
extern void
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
extern void
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
/*-- states for decompression. --*/
#define BZ_X_IDLE 1
#define BZ_X_OUTPUT 2
#define BZ_X_MAGIC_1 10
#define BZ_X_MAGIC_2 11
#define BZ_X_MAGIC_3 12
#define BZ_X_MAGIC_4 13
#define BZ_X_BLKHDR_1 14
#define BZ_X_BLKHDR_2 15
#define BZ_X_BLKHDR_3 16
#define BZ_X_BLKHDR_4 17
#define BZ_X_BLKHDR_5 18
#define BZ_X_BLKHDR_6 19
#define BZ_X_BCRC_1 20
#define BZ_X_BCRC_2 21
#define BZ_X_BCRC_3 22
#define BZ_X_BCRC_4 23
#define BZ_X_RANDBIT 24
#define BZ_X_ORIGPTR_1 25
#define BZ_X_ORIGPTR_2 26
#define BZ_X_ORIGPTR_3 27
#define BZ_X_MAPPING_1 28
#define BZ_X_MAPPING_2 29
#define BZ_X_SELECTOR_1 30
#define BZ_X_SELECTOR_2 31
#define BZ_X_SELECTOR_3 32
#define BZ_X_CODING_1 33
#define BZ_X_CODING_2 34
#define BZ_X_CODING_3 35
#define BZ_X_MTF_1 36
#define BZ_X_MTF_2 37
#define BZ_X_MTF_3 38
#define BZ_X_MTF_4 39
#define BZ_X_MTF_5 40
#define BZ_X_MTF_6 41
#define BZ_X_ENDHDR_2 42
#define BZ_X_ENDHDR_3 43
#define BZ_X_ENDHDR_4 44
#define BZ_X_ENDHDR_5 45
#define BZ_X_ENDHDR_6 46
#define BZ_X_CCRC_1 47
#define BZ_X_CCRC_2 48
#define BZ_X_CCRC_3 49
#define BZ_X_CCRC_4 50
/*-- Constants for the fast MTF decoder. --*/
#define MTFA_SIZE 4096
#define MTFL_SIZE 16
/*-- Structure holding all the decompression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* state indicator for this stream */
Int32 state;
/* for doing the final run-length decoding */
UChar state_out_ch;
Int32 state_out_len;
Bool blockRandomised;
BZ_RAND_DECLS;
/* the buffer for bit stream reading */
UInt32 bsBuff;
Int32 bsLive;
/* misc administratium */
Int32 blockSize100k;
Bool smallDecompress;
Int32 currBlockNo;
Int32 verbosity;
/* for undoing the Burrows-Wheeler transform */
Int32 origPtr;
UInt32 tPos;
Int32 k0;
Int32 unzftab[256];
Int32 nblock_used;
Int32 cftab[257];
Int32 cftabCopy[257];
/* for undoing the Burrows-Wheeler transform (FAST) */
UInt32 *tt;
/* for undoing the Burrows-Wheeler transform (SMALL) */
UInt16 *ll16;
UChar *ll4;
/* stored and calculated CRCs */
UInt32 storedBlockCRC;
UInt32 storedCombinedCRC;
UInt32 calculatedBlockCRC;
UInt32 calculatedCombinedCRC;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
Bool inUse16[16];
UChar seqToUnseq[256];
/* for decoding the MTF values */
UChar mtfa [MTFA_SIZE];
Int32 mtfbase[256 / MTFL_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 minLens[BZ_N_GROUPS];
/* save area for scalars in the main decompress code */
Int32 save_i;
Int32 save_j;
Int32 save_t;
Int32 save_alphaSize;
Int32 save_nGroups;
Int32 save_nSelectors;
Int32 save_EOB;
Int32 save_groupNo;
Int32 save_groupPos;
Int32 save_nextSym;
Int32 save_nblockMAX;
Int32 save_nblock;
Int32 save_es;
Int32 save_N;
Int32 save_curr;
Int32 save_zt;
Int32 save_zn;
Int32 save_zvec;
Int32 save_zj;
Int32 save_gSel;
Int32 save_gMinlen;
Int32* save_gLimit;
Int32* save_gBase;
Int32* save_gPerm;
}
DState;
/*-- Macros for decompression. --*/
#define BZ_GET_FAST(cccc) \
s->tPos = s->tt[s->tPos]; \
cccc = (UChar)(s->tPos & 0xff); \
s->tPos >>= 8;
#define BZ_GET_FAST_C(cccc) \
c_tPos = c_tt[c_tPos]; \
cccc = (UChar)(c_tPos & 0xff); \
c_tPos >>= 8;
#define SET_LL4(i,n) \
{ if (((i) & 0x1) == 0) \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
}
#define GET_LL4(i) \
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
#define SET_LL(i,n) \
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
SET_LL4(i, n >> 16); \
}
#define GET_LL(i) \
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
#define BZ_GET_SMALL(cccc) \
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
s->tPos = GET_LL(s->tPos);
/*-- externs for decompression. --*/
extern Int32
BZ2_indexIntoF ( Int32, Int32* );
extern Int32
BZ2_decompress ( DState* );
extern void
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
Int32, Int32, Int32 );
#endif
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
#ifdef BZ_NO_STDIO
#ifndef NULL
#define NULL 0
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib_private.h ---*/
/*-------------------------------------------------------------*/

672
3rdparty/bzip2/compress.c vendored Normal file
View File

@@ -0,0 +1,672 @@
/*-------------------------------------------------------------*/
/*--- Compression machinery (not incl block sorting) ---*/
/*--- compress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
/* CHANGES
0.9.0 -- original version.
0.9.0a/b -- no changes in this file.
0.9.0c -- changed setting of nGroups in sendMTFValues()
so as to do a bit better on small files
*/
#include "bzlib_private.h"
/*---------------------------------------------------*/
/*--- Bit stream I/O ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
void BZ2_bsInitWrite ( EState* s )
{
s->bsLive = 0;
s->bsBuff = 0;
}
/*---------------------------------------------------*/
static
void bsFinishWrite ( EState* s )
{
while (s->bsLive > 0) {
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
s->numZ++;
s->bsBuff <<= 8;
s->bsLive -= 8;
}
}
/*---------------------------------------------------*/
#define bsNEEDW(nz) \
{ \
while (s->bsLive >= 8) { \
s->zbits[s->numZ] \
= (UChar)(s->bsBuff >> 24); \
s->numZ++; \
s->bsBuff <<= 8; \
s->bsLive -= 8; \
} \
}
/*---------------------------------------------------*/
static
__inline__
void bsW ( EState* s, Int32 n, UInt32 v )
{
bsNEEDW ( n );
s->bsBuff |= (v << (32 - s->bsLive - n));
s->bsLive += n;
}
/*---------------------------------------------------*/
static
void bsPutUInt32 ( EState* s, UInt32 u )
{
bsW ( s, 8, (u >> 24) & 0xffL );
bsW ( s, 8, (u >> 16) & 0xffL );
bsW ( s, 8, (u >> 8) & 0xffL );
bsW ( s, 8, u & 0xffL );
}
/*---------------------------------------------------*/
static
void bsPutUChar ( EState* s, UChar c )
{
bsW( s, 8, (UInt32)c );
}
/*---------------------------------------------------*/
/*--- The back end proper ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
static
void makeMaps_e ( EState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->unseqToSeq[i] = s->nInUse;
s->nInUse++;
}
}
/*---------------------------------------------------*/
static
void generateMTFValues ( EState* s )
{
UChar yy[256];
Int32 i, j;
Int32 zPend;
Int32 wr;
Int32 EOB;
/*
After sorting (eg, here),
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
and
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
holds the original block data.
The first thing to do is generate the MTF values,
and put them in
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
Because there are strictly fewer or equal MTF values
than block values, ptr values in this area are overwritten
with MTF values only when they are no longer needed.
The final compressed bitstream is generated into the
area starting at
(UChar*) (&((UChar*)s->arr2)[s->nblock])
These storage aliases are set up in bzCompressInit(),
except for the last one, which is arranged in
compressBlock().
*/
UInt32* ptr = s->ptr;
UChar* block = s->block;
UInt16* mtfv = s->mtfv;
makeMaps_e ( s );
EOB = s->nInUse+1;
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
wr = 0;
zPend = 0;
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
for (i = 0; i < s->nblock; i++) {
UChar ll_i;
AssertD ( wr <= i, "generateMTFValues(1)" );
j = ptr[i]-1; if (j < 0) j += s->nblock;
ll_i = s->unseqToSeq[block[j]];
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
if (yy[0] == ll_i) {
zPend++;
} else {
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
{
register UChar rtmp;
register UChar* ryy_j;
register UChar rll_i;
rtmp = yy[1];
yy[1] = yy[0];
ryy_j = &(yy[1]);
rll_i = ll_i;
while ( rll_i != rtmp ) {
register UChar rtmp2;
ryy_j++;
rtmp2 = rtmp;
rtmp = *ryy_j;
*ryy_j = rtmp2;
};
yy[0] = rtmp;
j = ryy_j - &(yy[0]);
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
}
}
}
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
s->nMTF = wr;
}
/*---------------------------------------------------*/
#define BZ_LESSER_ICOST 0
#define BZ_GREATER_ICOST 15
static
void sendMTFValues ( EState* s )
{
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
Int32 nGroups, nBytes;
/*--
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
is a global since the decoder also needs it.
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
are also globals only used in this proc.
Made global to keep stack frame size small.
--*/
UInt16 cost[BZ_N_GROUPS];
Int32 fave[BZ_N_GROUPS];
UInt16* mtfv = s->mtfv;
if (s->verbosity >= 3)
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
"%d+2 syms in use\n",
s->nblock, s->nMTF, s->nInUse );
alphaSize = s->nInUse+2;
for (t = 0; t < BZ_N_GROUPS; t++)
for (v = 0; v < alphaSize; v++)
s->len[t][v] = BZ_GREATER_ICOST;
/*--- Decide how many coding tables to use ---*/
AssertH ( s->nMTF > 0, 3001 );
if (s->nMTF < 200) nGroups = 2; else
if (s->nMTF < 600) nGroups = 3; else
if (s->nMTF < 1200) nGroups = 4; else
if (s->nMTF < 2400) nGroups = 5; else
nGroups = 6;
/*--- Generate an initial set of coding tables ---*/
{
Int32 nPart, remF, tFreq, aFreq;
nPart = nGroups;
remF = s->nMTF;
gs = 0;
while (nPart > 0) {
tFreq = remF / nPart;
ge = gs-1;
aFreq = 0;
while (aFreq < tFreq && ge < alphaSize-1) {
ge++;
aFreq += s->mtfFreq[ge];
}
if (ge > gs
&& nPart != nGroups && nPart != 1
&& ((nGroups-nPart) % 2 == 1)) {
aFreq -= s->mtfFreq[ge];
ge--;
}
if (s->verbosity >= 3)
VPrintf5( " initial group %d, [%d .. %d], "
"has %d syms (%4.1f%%)\n",
nPart, gs, ge, aFreq,
(100.0 * (float)aFreq) / (float)(s->nMTF) );
for (v = 0; v < alphaSize; v++)
if (v >= gs && v <= ge)
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
s->len[nPart-1][v] = BZ_GREATER_ICOST;
nPart--;
gs = ge+1;
remF -= aFreq;
}
}
/*---
Iterate up to BZ_N_ITERS times to improve the tables.
---*/
for (iter = 0; iter < BZ_N_ITERS; iter++) {
for (t = 0; t < nGroups; t++) fave[t] = 0;
for (t = 0; t < nGroups; t++)
for (v = 0; v < alphaSize; v++)
s->rfreq[t][v] = 0;
/*---
Set up an auxiliary length table which is used to fast-track
the common case (nGroups == 6).
---*/
if (nGroups == 6) {
for (v = 0; v < alphaSize; v++) {
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
}
}
nSelectors = 0;
totc = 0;
gs = 0;
while (True) {
/*--- Set group start & end marks. --*/
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
/*--
Calculate the cost of this group as coded
by each of the coding tables.
--*/
for (t = 0; t < nGroups; t++) cost[t] = 0;
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
register UInt32 cost01, cost23, cost45;
register UInt16 icv;
cost01 = cost23 = cost45 = 0;
# define BZ_ITER(nn) \
icv = mtfv[gs+(nn)]; \
cost01 += s->len_pack[icv][0]; \
cost23 += s->len_pack[icv][1]; \
cost45 += s->len_pack[icv][2]; \
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
# undef BZ_ITER
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
UInt16 icv = mtfv[i];
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
}
}
/*--
Find the coding table which is best for this group,
and record its identity in the selector table.
--*/
bc = 999999999; bt = -1;
for (t = 0; t < nGroups; t++)
if (cost[t] < bc) { bc = cost[t]; bt = t; };
totc += bc;
fave[bt]++;
s->selector[nSelectors] = bt;
nSelectors++;
/*--
Increment the symbol frequencies for the selected table.
--*/
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
# undef BZ_ITUR
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++)
s->rfreq[bt][ mtfv[i] ]++;
}
gs = ge+1;
}
if (s->verbosity >= 3) {
VPrintf2 ( " pass %d: size is %d, grp uses are ",
iter+1, totc/8 );
for (t = 0; t < nGroups; t++)
VPrintf1 ( "%d ", fave[t] );
VPrintf0 ( "\n" );
}
/*--
Recompute the tables based on the accumulated frequencies.
--*/
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
comment in huffman.c for details. */
for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
alphaSize, 17 /*20*/ );
}
AssertH( nGroups < 8, 3002 );
AssertH( nSelectors < 32768 &&
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3003 );
/*--- Compute MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
for (i = 0; i < nGroups; i++) pos[i] = i;
for (i = 0; i < nSelectors; i++) {
ll_i = s->selector[i];
j = 0;
tmp = pos[j];
while ( ll_i != tmp ) {
j++;
tmp2 = tmp;
tmp = pos[j];
pos[j] = tmp2;
};
pos[0] = tmp;
s->selectorMtf[i] = j;
}
};
/*--- Assign actual codes for the tables. --*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
AssertH ( !(minLen < 1), 3005 );
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
minLen, maxLen, alphaSize );
}
/*--- Transmit the mapping table. ---*/
{
Bool inUse16[16];
for (i = 0; i < 16; i++) {
inUse16[i] = False;
for (j = 0; j < 16; j++)
if (s->inUse[i * 16 + j]) inUse16[i] = True;
}
nBytes = s->numZ;
for (i = 0; i < 16; i++)
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
for (i = 0; i < 16; i++)
if (inUse16[i])
for (j = 0; j < 16; j++) {
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
}
/*--- Now the selectors. ---*/
nBytes = s->numZ;
bsW ( s, 3, nGroups );
bsW ( s, 15, nSelectors );
for (i = 0; i < nSelectors; i++) {
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( "selectors %d, ", s->numZ-nBytes );
/*--- Now the coding tables. ---*/
nBytes = s->numZ;
for (t = 0; t < nGroups; t++) {
Int32 curr = s->len[t][0];
bsW ( s, 5, curr );
for (i = 0; i < alphaSize; i++) {
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
bsW ( s, 1, 0 );
}
}
if (s->verbosity >= 3)
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
/*--- And finally, the block data proper ---*/
nBytes = s->numZ;
selCtr = 0;
gs = 0;
while (True) {
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
AssertH ( s->selector[selCtr] < nGroups, 3006 );
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
UInt16 mtfv_i;
UChar* s_len_sel_selCtr
= &(s->len[s->selector[selCtr]][0]);
Int32* s_code_sel_selCtr
= &(s->code[s->selector[selCtr]][0]);
# define BZ_ITAH(nn) \
mtfv_i = mtfv[gs+(nn)]; \
bsW ( s, \
s_len_sel_selCtr[mtfv_i], \
s_code_sel_selCtr[mtfv_i] )
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
# undef BZ_ITAH
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
bsW ( s,
s->len [s->selector[selCtr]] [mtfv[i]],
s->code [s->selector[selCtr]] [mtfv[i]] );
}
}
gs = ge+1;
selCtr++;
}
AssertH( selCtr == nSelectors, 3007 );
if (s->verbosity >= 3)
VPrintf1( "codes %d\n", s->numZ-nBytes );
}
/*---------------------------------------------------*/
void BZ2_compressBlock ( EState* s, Bool is_last_block )
{
if (s->nblock > 0) {
BZ_FINALISE_CRC ( s->blockCRC );
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
s->combinedCRC ^= s->blockCRC;
if (s->blockNo > 1) s->numZ = 0;
if (s->verbosity >= 2)
VPrintf4( " block %d: crc = 0x%08x, "
"combined CRC = 0x%08x, size = %d\n",
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
BZ2_blockSort ( s );
}
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
/*-- If this is the first block, create the stream header. --*/
if (s->blockNo == 1) {
BZ2_bsInitWrite ( s );
bsPutUChar ( s, BZ_HDR_B );
bsPutUChar ( s, BZ_HDR_Z );
bsPutUChar ( s, BZ_HDR_h );
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
}
if (s->nblock > 0) {
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
/*-- Now the block's CRC, so it is in a known place. --*/
bsPutUInt32 ( s, s->blockCRC );
/*--
Now a single bit indicating (non-)randomisation.
As of version 0.9.5, we use a better sorting algorithm
which makes randomisation unnecessary. So always set
the randomised bit to 'no'. Of course, the decoder
still needs to be able to handle randomised blocks
so as to maintain backwards compatibility with
older versions of bzip2.
--*/
bsW(s,1,0);
bsW ( s, 24, s->origPtr );
generateMTFValues ( s );
sendMTFValues ( s );
}
/*-- If this is the last block, add the stream trailer. --*/
if (is_last_block) {
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
bsPutUInt32 ( s, s->combinedCRC );
if (s->verbosity >= 2)
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
bsFinishWrite ( s );
}
}
/*-------------------------------------------------------------*/
/*--- end compress.c ---*/
/*-------------------------------------------------------------*/

104
3rdparty/bzip2/crctable.c vendored Normal file
View File

@@ -0,0 +1,104 @@
/*-------------------------------------------------------------*/
/*--- Table for doing CRCs ---*/
/*--- crctable.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*--
I think this is an implementation of the AUTODIN-II,
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
from code by Rob Warnock, in Section 51 of the
comp.compression FAQ.
--*/
UInt32 BZ2_crc32Table[256] = {
/*-- Ugly, innit? --*/
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
};
/*-------------------------------------------------------------*/
/*--- end crctable.c ---*/
/*-------------------------------------------------------------*/

626
3rdparty/bzip2/decompress.c vendored Normal file
View File

@@ -0,0 +1,626 @@
/*-------------------------------------------------------------*/
/*--- Decompression machinery ---*/
/*--- decompress.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
static
void makeMaps_d ( DState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->seqToUnseq[s->nInUse] = i;
s->nInUse++;
}
}
/*---------------------------------------------------*/
#define RETURN(rrr) \
{ retVal = rrr; goto save_state_and_return; };
#define GET_BITS(lll,vvv,nnn) \
case lll: s->state = lll; \
while (True) { \
if (s->bsLive >= nnn) { \
UInt32 v; \
v = (s->bsBuff >> \
(s->bsLive-nnn)) & ((1 << nnn)-1); \
s->bsLive -= nnn; \
vvv = v; \
break; \
} \
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
s->bsBuff \
= (s->bsBuff << 8) | \
((UInt32) \
(*((UChar*)(s->strm->next_in)))); \
s->bsLive += 8; \
s->strm->next_in++; \
s->strm->avail_in--; \
s->strm->total_in_lo32++; \
if (s->strm->total_in_lo32 == 0) \
s->strm->total_in_hi32++; \
}
#define GET_UCHAR(lll,uuu) \
GET_BITS(lll,uuu,8)
#define GET_BIT(lll,uuu) \
GET_BITS(lll,uuu,1)
/*---------------------------------------------------*/
#define GET_MTF_VAL(label1,label2,lval) \
{ \
if (groupPos == 0) { \
groupNo++; \
if (groupNo >= nSelectors) \
RETURN(BZ_DATA_ERROR); \
groupPos = BZ_G_SIZE; \
gSel = s->selector[groupNo]; \
gMinlen = s->minLens[gSel]; \
gLimit = &(s->limit[gSel][0]); \
gPerm = &(s->perm[gSel][0]); \
gBase = &(s->base[gSel][0]); \
} \
groupPos--; \
zn = gMinlen; \
GET_BITS(label1, zvec, zn); \
while (1) { \
if (zn > 20 /* the longest code */) \
RETURN(BZ_DATA_ERROR); \
if (zvec <= gLimit[zn]) break; \
zn++; \
GET_BIT(label2, zj); \
zvec = (zvec << 1) | zj; \
}; \
if (zvec - gBase[zn] < 0 \
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
RETURN(BZ_DATA_ERROR); \
lval = gPerm[zvec - gBase[zn]]; \
}
/*---------------------------------------------------*/
Int32 BZ2_decompress ( DState* s )
{
UChar uc;
Int32 retVal;
Int32 minLen, maxLen;
bz_stream* strm = s->strm;
/* stuff that needs to be saved/restored */
Int32 i;
Int32 j;
Int32 t;
Int32 alphaSize;
Int32 nGroups;
Int32 nSelectors;
Int32 EOB;
Int32 groupNo;
Int32 groupPos;
Int32 nextSym;
Int32 nblockMAX;
Int32 nblock;
Int32 es;
Int32 N;
Int32 curr;
Int32 zt;
Int32 zn;
Int32 zvec;
Int32 zj;
Int32 gSel;
Int32 gMinlen;
Int32* gLimit;
Int32* gBase;
Int32* gPerm;
if (s->state == BZ_X_MAGIC_1) {
/*initialise the save area*/
s->save_i = 0;
s->save_j = 0;
s->save_t = 0;
s->save_alphaSize = 0;
s->save_nGroups = 0;
s->save_nSelectors = 0;
s->save_EOB = 0;
s->save_groupNo = 0;
s->save_groupPos = 0;
s->save_nextSym = 0;
s->save_nblockMAX = 0;
s->save_nblock = 0;
s->save_es = 0;
s->save_N = 0;
s->save_curr = 0;
s->save_zt = 0;
s->save_zn = 0;
s->save_zvec = 0;
s->save_zj = 0;
s->save_gSel = 0;
s->save_gMinlen = 0;
s->save_gLimit = NULL;
s->save_gBase = NULL;
s->save_gPerm = NULL;
}
/*restore from the save area*/
i = s->save_i;
j = s->save_j;
t = s->save_t;
alphaSize = s->save_alphaSize;
nGroups = s->save_nGroups;
nSelectors = s->save_nSelectors;
EOB = s->save_EOB;
groupNo = s->save_groupNo;
groupPos = s->save_groupPos;
nextSym = s->save_nextSym;
nblockMAX = s->save_nblockMAX;
nblock = s->save_nblock;
es = s->save_es;
N = s->save_N;
curr = s->save_curr;
zt = s->save_zt;
zn = s->save_zn;
zvec = s->save_zvec;
zj = s->save_zj;
gSel = s->save_gSel;
gMinlen = s->save_gMinlen;
gLimit = s->save_gLimit;
gBase = s->save_gBase;
gPerm = s->save_gPerm;
retVal = BZ_OK;
switch (s->state) {
GET_UCHAR(BZ_X_MAGIC_1, uc);
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_2, uc);
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_3, uc)
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
s->blockSize100k -= BZ_HDR_0;
if (s->smallDecompress) {
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
s->ll4 = BZALLOC(
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
);
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
} else {
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
}
GET_UCHAR(BZ_X_BLKHDR_1, uc);
if (uc == 0x17) goto endhdr_2;
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_2, uc);
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_3, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_4, uc);
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_5, uc);
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_6, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
s->currBlockNo++;
if (s->verbosity >= 2)
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
s->storedBlockCRC = 0;
GET_UCHAR(BZ_X_BCRC_1, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_2, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_3, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_4, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
s->origPtr = 0;
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
if (s->origPtr < 0)
RETURN(BZ_DATA_ERROR);
if (s->origPtr > 10 + 100000*s->blockSize100k)
RETURN(BZ_DATA_ERROR);
/*--- Receive the mapping table ---*/
for (i = 0; i < 16; i++) {
GET_BIT(BZ_X_MAPPING_1, uc);
if (uc == 1)
s->inUse16[i] = True; else
s->inUse16[i] = False;
}
for (i = 0; i < 256; i++) s->inUse[i] = False;
for (i = 0; i < 16; i++)
if (s->inUse16[i])
for (j = 0; j < 16; j++) {
GET_BIT(BZ_X_MAPPING_2, uc);
if (uc == 1) s->inUse[i * 16 + j] = True;
}
makeMaps_d ( s );
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
alphaSize = s->nInUse+2;
/*--- Now the selectors ---*/
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
for (i = 0; i < nSelectors; i++) {
j = 0;
while (True) {
GET_BIT(BZ_X_SELECTOR_3, uc);
if (uc == 0) break;
j++;
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
}
s->selectorMtf[i] = j;
}
/*--- Undo the MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], tmp, v;
for (v = 0; v < nGroups; v++) pos[v] = v;
for (i = 0; i < nSelectors; i++) {
v = s->selectorMtf[i];
tmp = pos[v];
while (v > 0) { pos[v] = pos[v-1]; v--; }
pos[0] = tmp;
s->selector[i] = tmp;
}
}
/*--- Now the coding tables ---*/
for (t = 0; t < nGroups; t++) {
GET_BITS(BZ_X_CODING_1, curr, 5);
for (i = 0; i < alphaSize; i++) {
while (True) {
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
GET_BIT(BZ_X_CODING_2, uc);
if (uc == 0) break;
GET_BIT(BZ_X_CODING_3, uc);
if (uc == 0) curr++; else curr--;
}
s->len[t][i] = curr;
}
}
/*--- Create the Huffman decoding tables ---*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
BZ2_hbCreateDecodeTables (
&(s->limit[t][0]),
&(s->base[t][0]),
&(s->perm[t][0]),
&(s->len[t][0]),
minLen, maxLen, alphaSize
);
s->minLens[t] = minLen;
}
/*--- Now the MTF values ---*/
EOB = s->nInUse+1;
nblockMAX = 100000 * s->blockSize100k;
groupNo = -1;
groupPos = 0;
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
/*-- MTF init --*/
{
Int32 ii, jj, kk;
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
/*-- end MTF init --*/
nblock = 0;
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
while (True) {
if (nextSym == EOB) break;
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
es = -1;
N = 1;
do {
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
N = N * 2;
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
}
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
es++;
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
s->unzftab[uc] += es;
if (s->smallDecompress)
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->ll16[nblock] = (UInt16)uc;
nblock++;
es--;
}
else
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->tt[nblock] = (UInt32)uc;
nblock++;
es--;
};
continue;
} else {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
/*-- uc = MTF ( nextSym-1 ) --*/
{
Int32 ii, jj, kk, pp, lno, off;
UInt32 nn;
nn = (UInt32)(nextSym - 1);
if (nn < MTFL_SIZE) {
/* avoid general-case expense */
pp = s->mtfbase[0];
uc = s->mtfa[pp+nn];
while (nn > 3) {
Int32 z = pp+nn;
s->mtfa[(z) ] = s->mtfa[(z)-1];
s->mtfa[(z)-1] = s->mtfa[(z)-2];
s->mtfa[(z)-2] = s->mtfa[(z)-3];
s->mtfa[(z)-3] = s->mtfa[(z)-4];
nn -= 4;
}
while (nn > 0) {
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
};
s->mtfa[pp] = uc;
} else {
/* general case */
lno = nn / MTFL_SIZE;
off = nn % MTFL_SIZE;
pp = s->mtfbase[lno] + off;
uc = s->mtfa[pp];
while (pp > s->mtfbase[lno]) {
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
};
s->mtfbase[lno]++;
while (lno > 0) {
s->mtfbase[lno]--;
s->mtfa[s->mtfbase[lno]]
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
lno--;
}
s->mtfbase[0]--;
s->mtfa[s->mtfbase[0]] = uc;
if (s->mtfbase[0] == 0) {
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
}
}
/*-- end uc = MTF ( nextSym-1 ) --*/
s->unzftab[s->seqToUnseq[uc]]++;
if (s->smallDecompress)
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
nblock++;
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
continue;
}
}
/* Now we know what nblock is, we can do a better sanity
check on s->origPtr.
*/
if (s->origPtr < 0 || s->origPtr >= nblock)
RETURN(BZ_DATA_ERROR);
/*-- Set up cftab to facilitate generation of T^(-1) --*/
s->cftab[0] = 0;
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
for (i = 0; i <= 256; i++) {
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
/* s->cftab[i] can legitimately be == nblock */
RETURN(BZ_DATA_ERROR);
}
}
s->state_out_len = 0;
s->state_out_ch = 0;
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
s->state = BZ_X_OUTPUT;
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
if (s->smallDecompress) {
/*-- Make a copy of cftab, used in generation of T --*/
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
/*-- compute the T vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->ll16[i]);
SET_LL(i, s->cftabCopy[uc]);
s->cftabCopy[uc]++;
}
/*-- Compute T^(-1) by pointer reversal on T --*/
i = s->origPtr;
j = GET_LL(i);
do {
Int32 tmp = GET_LL(j);
SET_LL(j, i);
i = j;
j = tmp;
}
while (i != s->origPtr);
s->tPos = s->origPtr;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_SMALL(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_SMALL(s->k0); s->nblock_used++;
}
} else {
/*-- compute the T^(-1) vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->tt[i] & 0xff);
s->tt[s->cftab[uc]] |= (i << 8);
s->cftab[uc]++;
}
s->tPos = s->tt[s->origPtr] >> 8;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_FAST(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_FAST(s->k0); s->nblock_used++;
}
}
RETURN(BZ_OK);
endhdr_2:
GET_UCHAR(BZ_X_ENDHDR_2, uc);
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_3, uc);
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_4, uc);
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_5, uc);
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_6, uc);
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
s->storedCombinedCRC = 0;
GET_UCHAR(BZ_X_CCRC_1, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_2, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_3, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_4, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
s->state = BZ_X_IDLE;
RETURN(BZ_STREAM_END);
default: AssertH ( False, 4001 );
}
AssertH ( False, 4002 );
save_state_and_return:
s->save_i = i;
s->save_j = j;
s->save_t = t;
s->save_alphaSize = alphaSize;
s->save_nGroups = nGroups;
s->save_nSelectors = nSelectors;
s->save_EOB = EOB;
s->save_groupNo = groupNo;
s->save_groupPos = groupPos;
s->save_nextSym = nextSym;
s->save_nblockMAX = nblockMAX;
s->save_nblock = nblock;
s->save_es = es;
s->save_N = N;
s->save_curr = curr;
s->save_zt = zt;
s->save_zn = zn;
s->save_zvec = zvec;
s->save_zj = zj;
s->save_gSel = gSel;
s->save_gMinlen = gMinlen;
s->save_gLimit = gLimit;
s->save_gBase = gBase;
s->save_gPerm = gPerm;
return retVal;
}
/*-------------------------------------------------------------*/
/*--- end decompress.c ---*/
/*-------------------------------------------------------------*/

205
3rdparty/bzip2/huffman.c vendored Normal file
View File

@@ -0,0 +1,205 @@
/*-------------------------------------------------------------*/
/*--- Huffman coding low-level stuff ---*/
/*--- huffman.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
#define ADDWEIGHTS(zw1,zw2) \
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
#define UPHEAP(z) \
{ \
Int32 zz, tmp; \
zz = z; tmp = heap[zz]; \
while (weight[tmp] < weight[heap[zz >> 1]]) { \
heap[zz] = heap[zz >> 1]; \
zz >>= 1; \
} \
heap[zz] = tmp; \
}
#define DOWNHEAP(z) \
{ \
Int32 zz, yy, tmp; \
zz = z; tmp = heap[zz]; \
while (True) { \
yy = zz << 1; \
if (yy > nHeap) break; \
if (yy < nHeap && \
weight[heap[yy+1]] < weight[heap[yy]]) \
yy++; \
if (weight[tmp] < weight[heap[yy]]) break; \
heap[zz] = heap[yy]; \
zz = yy; \
} \
heap[zz] = tmp; \
}
/*---------------------------------------------------*/
void BZ2_hbMakeCodeLengths ( UChar *len,
Int32 *freq,
Int32 alphaSize,
Int32 maxLen )
{
/*--
Nodes and heap entries run from 1. Entry 0
for both the heap and nodes is a sentinel.
--*/
Int32 nNodes, nHeap, n1, n2, i, j, k;
Bool tooLong;
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
for (i = 0; i < alphaSize; i++)
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
while (True) {
nNodes = alphaSize;
nHeap = 0;
heap[0] = 0;
weight[0] = 0;
parent[0] = -2;
for (i = 1; i <= alphaSize; i++) {
parent[i] = -1;
nHeap++;
heap[nHeap] = i;
UPHEAP(nHeap);
}
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
while (nHeap > 1) {
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
nNodes++;
parent[n1] = parent[n2] = nNodes;
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
parent[nNodes] = -1;
nHeap++;
heap[nHeap] = nNodes;
UPHEAP(nHeap);
}
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
tooLong = False;
for (i = 1; i <= alphaSize; i++) {
j = 0;
k = i;
while (parent[k] >= 0) { k = parent[k]; j++; }
len[i-1] = j;
if (j > maxLen) tooLong = True;
}
if (! tooLong) break;
/* 17 Oct 04: keep-going condition for the following loop used
to be 'i < alphaSize', which missed the last element,
theoretically leading to the possibility of the compressor
looping. However, this count-scaling step is only needed if
one of the generated Huffman code words is longer than
maxLen, which up to and including version 1.0.2 was 20 bits,
which is extremely unlikely. In version 1.0.3 maxLen was
changed to 17 bits, which has minimal effect on compression
ratio, but does mean this scaling step is used from time to
time, enough to verify that it works.
This means that bzip2-1.0.3 and later will only produce
Huffman codes with a maximum length of 17 bits. However, in
order to preserve backwards compatibility with bitstreams
produced by versions pre-1.0.3, the decompressor must still
handle lengths of up to 20. */
for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8;
j = 1 + (j / 2);
weight[i] = j << 8;
}
}
}
/*---------------------------------------------------*/
void BZ2_hbAssignCodes ( Int32 *code,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 n, vec, i;
vec = 0;
for (n = minLen; n <= maxLen; n++) {
for (i = 0; i < alphaSize; i++)
if (length[i] == n) { code[i] = vec; vec++; };
vec <<= 1;
}
}
/*---------------------------------------------------*/
void BZ2_hbCreateDecodeTables ( Int32 *limit,
Int32 *base,
Int32 *perm,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 pp, i, j, vec;
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (j = 0; j < alphaSize; j++)
if (length[j] == i) { perm[pp] = j; pp++; };
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
vec = 0;
for (i = minLen; i <= maxLen; i++) {
vec += (base[i+1] - base[i]);
limit[i] = vec-1;
vec <<= 1;
}
for (i = minLen + 1; i <= maxLen; i++)
base[i] = ((limit[i-1] + 1) << 1) - base[i];
}
/*-------------------------------------------------------------*/
/*--- end huffman.c ---*/
/*-------------------------------------------------------------*/

84
3rdparty/bzip2/randtable.c vendored Normal file
View File

@@ -0,0 +1,84 @@
/*-------------------------------------------------------------*/
/*--- Table for randomising repetitive blocks ---*/
/*--- randtable.c ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.4 of 20 December 2006
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------*/
Int32 BZ2_rNums[512] = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
};
/*-------------------------------------------------------------*/
/*--- end randtable.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -1,115 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{78B079BD-9FC7-4B9E-B4A6-96DA0F00248B}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(SolutionDir)3rdparty\DefaultProjectRootDir.props" />
<Import Project="$(SolutionDir)3rdparty\3rdparty.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\CodeGen_Release.props" />
<Import Condition="!$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\include;$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="!$(Configuration.Contains(Debug))">_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;FT2_BUILD_LIBRARY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">_CRT_SECURE_NO_WARNINGS;FT_DEBUG_LEVEL_ERROR;FT_DEBUG_LEVEL_TRACE;FT2_BUILD_LIBRARY;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<DisableSpecificWarnings>4001</DisableSpecificWarnings>
</ClCompile>
<Lib>
<TargetMachine Condition="'$(Platform)'=='Win32'">MachineX86</TargetMachine>
<TargetMachine Condition="'$(Platform)'=='x64'">MachineX64</TargetMachine>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\autofit\autofit.c" />
<ClCompile Include="..\..\src\bdf\bdf.c" />
<ClCompile Include="..\..\src\cff\cff.c" />
<ClCompile Include="..\..\src\base\ftbase.c" />
<ClCompile Include="..\..\src\base\ftbitmap.c" />
<ClCompile Include="..\..\src\cache\ftcache.c" />
<ClCompile Include="ftdebug.c" />
<ClCompile Include="..\..\src\base\ftfstype.c" />
<ClCompile Include="..\..\src\base\ftgasp.c" />
<ClCompile Include="..\..\src\base\ftglyph.c" />
<ClCompile Include="..\..\src\gzip\ftgzip.c" />
<ClCompile Include="..\..\src\base\ftinit.c" />
<ClCompile Include="..\..\src\lzw\ftlzw.c" />
<ClCompile Include="..\..\src\base\ftstroke.c" />
<ClCompile Include="..\..\src\base\ftsystem.c" />
<ClCompile Include="..\..\src\smooth\smooth.c" />
<ClCompile Include="..\..\src\base\ftbbox.c" />
<ClCompile Include="..\..\src\base\ftfntfmt.c" />
<ClCompile Include="..\..\src\base\ftmm.c" />
<ClCompile Include="..\..\src\base\ftpfr.c" />
<ClCompile Include="..\..\src\base\ftsynth.c" />
<ClCompile Include="..\..\src\base\fttype1.c" />
<ClCompile Include="..\..\src\base\ftwinfnt.c" />
<ClCompile Include="..\..\src\base\ftlcdfil.c" />
<ClCompile Include="..\..\src\base\ftgxval.c" />
<ClCompile Include="..\..\src\base\ftotval.c" />
<ClCompile Include="..\..\src\base\ftpatent.c" />
<ClCompile Include="..\..\src\pcf\pcf.c" />
<ClCompile Include="..\..\src\pfr\pfr.c" />
<ClCompile Include="..\..\src\psaux\psaux.c" />
<ClCompile Include="..\..\src\pshinter\pshinter.c" />
<ClCompile Include="..\..\src\psnames\psmodule.c" />
<ClCompile Include="..\..\src\raster\raster.c" />
<ClCompile Include="..\..\src\sfnt\sfnt.c" />
<ClCompile Include="..\..\src\truetype\truetype.c" />
<ClCompile Include="..\..\src\type1\type1.c" />
<ClCompile Include="..\..\src\cid\type1cid.c" />
<ClCompile Include="..\..\src\type42\type42.c" />
<ClCompile Include="..\..\src\winfonts\winfnt.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\ft2build.h" />
<ClInclude Include="..\..\include\freetype\config\ftconfig.h" />
<ClInclude Include="..\..\include\freetype\config\ftheader.h" />
<ClInclude Include="..\..\include\freetype\config\ftmodule.h" />
<ClInclude Include="..\..\include\freetype\config\ftoption.h" />
<ClInclude Include="..\..\include\freetype\config\ftstdlib.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\zlib\zlib.vcxproj">
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@@ -1,155 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{b4c15893-ec11-491d-9507-0ac184f9cc78}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Source Files\FT_MODULES">
<UniqueIdentifier>{4d3e4eff-3fbc-4b20-b413-2743b23b7109}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{e6cf6a0f-0404-4024-8bf8-ff5b29f35657}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\autofit\autofit.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\bdf\bdf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cff\cff.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftbase.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftbitmap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cache\ftcache.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ftdebug.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftfstype.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftgasp.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftglyph.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gzip\ftgzip.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftinit.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lzw\ftlzw.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftstroke.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftsystem.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\smooth\smooth.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftbbox.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftfntfmt.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftmm.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftpfr.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftsynth.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\fttype1.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftwinfnt.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftlcdfil.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftgxval.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftotval.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\base\ftpatent.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\pcf\pcf.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\pfr\pfr.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\psaux\psaux.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\pshinter\pshinter.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\psnames\psmodule.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\raster\raster.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\sfnt\sfnt.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\truetype\truetype.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\type1\type1.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\cid\type1cid.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\type42\type42.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\winfonts\winfnt.c">
<Filter>Source Files\FT_MODULES</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\ft2build.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\freetype\config\ftconfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\freetype\config\ftheader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\freetype\config\ftmodule.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\freetype\config\ftoption.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\freetype\config\ftstdlib.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -1,237 +0,0 @@
/***************************************************************************/
/* */
/* ftdebug.c */
/* */
/* Debugging and logging component for Win32 (body). */
/* */
/* Copyright 1996-2016 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This component contains various macros and functions used to ease the */
/* debugging of the FreeType engine. Its main purpose is in assertion */
/* checking, tracing, and error detection. */
/* */
/* There are now three debugging modes: */
/* */
/* - trace mode */
/* */
/* Error and trace messages are sent to the log file (which can be the */
/* standard error output). */
/* */
/* - error mode */
/* */
/* Only error messages are generated. */
/* */
/* - release mode: */
/* */
/* No error message is sent or generated. The code is free from any */
/* debugging parts. */
/* */
/*************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#ifdef FT_DEBUG_LEVEL_ERROR
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Message( const char* fmt,
... )
{
static char buf[8192];
va_list ap;
va_start( ap, fmt );
vprintf( fmt, ap );
/* send the string to the debugger as well */
vsprintf( buf, fmt, ap );
OutputDebugStringA( buf );
va_end( ap );
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( void )
FT_Panic( const char* fmt,
... )
{
static char buf[8192];
va_list ap;
va_start( ap, fmt );
vsprintf( buf, fmt, ap );
OutputDebugStringA( buf );
va_end( ap );
exit( EXIT_FAILURE );
}
/* documentation is in ftdebug.h */
FT_BASE_DEF( int )
FT_Throw( FT_Error error,
int line,
const char* file )
{
FT_UNUSED( error );
FT_UNUSED( line );
FT_UNUSED( file );
return 0;
}
#ifdef FT_DEBUG_LEVEL_TRACE
/* array of trace levels, initialized to 0 */
int ft_trace_levels[trace_count];
/* define array of trace toggle names */
#define FT_TRACE_DEF( x ) #x ,
static const char* ft_trace_toggles[trace_count + 1] =
{
#include FT_INTERNAL_TRACE_H
NULL
};
#undef FT_TRACE_DEF
/*************************************************************************/
/* */
/* Initialize the tracing sub-system. This is done by retrieving the */
/* value of the "FT2_DEBUG" environment variable. It must be a list of */
/* toggles, separated by spaces, `;' or `,'. Example: */
/* */
/* "any:3 memory:6 stream:5" */
/* */
/* This will request that all levels be set to 3, except the trace level */
/* for the memory and stream components which are set to 6 and 5, */
/* respectively. */
/* */
/* See the file `include/freetype/internal/fttrace.h' for details of the */
/* available toggle names. */
/* */
/* The level must be between 0 and 6; 0 means quiet (except for serious */
/* runtime errors), and 6 means _very_ verbose. */
/* */
FT_BASE_DEF( void )
ft_debug_init( void )
{
const char* ft2_debug = getenv( "FT2_DEBUG" );
if ( ft2_debug )
{
const char* p = ft2_debug;
const char* q;
for ( ; *p; p++ )
{
/* skip leading whitespace and separators */
if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
continue;
/* read toggle name, followed by ':' */
q = p;
while ( *p && *p != ':' )
p++;
if ( !*p )
break;
if ( *p == ':' && p > q )
{
int n, i, len = (int)( p - q );
int level = -1, found = -1;
for ( n = 0; n < trace_count; n++ )
{
const char* toggle = ft_trace_toggles[n];
for ( i = 0; i < len; i++ )
{
if ( toggle[i] != q[i] )
break;
}
if ( i == len && toggle[i] == 0 )
{
found = n;
break;
}
}
/* read level */
p++;
if ( *p )
{
level = *p - '0';
if ( level < 0 || level > 7 )
level = -1;
}
if ( found >= 0 && level >= 0 )
{
if ( found == trace_any )
{
/* special case for "any" */
for ( n = 0; n < trace_count; n++ )
ft_trace_levels[n] = level;
}
else
ft_trace_levels[found] = level;
}
}
}
}
}
#else /* !FT_DEBUG_LEVEL_TRACE */
FT_BASE_DEF( void )
ft_debug_init( void )
{
/* nothing */
}
#endif /* !FT_DEBUG_LEVEL_TRACE */
#endif /* FT_DEBUG_LEVEL_ERROR */
/* END */

View File

@@ -1,169 +0,0 @@
The FreeType Project LICENSE
----------------------------
2006-Jan-27
Copyright 1996-2002, 2006 by
David Turner, Robert Wilhelm, and Werner Lemberg
Introduction
============
The FreeType Project is distributed in several archive packages;
some of them may contain, in addition to the FreeType font engine,
various tools and contributions which rely on, or relate to, the
FreeType Project.
This license applies to all files found in such packages, and
which do not fall under their own explicit license. The license
affects thus the FreeType font engine, the test programs,
documentation and makefiles, at the very least.
This license was inspired by the BSD, Artistic, and IJG
(Independent JPEG Group) licenses, which all encourage inclusion
and use of free software in commercial and freeware products
alike. As a consequence, its main points are that:
o We don't promise that this software works. However, we will be
interested in any kind of bug reports. (`as is' distribution)
o You can use this software for whatever you want, in parts or
full form, without having to pay us. (`royalty-free' usage)
o You may not pretend that you wrote this software. If you use
it, or only parts of it, in a program, you must acknowledge
somewhere in your documentation that you have used the
FreeType code. (`credits')
We specifically permit and encourage the inclusion of this
software, with or without modifications, in commercial products.
We disclaim all warranties covering The FreeType Project and
assume no liability related to The FreeType Project.
Finally, many people asked us for a preferred form for a
credit/disclaimer to use in compliance with this license. We thus
encourage you to use the following text:
"""
Portions of this software are copyright © <year> The FreeType
Project (www.freetype.org). All rights reserved.
"""
Please replace <year> with the value from the FreeType version you
actually use.
Legal Terms
===========
0. Definitions
--------------
Throughout this license, the terms `package', `FreeType Project',
and `FreeType archive' refer to the set of files originally
distributed by the authors (David Turner, Robert Wilhelm, and
Werner Lemberg) as the `FreeType Project', be they named as alpha,
beta or final release.
`You' refers to the licensee, or person using the project, where
`using' is a generic term including compiling the project's source
code as well as linking it to form a `program' or `executable'.
This program is referred to as `a program using the FreeType
engine'.
This license applies to all files distributed in the original
FreeType Project, including all source code, binaries and
documentation, unless otherwise stated in the file in its
original, unmodified form as distributed in the original archive.
If you are unsure whether or not a particular file is covered by
this license, you must contact us to verify this.
The FreeType Project is copyright (C) 1996-2000 by David Turner,
Robert Wilhelm, and Werner Lemberg. All rights reserved except as
specified below.
1. No Warranty
--------------
THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
USE, OF THE FREETYPE PROJECT.
2. Redistribution
-----------------
This license grants a worldwide, royalty-free, perpetual and
irrevocable right and license to use, execute, perform, compile,
display, copy, create derivative works of, distribute and
sublicense the FreeType Project (in both source and object code
forms) and derivative works thereof for any purpose; and to
authorize others to exercise some or all of the rights granted
herein, subject to the following conditions:
o Redistribution of source code must retain this license file
(`FTL.TXT') unaltered; any additions, deletions or changes to
the original files must be clearly indicated in accompanying
documentation. The copyright notices of the unaltered,
original files must be preserved in all copies of source
files.
o Redistribution in binary form must provide a disclaimer that
states that the software is based in part of the work of the
FreeType Team, in the distribution documentation. We also
encourage you to put an URL to the FreeType web page in your
documentation, though this isn't mandatory.
These conditions apply to any software derived from or based on
the FreeType Project, not just the unmodified files. If you use
our work, you must acknowledge us. However, no fee need be paid
to us.
3. Advertising
--------------
Neither the FreeType authors and contributors nor you shall use
the name of the other for commercial, advertising, or promotional
purposes without specific prior written permission.
We suggest, but do not require, that you use one or more of the
following phrases to refer to this software in your documentation
or advertising materials: `FreeType Project', `FreeType Engine',
`FreeType library', or `FreeType Distribution'.
As you have not signed this license, you are not required to
accept it. However, as the FreeType Project is copyrighted
material, only this license, or another one contracted with the
authors, grants you the right to use, distribute, and modify it.
Therefore, by using, distributing, or modifying the FreeType
Project, you indicate that you understand and accept all the terms
of this license.
4. Contacts
-----------
There are two mailing lists related to FreeType:
o freetype@nongnu.org
Discusses general use and applications of FreeType, as well as
future and wanted additions to the library and distribution.
If you are looking for support, start in this list if you
haven't found anything to help you in the documentation.
o freetype-devel@nongnu.org
Discusses bugs, as well as engine internals, design issues,
specific licenses, porting, etc.
Our home page can be found at
http://www.freetype.org
--- end of FTL.TXT ---

Some files were not shown because too many files have changed in this diff Show More