mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
4 Commits
v1.5.0-dev
...
v1.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9dd6277e3 | ||
|
|
e5f49d0ae7 | ||
|
|
73371c3098 | ||
|
|
11da1c053d |
8
.gitattributes
vendored
8
.gitattributes
vendored
@@ -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
|
||||
112
.gitignore
vendored
112
.gitignore
vendored
@@ -1,112 +0,0 @@
|
||||
.*.swp
|
||||
.*.swn
|
||||
.*.swo
|
||||
|
||||
*.suo
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.user
|
||||
*.log
|
||||
*.dsp
|
||||
*.dsw
|
||||
*.bsc
|
||||
*.aps
|
||||
*.exe
|
||||
|
||||
*.trace
|
||||
*.dump
|
||||
|
||||
*.asm
|
||||
!/pcsx2/IPU/yuv2rgb.asm
|
||||
!/pcsx2/x86/ix86-32/aVif_proc-32.asm
|
||||
!/plugins/CDVDpeops/i386.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
|
||||
|
||||
**/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
|
||||
|
||||
Debug
|
||||
Release
|
||||
Devel
|
||||
|
||||
oprofile_data/
|
||||
|
||||
# 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
|
||||
/nsis/output/
|
||||
|
||||
!/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
|
||||
/nsis/svnrev_cdvdiso.nsh
|
||||
/nsis/svnrev_gsdx.nsh
|
||||
/nsis/svnrev_lilypad.nsh
|
||||
/nsis/svnrev_pcsx2.nsh
|
||||
/nsis/svnrev_spu2x.nsh
|
||||
/nsis/svnrev_zerogs.nsh
|
||||
/nsis/svnrev_zerospu2.nsh
|
||||
/pcsx2/gui/Resources/*.h
|
||||
!/pcsx2/gui/Resources/EmbeddedImage.h
|
||||
/plugins/CDVDolio/Template
|
||||
/plugins/GSdx/Template
|
||||
/plugins/USBqemu/Win32/bin
|
||||
/plugins/xpad/Template
|
||||
/plugins/zerospu2/Windows/dsound51.cpp
|
||||
/tools/bin
|
||||
/tools/GSDumpGUI/bin
|
||||
/tools/GSDumpGUI/obj
|
||||
23
.travis.yml
23
.travis.yml
@@ -1,23 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Version 5 seems to be whatever is latest - for now it's 5.2
|
||||
- env: VERSION=5
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: VERSION=4.9
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: VERSION=3.7
|
||||
compiler: clang
|
||||
os: linux
|
||||
|
||||
before_install:
|
||||
- ./travis.sh before_install
|
||||
|
||||
script:
|
||||
- ./travis.sh script
|
||||
40
3rdparty/3rdparty.props
vendored
40
3rdparty/3rdparty.props
vendored
@@ -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>$(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>
|
||||
<?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
26
3rdparty/3rdparty.vsprops
vendored
Normal 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=""$(ProjectDir)""
|
||||
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>
|
||||
54
3rdparty/3rdpartyDLL.props
vendored
54
3rdparty/3rdpartyDLL.props
vendored
@@ -1,28 +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>
|
||||
<?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
30
3rdparty/3rdpartyDLL.vsprops
vendored
Normal 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=""$(ProjectDir)""
|
||||
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=""$(SvnRootDir)/common/include""
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
||||
8
3rdparty/CMakeLists.txt
vendored
Normal file
8
3rdparty/CMakeLists.txt
vendored
Normal 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
|
||||
34
3rdparty/DefaultProjectRootDir.props
vendored
34
3rdparty/DefaultProjectRootDir.props
vendored
@@ -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
15
3rdparty/DefaultProjectRootDir.vsprops
vendored
Normal 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>
|
||||
14435
3rdparty/GL/glew.h
vendored
Normal file
14435
3rdparty/GL/glew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2173
3rdparty/GL/glext.h
vendored
2173
3rdparty/GL/glext.h
vendored
File diff suppressed because it is too large
Load Diff
1476
3rdparty/GL/glxew.h
vendored
Normal file
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
1247
3rdparty/GL/wglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1363
3rdparty/GL/wglext.h
vendored
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
349
3rdparty/SoundTouch/3dnow_win.cpp
vendored
Normal 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
184
3rdparty/SoundTouch/AAFilter.cpp
vendored
Normal 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();
|
||||
}
|
||||
@@ -13,10 +13,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-07 21:41:23 +0200 (Tue, 07 Jan 2014) $
|
||||
// Last changed : $Date: 2008-02-10 14:26:55 -0200 (dom, 10 fev 2008) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: AAFilter.h 187 2014-01-07 19:41:23Z oparviai $
|
||||
// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -45,7 +45,6 @@
|
||||
#define AAFilter_H
|
||||
|
||||
#include "STTypes.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
@@ -85,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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,371 +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: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: BPMDetect.cpp 202 2015-02-21 21:24:29Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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();
|
||||
#pragma omp parallel for
|
||||
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);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// 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);
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-08-30 22:53:44 +0300 (Thu, 30 Aug 2012) $
|
||||
// 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 $
|
||||
67
3rdparty/SoundTouch/CMakeLists.txt
vendored
Normal file
67
3rdparty/SoundTouch/CMakeLists.txt
vendored
Normal 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 "")
|
||||
@@ -15,7 +15,7 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-11-08 20:53:01 +0200 (Thu, 08 Nov 2012) $
|
||||
// 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 $
|
||||
@@ -15,10 +15,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-05 23:40:22 +0200 (Sun, 05 Jan 2014) $
|
||||
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $
|
||||
// $Id: FIFOSampleBuffer.h 143 2012-06-13 19:29:53Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -162,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;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2012-06-13 22:29:53 +0300 (Wed, 13 Jun 2012) $
|
||||
// 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 $
|
||||
@@ -11,10 +11,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
|
||||
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIRFilter.cpp 202 2015-02-21 21:24:29Z oparviai $
|
||||
// $Id: FIRFilter.cpp 131 2011-09-02 18:56:11Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -72,7 +72,8 @@ FIRFilter::~FIRFilter()
|
||||
// Usual C-version of the filter routine for stereo sound
|
||||
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
int j, end;
|
||||
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.
|
||||
@@ -86,12 +87,9 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||
|
||||
end = 2 * (numSamples - length);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j += 2)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
LONG_SAMPLETYPE suml, sumr;
|
||||
uint i;
|
||||
|
||||
suml = sumr = 0;
|
||||
ptr = src + j;
|
||||
@@ -132,31 +130,28 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||
// Usual C-version of the filter routine for mono sound
|
||||
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
int j, end;
|
||||
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;
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j ++)
|
||||
{
|
||||
const SAMPLETYPE *pSrc = src + j;
|
||||
LONG_SAMPLETYPE sum;
|
||||
uint i;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i += 4)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
sum += pSrc[i + 0] * filterCoeffs[i + 0] +
|
||||
pSrc[i + 1] * filterCoeffs[i + 1] +
|
||||
pSrc[i + 2] * filterCoeffs[i + 2] +
|
||||
pSrc[i + 3] * filterCoeffs[i + 3];
|
||||
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;
|
||||
@@ -166,67 +161,12 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
||||
sum *= dScaler;
|
||||
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)sum;
|
||||
src ++;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
uint FIRFilter::evaluateFilterMulti(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels)
|
||||
{
|
||||
int j, end;
|
||||
|
||||
#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);
|
||||
assert(numChannels < 16);
|
||||
|
||||
end = numChannels * (numSamples - length);
|
||||
|
||||
#pragma omp parallel for
|
||||
for (j = 0; j < end; j += numChannels)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
LONG_SAMPLETYPE sums[16];
|
||||
uint c, i;
|
||||
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
{
|
||||
sums[c] = 0;
|
||||
}
|
||||
|
||||
ptr = src + j;
|
||||
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
SAMPLETYPE coef=filterCoeffs[i];
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
{
|
||||
sums[c] += ptr[0] * coef;
|
||||
ptr ++;
|
||||
}
|
||||
}
|
||||
|
||||
for (c = 0; c < numChannels; c ++)
|
||||
{
|
||||
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
sums[c] >>= resultDivFactor;
|
||||
#else
|
||||
sums[c] *= dScaler;
|
||||
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||
dest[j+c] = (SAMPLETYPE)sums[c];
|
||||
}
|
||||
}
|
||||
return numSamples - length;
|
||||
}
|
||||
|
||||
|
||||
// Set filter coeffiecients and length.
|
||||
//
|
||||
// Throws an exception if filter length isn't divisible by 8
|
||||
@@ -259,27 +199,18 @@ uint FIRFilter::getLength() const
|
||||
//
|
||||
// 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)
|
||||
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;
|
||||
|
||||
#ifndef USE_MULTICH_ALWAYS
|
||||
if (numChannels == 1)
|
||||
{
|
||||
return evaluateFilterMono(dest, src, numSamples);
|
||||
}
|
||||
else if (numChannels == 2)
|
||||
if (numChannels == 2)
|
||||
{
|
||||
return evaluateFilterStereo(dest, src, numSamples);
|
||||
}
|
||||
else
|
||||
#endif // USE_MULTICH_ALWAYS
|
||||
{
|
||||
assert(numChannels > 0);
|
||||
return evaluateFilterMulti(dest, src, numSamples, numChannels);
|
||||
} else {
|
||||
return evaluateFilterMono(dest, src, numSamples);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-02-21 23:24:29 +0200 (Sat, 21 Feb 2015) $
|
||||
// Last changed : $Date: 2011-02-13 17:13:57 -0200 (dom, 13 fev 2011) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: FIRFilter.h 202 2015-02-21 21:24:29Z oparviai $
|
||||
// $Id: FIRFilter.h 104 2011-02-13 19:13:57Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -71,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();
|
||||
@@ -91,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
71
3rdparty/SoundTouch/Makefile.am
vendored
Normal 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
|
||||
@@ -1,286 +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
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-05-18 18:22:02 +0300 (Mon, 18 May 2015) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: PeakFinder.cpp 213 2015-05-18 15:22:02Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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);
|
||||
|
||||
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 = 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;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// 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;
|
||||
}
|
||||
@@ -1,97 +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
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2011-12-30 22:33:46 +0200 (Fri, 30 Dec 2011) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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_
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// 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
777
3rdparty/SoundTouch/README.html
vendored
Normal 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 & SoundStretch utility.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
<pre>make install -</pre>
|
||||
</td>
|
||||
<td>
|
||||
<p>Installs the SoundTouch & 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> </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 "<b>source/Android-lib/README-SoundTouch-Android.html</b>"
|
||||
in the package.</p>
|
||||
|
||||
<hr>
|
||||
<h2>3. About implementation & 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 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. <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. <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"> </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 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 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> [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 <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 & 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 & 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:
|
||||
<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. </li>
|
||||
<li> Check against empty buffers in FIFOSampleBuffer </li>
|
||||
<li> Other minor fixes & 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 </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> </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 & 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
626
3rdparty/SoundTouch/RateTransposer.cpp
vendored
Normal 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
159
3rdparty/SoundTouch/RateTransposer.h
vendored
Normal 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
|
||||
@@ -8,10 +8,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-05-18 18:25:07 +0300 (Mon, 18 May 2015) $
|
||||
// Last changed : $Date: 2012-12-28 12:53:56 -0200 (sex, 28 dez 2012) $
|
||||
// File revision : $Revision: 3 $
|
||||
//
|
||||
// $Id: STTypes.h 215 2015-05-18 15:25:07Z oparviai $
|
||||
// $Id: STTypes.h 162 2012-12-28 14:53:56Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -60,6 +60,16 @@ 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
|
||||
{
|
||||
@@ -68,14 +78,7 @@ namespace soundtouch
|
||||
//#undef SOUNDTOUCH_INTEGER_SAMPLES
|
||||
//#undef SOUNDTOUCH_FLOAT_SAMPLES
|
||||
|
||||
/// If following flag is defined, always uses multichannel processing
|
||||
/// routines also for mono and stero sound. This is for routine testing
|
||||
/// purposes; output should be same with either routines, yet disabling
|
||||
/// the dedicated mono/stereo processing routines will result in slower
|
||||
/// runtime performance so recommendation is to keep this off.
|
||||
// #define USE_MULTICH_ALWAYS
|
||||
|
||||
#if (defined(__SOFTFP__) && 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
|
||||
@@ -172,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
86
3rdparty/SoundTouch/SoundTouch.cbp
vendored
Normal 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>
|
||||
@@ -41,10 +41,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-07-26 17:45:48 +0300 (Sun, 26 Jul 2015) $
|
||||
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: SoundTouch.cpp 225 2015-07-26 14:45:48Z oparviai $
|
||||
// $Id: SoundTouch.cpp 143 2012-06-13 19:29:53Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -97,7 +97,7 @@ SoundTouch::SoundTouch()
|
||||
{
|
||||
// Initialize rate transposer and tempo changer instances
|
||||
|
||||
pRateTransposer = new RateTransposer();
|
||||
pRateTransposer = RateTransposer::newInstance();
|
||||
pTDStretch = TDStretch::newInstance();
|
||||
|
||||
setOutPipe(pTDStretch);
|
||||
@@ -110,11 +110,8 @@ SoundTouch::SoundTouch()
|
||||
|
||||
calcEffectiveRateAndTempo();
|
||||
|
||||
samplesExpectedOut = 0;
|
||||
samplesOutput = 0;
|
||||
|
||||
channels = 0;
|
||||
bSrateSet = false;
|
||||
bSrateSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,11 +143,10 @@ uint SoundTouch::getVersionId()
|
||||
// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void SoundTouch::setChannels(uint numChannels)
|
||||
{
|
||||
/*if (numChannels != 1 && numChannels != 2)
|
||||
if (numChannels != 1 && numChannels != 2)
|
||||
{
|
||||
//ST_THROW_RT_ERROR("Illegal number of channels");
|
||||
return;
|
||||
}*/
|
||||
ST_THROW_RT_ERROR("Illegal number of channels");
|
||||
}
|
||||
channels = numChannels;
|
||||
pRateTransposer->setChannels((int)numChannels);
|
||||
pTDStretch->setChannels((int)numChannels);
|
||||
@@ -160,7 +156,7 @@ void SoundTouch::setChannels(uint numChannels)
|
||||
|
||||
// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
// represent slower rate, larger faster rates.
|
||||
void SoundTouch::setRate(double newRate)
|
||||
void SoundTouch::setRate(float newRate)
|
||||
{
|
||||
virtualRate = newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
@@ -170,9 +166,9 @@ void SoundTouch::setRate(double newRate)
|
||||
|
||||
// Sets new rate control value as a difference in percents compared
|
||||
// to the original rate (-50 .. +100 %)
|
||||
void SoundTouch::setRateChange(double newRate)
|
||||
void SoundTouch::setRateChange(float newRate)
|
||||
{
|
||||
virtualRate = 1.0 + 0.01 * newRate;
|
||||
virtualRate = 1.0f + 0.01f * newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
@@ -180,7 +176,7 @@ void SoundTouch::setRateChange(double newRate)
|
||||
|
||||
// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
// represent slower tempo, larger faster tempo.
|
||||
void SoundTouch::setTempo(double newTempo)
|
||||
void SoundTouch::setTempo(float newTempo)
|
||||
{
|
||||
virtualTempo = newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
@@ -190,9 +186,9 @@ void SoundTouch::setTempo(double newTempo)
|
||||
|
||||
// Sets new tempo control value as a difference in percents compared
|
||||
// to the original tempo (-50 .. +100 %)
|
||||
void SoundTouch::setTempoChange(double newTempo)
|
||||
void SoundTouch::setTempoChange(float newTempo)
|
||||
{
|
||||
virtualTempo = 1.0 + 0.01 * newTempo;
|
||||
virtualTempo = 1.0f + 0.01f * newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
@@ -200,7 +196,7 @@ void SoundTouch::setTempoChange(double newTempo)
|
||||
|
||||
// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
// represent lower pitches, larger values higher pitch.
|
||||
void SoundTouch::setPitch(double newPitch)
|
||||
void SoundTouch::setPitch(float newPitch)
|
||||
{
|
||||
virtualPitch = newPitch;
|
||||
calcEffectiveRateAndTempo();
|
||||
@@ -210,9 +206,9 @@ void SoundTouch::setPitch(double newPitch)
|
||||
|
||||
// Sets pitch change in octaves compared to the original pitch
|
||||
// (-1.00 .. +1.00)
|
||||
void SoundTouch::setPitchOctaves(double newPitch)
|
||||
void SoundTouch::setPitchOctaves(float newPitch)
|
||||
{
|
||||
virtualPitch = exp(0.69314718056 * newPitch);
|
||||
virtualPitch = (float)exp(0.69314718056f * newPitch);
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
@@ -222,14 +218,14 @@ void SoundTouch::setPitchOctaves(double newPitch)
|
||||
// (-12 .. +12)
|
||||
void SoundTouch::setPitchSemiTones(int newPitch)
|
||||
{
|
||||
setPitchOctaves((double)newPitch / 12.0);
|
||||
setPitchOctaves((float)newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SoundTouch::setPitchSemiTones(double newPitch)
|
||||
void SoundTouch::setPitchSemiTones(float newPitch)
|
||||
{
|
||||
setPitchOctaves(newPitch / 12.0);
|
||||
setPitchOctaves(newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -237,14 +233,14 @@ void SoundTouch::setPitchSemiTones(double newPitch)
|
||||
// nominal control values.
|
||||
void SoundTouch::calcEffectiveRateAndTempo()
|
||||
{
|
||||
double oldTempo = tempo;
|
||||
double oldRate = rate;
|
||||
float oldTempo = tempo;
|
||||
float oldRate = rate;
|
||||
|
||||
tempo = virtualTempo / virtualPitch;
|
||||
rate = virtualPitch * virtualRate;
|
||||
tempo = virtualTempo / virtualPitch;
|
||||
rate = virtualPitch * virtualRate;
|
||||
|
||||
if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
|
||||
if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
|
||||
if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
|
||||
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
if (rate <= 1.0f)
|
||||
@@ -258,7 +254,7 @@ void SoundTouch::calcEffectiveRateAndTempo()
|
||||
tempoOut = pTDStretch->getOutput();
|
||||
tempoOut->moveSamples(*output);
|
||||
// move samples in pitch transposer's store buffer to tempo changer's input
|
||||
// deprecated : pTDStretch->moveSamples(*pRateTransposer->getStore());
|
||||
pTDStretch->moveSamples(*pRateTransposer->getStore());
|
||||
|
||||
output = pTDStretch;
|
||||
}
|
||||
@@ -286,7 +282,7 @@ void SoundTouch::calcEffectiveRateAndTempo()
|
||||
// Sets sample rate.
|
||||
void SoundTouch::setSampleRate(uint srate)
|
||||
{
|
||||
bSrateSet = true;
|
||||
bSrateSet = TRUE;
|
||||
// set sample rate, leave other tempo changer parameters as they are.
|
||||
pTDStretch->setParameters((int)srate);
|
||||
}
|
||||
@@ -296,7 +292,7 @@ void SoundTouch::setSampleRate(uint srate)
|
||||
// the input of the object.
|
||||
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||
{
|
||||
if (bSrateSet == false)
|
||||
if (bSrateSet == FALSE)
|
||||
{
|
||||
ST_THROW_RT_ERROR("SoundTouch : Sample rate not defined");
|
||||
}
|
||||
@@ -320,13 +316,8 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||
pTDStretch->putSamples(samples, nSamples);
|
||||
}
|
||||
*/
|
||||
|
||||
// accumulate how many samples are expected out from processing, given the current
|
||||
// processing setting
|
||||
samplesExpectedOut += (double)nSamples / ((double)rate * (double)tempo);
|
||||
|
||||
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||
if (rate <= 1.0f)
|
||||
else if (rate <= 1.0f)
|
||||
{
|
||||
// transpose the rate down, output the transposed sound to tempo changer buffer
|
||||
assert(output == pTDStretch);
|
||||
@@ -354,37 +345,49 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||
void SoundTouch::flush()
|
||||
{
|
||||
int i;
|
||||
int numStillExpected;
|
||||
SAMPLETYPE *buff = new SAMPLETYPE[128 * channels];
|
||||
int nUnprocessed;
|
||||
int nOut;
|
||||
SAMPLETYPE buff[64*2]; // note: allocate 2*64 to cater 64 sample frames of stereo sound
|
||||
|
||||
// how many samples are still expected to output
|
||||
numStillExpected = (int)((long)(samplesExpectedOut + 0.5) - samplesOutput);
|
||||
// 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);
|
||||
|
||||
memset(buff, 0, 128 * channels * sizeof(SAMPLETYPE));
|
||||
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
|
||||
// 24ksamples in any case)
|
||||
for (i = 0; (numStillExpected > (int)numSamples()) && (i < 200); i ++)
|
||||
{
|
||||
putSamples(buff, 128);
|
||||
}
|
||||
// 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);
|
||||
|
||||
adjustAmountOfSamples(numStillExpected);
|
||||
// finish
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] buff;
|
||||
|
||||
// Clear input buffers
|
||||
// pRateTransposer->clearInput();
|
||||
// Clear working buffers
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clearInput();
|
||||
// yet leave the output intouched as that's where the
|
||||
// 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)
|
||||
BOOL SoundTouch::setSetting(int settingId, int value)
|
||||
{
|
||||
int sampleRate, sequenceMs, seekWindowMs, overlapMs;
|
||||
|
||||
@@ -395,36 +398,36 @@ bool SoundTouch::setSetting(int settingId, int value)
|
||||
{
|
||||
case SETTING_USE_AA_FILTER :
|
||||
// enables / disabless anti-alias filter
|
||||
pRateTransposer->enableAAFilter((value != 0) ? true : false);
|
||||
return true;
|
||||
pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_AA_FILTER_LENGTH :
|
||||
// sets anti-alias filter length
|
||||
pRateTransposer->getAAFilter()->setLength(value);
|
||||
return true;
|
||||
return TRUE;
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
// enables / disables tempo routine quick seeking algorithm
|
||||
pTDStretch->enableQuickSeek((value != 0) ? true : false);
|
||||
return true;
|
||||
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;
|
||||
return TRUE;
|
||||
|
||||
case SETTING_SEEKWINDOW_MS:
|
||||
// change time-stretch seek window length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
|
||||
return true;
|
||||
return TRUE;
|
||||
|
||||
case SETTING_OVERLAP_MS:
|
||||
// change time-stretch overlap length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
|
||||
return true;
|
||||
return TRUE;
|
||||
|
||||
default :
|
||||
return false;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +479,6 @@ int SoundTouch::getSetting(int settingId) const
|
||||
// buffers.
|
||||
void SoundTouch::clear()
|
||||
{
|
||||
samplesExpectedOut = 0;
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clear();
|
||||
}
|
||||
@@ -497,30 +499,3 @@ uint SoundTouch::numUnprocessedSamples() const
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
uint SoundTouch::receiveSamples(SAMPLETYPE *output, uint maxSamples)
|
||||
{
|
||||
uint ret = FIFOProcessor::receiveSamples(output, maxSamples);
|
||||
samplesOutput += (long)ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
uint SoundTouch::receiveSamples(uint maxSamples)
|
||||
{
|
||||
uint ret = FIFOProcessor::receiveSamples(maxSamples);
|
||||
samplesOutput += (long)ret;
|
||||
return ret;
|
||||
}
|
||||
@@ -41,10 +41,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-09-20 10:38:32 +0300 (Sun, 20 Sep 2015) $
|
||||
// Last changed : $Date: 2012-12-28 17:32:59 -0200 (sex, 28 dez 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: SoundTouch.h 230 2015-09-20 07:38:32Z oparviai $
|
||||
// $Id: SoundTouch.h 163 2012-12-28 19:32:59Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -79,10 +79,10 @@ namespace soundtouch
|
||||
{
|
||||
|
||||
/// Soundtouch library version string
|
||||
#define SOUNDTOUCH_VERSION "1.9.2"
|
||||
#define SOUNDTOUCH_VERSION "1.7.1"
|
||||
|
||||
/// SoundTouch library version id
|
||||
#define SOUNDTOUCH_VERSION_ID (10902)
|
||||
#define SOUNDTOUCH_VERSION_ID (10701)
|
||||
|
||||
//
|
||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||
@@ -151,23 +151,16 @@ private:
|
||||
class TDStretch *pTDStretch;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
double virtualRate;
|
||||
float virtualRate;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
double virtualTempo;
|
||||
float virtualTempo;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
double virtualPitch;
|
||||
float virtualPitch;
|
||||
|
||||
/// Flag: Has sample rate been set?
|
||||
bool bSrateSet;
|
||||
|
||||
/// Accumulator for how many samples in total will be expected as output vs. samples put in,
|
||||
/// considering current processing settings.
|
||||
double samplesExpectedOut;
|
||||
|
||||
/// Accumulator for how many samples in total have been read out from the processing so far
|
||||
long samplesOutput;
|
||||
BOOL bSrateSet;
|
||||
|
||||
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
|
||||
/// 'virtualPitch' parameters.
|
||||
@@ -178,10 +171,10 @@ protected :
|
||||
uint channels;
|
||||
|
||||
/// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
double rate;
|
||||
float rate;
|
||||
|
||||
/// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
double tempo;
|
||||
float tempo;
|
||||
|
||||
public:
|
||||
SoundTouch();
|
||||
@@ -195,32 +188,32 @@ public:
|
||||
|
||||
/// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
/// represent slower rate, larger faster rates.
|
||||
void setRate(double newRate);
|
||||
void setRate(float newRate);
|
||||
|
||||
/// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
/// represent slower tempo, larger faster tempo.
|
||||
void setTempo(double newTempo);
|
||||
void setTempo(float newTempo);
|
||||
|
||||
/// Sets new rate control value as a difference in percents compared
|
||||
/// to the original rate (-50 .. +100 %)
|
||||
void setRateChange(double newRate);
|
||||
void setRateChange(float newRate);
|
||||
|
||||
/// Sets new tempo control value as a difference in percents compared
|
||||
/// to the original tempo (-50 .. +100 %)
|
||||
void setTempoChange(double newTempo);
|
||||
void setTempoChange(float newTempo);
|
||||
|
||||
/// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
/// represent lower pitches, larger values higher pitch.
|
||||
void setPitch(double newPitch);
|
||||
void setPitch(float newPitch);
|
||||
|
||||
/// Sets pitch change in octaves compared to the original pitch
|
||||
/// (-1.00 .. +1.00)
|
||||
void setPitchOctaves(double newPitch);
|
||||
void setPitchOctaves(float newPitch);
|
||||
|
||||
/// Sets pitch change in semi-tones compared to the original pitch
|
||||
/// (-12 .. +12)
|
||||
void setPitchSemiTones(int newPitch);
|
||||
void setPitchSemiTones(double newPitch);
|
||||
void setPitchSemiTones(float newPitch);
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint numChannels);
|
||||
@@ -247,23 +240,6 @@ public:
|
||||
///< contains data for both channels.
|
||||
);
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
);
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
);
|
||||
|
||||
/// Clears all the samples in the object's output and internal processing
|
||||
/// buffers.
|
||||
virtual void clear();
|
||||
@@ -271,8 +247,8 @@ public:
|
||||
/// 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.
|
||||
/// \return 'TRUE' if the setting was succesfully changed
|
||||
BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines.
|
||||
int value ///< New setting value.
|
||||
);
|
||||
|
||||
285
3rdparty/SoundTouch/SoundTouch.vcproj
vendored
Normal file
285
3rdparty/SoundTouch/SoundTouch.vcproj
vendored
Normal 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
112
3rdparty/SoundTouch/SoundTouch.vcxproj
vendored
Normal 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>
|
||||
83
3rdparty/SoundTouch/SoundTouch.vcxproj.filters
vendored
Normal file
83
3rdparty/SoundTouch/SoundTouch.vcxproj.filters
vendored
Normal 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>
|
||||
116
3rdparty/SoundTouch/SoundTouch_vs2012.vcxproj
vendored
Normal file
116
3rdparty/SoundTouch/SoundTouch_vs2012.vcxproj
vendored
Normal 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>
|
||||
83
3rdparty/SoundTouch/SoundTouch_vs2012.vcxproj.filters
vendored
Normal file
83
3rdparty/SoundTouch/SoundTouch_vs2012.vcxproj.filters
vendored
Normal 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>
|
||||
116
3rdparty/SoundTouch/SoundTouch_vs2013.vcxproj
vendored
Normal file
116
3rdparty/SoundTouch/SoundTouch_vs2013.vcxproj
vendored
Normal 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>
|
||||
83
3rdparty/SoundTouch/SoundTouch_vs2013.vcxproj.filters
vendored
Normal file
83
3rdparty/SoundTouch/SoundTouch_vs2013.vcxproj.filters
vendored
Normal 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
808
3rdparty/SoundTouch/TDStretch.cpp
vendored
Normal 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
|
||||
@@ -13,10 +13,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
|
||||
// Last changed : $Date: 2012-04-01 16:49:30 -0300 (dom, 01 abr 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: TDStretch.h 226 2015-08-08 21:00:15Z oparviai $
|
||||
// $Id: TDStretch.h 137 2012-04-01 19:49:30Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -112,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;
|
||||
|
||||
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.
|
||||
@@ -191,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();
|
||||
@@ -204,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.
|
||||
@@ -258,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();
|
||||
};
|
||||
@@ -271,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
745
3rdparty/SoundTouch/WavFile.cpp
vendored
Normal 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;
|
||||
}
|
||||
@@ -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,10 +16,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-10-05 19:20:24 +0300 (Sun, 05 Oct 2014) $
|
||||
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: WavFile.h 200 2014-10-05 16:20:24Z oparviai $
|
||||
// $Id: WavFile.h 63 2009-02-21 16:00:14Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -51,11 +51,11 @@
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
@@ -63,7 +63,7 @@ typedef struct
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
@@ -75,16 +75,8 @@ typedef struct
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'fact' section header
|
||||
typedef struct
|
||||
{
|
||||
char fact_field[4];
|
||||
int fact_len;
|
||||
uint fact_sample_len;
|
||||
} WavFact;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
@@ -92,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;
|
||||
@@ -171,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;
|
||||
|
||||
@@ -180,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.
|
||||
@@ -208,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.
|
||||
@@ -227,7 +192,7 @@ public:
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile : protected WavFileBase
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
@@ -250,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)
|
||||
@@ -263,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
28
3rdparty/SoundTouch/build.sh
vendored
Normal 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
37
3rdparty/SoundTouch/configure.ac
vendored
Normal 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
|
||||
@@ -12,7 +12,7 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
|
||||
// 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 $
|
||||
@@ -1,138 +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
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2014-01-07 20:24:28 +0200 (Tue, 07 Jan 2014) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: cpu_detect_x86.cpp 183 2014-01-07 18:24:28Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
}
|
||||
134
3rdparty/SoundTouch/cpu_detect_x86_gcc.cpp
vendored
Normal file
134
3rdparty/SoundTouch/cpu_detect_x86_gcc.cpp
vendored
Normal 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
|
||||
}
|
||||
137
3rdparty/SoundTouch/cpu_detect_x86_win.cpp
vendored
Normal file
137
3rdparty/SoundTouch/cpu_detect_x86_win.cpp
vendored
Normal 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
1
3rdparty/SoundTouch/depcomp
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/share/automake-1.10/depcomp
|
||||
1
3rdparty/SoundTouch/install-sh
vendored
Symbolic link
1
3rdparty/SoundTouch/install-sh
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/share/automake-1.10/install-sh
|
||||
1
3rdparty/SoundTouch/missing
vendored
Symbolic link
1
3rdparty/SoundTouch/missing
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/share/automake-1.10/missing
|
||||
317
3rdparty/SoundTouch/mmx_optimized.cpp
vendored
Normal file
317
3rdparty/SoundTouch/mmx_optimized.cpp
vendored
Normal 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
|
||||
7
3rdparty/SoundTouch/soundtouch_config.h
vendored
Normal file
7
3rdparty/SoundTouch/soundtouch_config.h
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef SOUNDTOUCH_CONFIG_H_INCLUDED
|
||||
#define SOUNDTOUCH_CONFIG_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
#endif // SOUNDTOUCH_CONFIG_H_INCLUDED
|
||||
@@ -23,10 +23,10 @@
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2015-08-09 00:00:15 +0300 (Sun, 09 Aug 2015) $
|
||||
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
|
||||
// File revision : $Revision: 4 $
|
||||
//
|
||||
// $Id: sse_optimized.cpp 226 2015-08-08 21:00:15Z oparviai $
|
||||
// $Id: sse_optimized.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -71,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;
|
||||
@@ -141,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;
|
||||
@@ -182,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'
|
||||
@@ -259,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();
|
||||
@@ -302,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:
|
||||
327
3rdparty/bzip2/CHANGES
vendored
327
3rdparty/bzip2/CHANGES
vendored
@@ -1,327 +0,0 @@
|
||||
------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 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.
|
||||
------------------------------------------------------------------
|
||||
|
||||
|
||||
0.9.0
|
||||
~~~~~
|
||||
First version.
|
||||
|
||||
|
||||
0.9.0a
|
||||
~~~~~~
|
||||
Removed 'ranlib' from Makefile, since most modern Unix-es
|
||||
don't need it, or even know about it.
|
||||
|
||||
|
||||
0.9.0b
|
||||
~~~~~~
|
||||
Fixed a problem with error reporting in bzip2.c. This does not effect
|
||||
the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
|
||||
program proper) compress and decompress correctly, but give misleading
|
||||
error messages (internal panics) when an I/O error occurs, instead of
|
||||
reporting the problem correctly. This shouldn't give any data loss
|
||||
(as far as I can see), but is confusing.
|
||||
|
||||
Made the inline declarations disappear for non-GCC compilers.
|
||||
|
||||
|
||||
0.9.0c
|
||||
~~~~~~
|
||||
Fixed some problems in the library pertaining to some boundary cases.
|
||||
This makes the library behave more correctly in those situations. The
|
||||
fixes apply only to features (calls and parameters) not used by
|
||||
bzip2.c, so the non-fixedness of them in previous versions has no
|
||||
effect on reliability of bzip2.c.
|
||||
|
||||
In bzlib.c:
|
||||
* made zero-length BZ_FLUSH work correctly in bzCompress().
|
||||
* fixed bzWrite/bzRead to ignore zero-length requests.
|
||||
* fixed bzread to correctly handle read requests after EOF.
|
||||
* wrong parameter order in call to bzDecompressInit in
|
||||
bzBuffToBuffDecompress. Fixed.
|
||||
|
||||
In compress.c:
|
||||
* changed setting of nGroups in sendMTFValues() so as to
|
||||
do a bit better on small files. This _does_ effect
|
||||
bzip2.c.
|
||||
|
||||
|
||||
0.9.5a
|
||||
~~~~~~
|
||||
Major change: add a fallback sorting algorithm (blocksort.c)
|
||||
to give reasonable behaviour even for very repetitive inputs.
|
||||
Nuked --repetitive-best and --repetitive-fast since they are
|
||||
no longer useful.
|
||||
|
||||
Minor changes: mostly a whole bunch of small changes/
|
||||
bugfixes in the driver (bzip2.c). Changes pertaining to the
|
||||
user interface are:
|
||||
|
||||
allow decompression of symlink'd files to stdout
|
||||
decompress/test files even without .bz2 extension
|
||||
give more accurate error messages for I/O errors
|
||||
when compressing/decompressing to stdout, don't catch control-C
|
||||
read flags from BZIP2 and BZIP environment variables
|
||||
decline to break hard links to a file unless forced with -f
|
||||
allow -c flag even with no filenames
|
||||
preserve file ownerships as far as possible
|
||||
make -s -1 give the expected block size (100k)
|
||||
add a flag -q --quiet to suppress nonessential warnings
|
||||
stop decoding flags after --, so files beginning in - can be handled
|
||||
resolved inconsistent naming: bzcat or bz2cat ?
|
||||
bzip2 --help now returns 0
|
||||
|
||||
Programming-level changes are:
|
||||
|
||||
fixed syntax error in GET_LL4 for Borland C++ 5.02
|
||||
let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
|
||||
fix overshoot of mode-string end in bzopen_or_bzdopen
|
||||
wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
|
||||
close file handles under all error conditions
|
||||
added minor mods so it compiles with DJGPP out of the box
|
||||
fixed Makefile so it doesn't give problems with BSD make
|
||||
fix uninitialised memory reads in dlltest.c
|
||||
|
||||
0.9.5b
|
||||
~~~~~~
|
||||
Open stdin/stdout in binary mode for DJGPP.
|
||||
|
||||
0.9.5c
|
||||
~~~~~~
|
||||
Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
|
||||
version could cause the sorted order to be wrong in some extremely
|
||||
obscure cases. Also changed setting of quadrant in blocksort.c.
|
||||
|
||||
0.9.5d
|
||||
~~~~~~
|
||||
The only functional change is to make bzlibVersion() in the library
|
||||
return the correct string. This has no effect whatsoever on the
|
||||
functioning of the bzip2 program or library. Added a couple of casts
|
||||
so the library compiles without warnings at level 3 in MS Visual
|
||||
Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
|
||||
changes are minor documentation changes.
|
||||
|
||||
1.0
|
||||
~~~
|
||||
Several minor bugfixes and enhancements:
|
||||
|
||||
* Large file support. The library uses 64-bit counters to
|
||||
count the volume of data passing through it. bzip2.c
|
||||
is now compiled with -D_FILE_OFFSET_BITS=64 to get large
|
||||
file support from the C library. -v correctly prints out
|
||||
file sizes greater than 4 gigabytes. All these changes have
|
||||
been made without assuming a 64-bit platform or a C compiler
|
||||
which supports 64-bit ints, so, except for the C library
|
||||
aspect, they are fully portable.
|
||||
|
||||
* Decompression robustness. The library/program should be
|
||||
robust to any corruption of compressed data, detecting and
|
||||
handling _all_ corruption, instead of merely relying on
|
||||
the CRCs. What this means is that the program should
|
||||
never crash, given corrupted data, and the library should
|
||||
always return BZ_DATA_ERROR.
|
||||
|
||||
* Fixed an obscure race-condition bug only ever observed on
|
||||
Solaris, in which, if you were very unlucky and issued
|
||||
control-C at exactly the wrong time, both input and output
|
||||
files would be deleted.
|
||||
|
||||
* Don't run out of file handles on test/decompression when
|
||||
large numbers of files have invalid magic numbers.
|
||||
|
||||
* Avoid library namespace pollution. Prefix all exported
|
||||
symbols with BZ2_.
|
||||
|
||||
* Minor sorting enhancements from my DCC2000 paper.
|
||||
|
||||
* Advance the version number to 1.0, so as to counteract the
|
||||
(false-in-this-case) impression some people have that programs
|
||||
with version numbers less than 1.0 are in some way, experimental,
|
||||
pre-release versions.
|
||||
|
||||
* Create an initial Makefile-libbz2_so to build a shared library.
|
||||
Yes, I know I should really use libtool et al ...
|
||||
|
||||
* Make the program exit with 2 instead of 0 when decompression
|
||||
fails due to a bad magic number (ie, an invalid bzip2 header).
|
||||
Also exit with 1 (as the manual claims :-) whenever a diagnostic
|
||||
message would have been printed AND the corresponding operation
|
||||
is aborted, for example
|
||||
bzip2: Output file xx already exists.
|
||||
When a diagnostic message is printed but the operation is not
|
||||
aborted, for example
|
||||
bzip2: Can't guess original name for wurble -- using wurble.out
|
||||
then the exit value 0 is returned, unless some other problem is
|
||||
also detected.
|
||||
|
||||
I think it corresponds more closely to what the manual claims now.
|
||||
|
||||
|
||||
1.0.1
|
||||
~~~~~
|
||||
* Modified dlltest.c so it uses the new BZ2_ naming scheme.
|
||||
* Modified makefile-msc to fix minor build probs on Win2k.
|
||||
* Updated README.COMPILATION.PROBLEMS.
|
||||
|
||||
There are no functionality changes or bug fixes relative to version
|
||||
1.0.0. This is just a documentation update + a fix for minor Win32
|
||||
build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
|
||||
utterly pointless. Don't bother.
|
||||
|
||||
|
||||
1.0.2
|
||||
~~~~~
|
||||
A bug fix release, addressing various minor issues which have appeared
|
||||
in the 18 or so months since 1.0.1 was released. Most of the fixes
|
||||
are to do with file-handling or documentation bugs. To the best of my
|
||||
knowledge, there have been no data-loss-causing bugs reported in the
|
||||
compression/decompression engine of 1.0.0 or 1.0.1.
|
||||
|
||||
Note that this release does not improve the rather crude build system
|
||||
for Unix platforms. The general plan here is to autoconfiscate/
|
||||
libtoolise 1.0.2 soon after release, and release the result as 1.1.0
|
||||
or perhaps 1.2.0. That, however, is still just a plan at this point.
|
||||
|
||||
Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
|
||||
parentheses.
|
||||
|
||||
* Fix an infinite segfault loop in 1.0.1 when a directory is
|
||||
encountered in -f (force) mode.
|
||||
(Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
|
||||
|
||||
* Avoid double fclose() of output file on certain I/O error paths.
|
||||
(Solar Designer)
|
||||
|
||||
* Don't fail with internal error 1007 when fed a long stream (> 48MB)
|
||||
of byte 251. Also print useful message suggesting that 1007s may be
|
||||
caused by bad memory.
|
||||
(noticed by Juan Pedro Vallejo, fixed by me)
|
||||
|
||||
* Fix uninitialised variable silly bug in demo prog dlltest.c.
|
||||
(Jorj Bauer)
|
||||
|
||||
* Remove 512-MB limitation on recovered file size for bzip2recover
|
||||
on selected platforms which support 64-bit ints. At the moment
|
||||
all GCC supported platforms, and Win32.
|
||||
(me, Alson van der Meulen)
|
||||
|
||||
* Hard-code header byte values, to give correct operation on platforms
|
||||
using EBCDIC as their native character set (IBM's OS/390).
|
||||
(Leland Lucius)
|
||||
|
||||
* Copy file access times correctly.
|
||||
(Marty Leisner)
|
||||
|
||||
* Add distclean and check targets to Makefile.
|
||||
(Michael Carmack)
|
||||
|
||||
* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
|
||||
(Rich Ireland, Bo Thorsen)
|
||||
|
||||
* Pass -p (create parent dirs as needed) to mkdir during make install.
|
||||
(Jeremy Fusco)
|
||||
|
||||
* Dereference symlinks when copying file permissions in -f mode.
|
||||
(Volker Schmidt)
|
||||
|
||||
* Majorly simplify implementation of uInt64_qrm10.
|
||||
(Bo Lindbergh)
|
||||
|
||||
* Check the input file still exists before deleting the output one,
|
||||
when aborting in cleanUpAndFail().
|
||||
(Joerg Prante, Robert Linden, Matthias Krings)
|
||||
|
||||
Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
|
||||
of bzip2:
|
||||
|
||||
* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
|
||||
|
||||
* Spelling changes and minor enhancements in bzip2.1.
|
||||
|
||||
* Avoid race condition between creating the output file and setting its
|
||||
interim permissions safely, by using fopen_output_safely().
|
||||
No changes to bzip2recover since there is no issue with file
|
||||
permissions there.
|
||||
|
||||
* do not print senseless report with -v when compressing an empty
|
||||
file.
|
||||
|
||||
* bzcat -f works on non-bzip2 files.
|
||||
|
||||
* do not try to escape shell meta-characters on unix (the shell takes
|
||||
care of these).
|
||||
|
||||
* added --fast and --best aliases for -1 -9 for gzip compatibility.
|
||||
|
||||
|
||||
1.0.3 (15 Feb 05)
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Fixes some minor bugs since the last version, 1.0.2.
|
||||
|
||||
* Further robustification against corrupted compressed data.
|
||||
There are currently no known bitstreams which can cause the
|
||||
decompressor to crash, loop or access memory which does not
|
||||
belong to it. If you are using bzip2 or the library to
|
||||
decompress bitstreams from untrusted sources, an upgrade
|
||||
to 1.0.3 is recommended. This fixes CAN-2005-1260.
|
||||
|
||||
* The documentation has been converted to XML, from which html
|
||||
and pdf can be derived.
|
||||
|
||||
* Various minor bugs in the documentation have been fixed.
|
||||
|
||||
* Fixes for various compilation warnings with newer versions of
|
||||
gcc, and on 64-bit platforms.
|
||||
|
||||
* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
|
||||
This has been fixed.
|
||||
|
||||
|
||||
1.0.4 (20 Dec 06)
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Fixes some minor bugs since the last version, 1.0.3.
|
||||
|
||||
* Fix file permissions race problem (CAN-2005-0953).
|
||||
|
||||
* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD
|
||||
scan.
|
||||
|
||||
* 'const'/prototype cleanups in the C code.
|
||||
|
||||
* Change default install location to /usr/local, and handle multiple
|
||||
'make install's without error.
|
||||
|
||||
* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758
|
||||
to the extent that applies to bzgrep.
|
||||
|
||||
* Use 'mktemp' rather than 'tempfile' in bzdiff.
|
||||
|
||||
* Tighten up a couple of assertions in blocksort.c following automated
|
||||
analysis.
|
||||
|
||||
* Fix minor doc/comment bugs.
|
||||
|
||||
|
||||
1.0.5 (10 Dec 07)
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Security fix only. Fixes CERT-FI 20469 as it applies to bzip2.
|
||||
|
||||
|
||||
1.0.6 (6 Sept 10)
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Security fix for CVE-2010-0405. This was reported by Mikolaj
|
||||
Izdebski.
|
||||
|
||||
* Make the documentation build on Ubuntu 10.04
|
||||
55
3rdparty/bzip2/CMakeLists.txt
vendored
Normal file
55
3rdparty/bzip2/CMakeLists.txt
vendored
Normal 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 "")
|
||||
85
3rdparty/bzip2/LICENSE
vendored
85
3rdparty/bzip2/LICENSE
vendored
@@ -1,42 +1,43 @@
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This program, "bzip2", the associated library "libbzip2", and all
|
||||
documentation, are copyright (C) 1996-2010 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, jseward@bzip.org
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
420
3rdparty/bzip2/README
vendored
420
3rdparty/bzip2/README
vendored
@@ -1,215 +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.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 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.
|
||||
|
||||
WHAT'S NEW IN 1.0.5 ?
|
||||
|
||||
See the CHANGES file.
|
||||
|
||||
WHAT'S NEW IN 1.0.6 ?
|
||||
|
||||
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)
|
||||
10 December 2007 (bzip2, version 1.0.5)
|
||||
6 Sept 2010 (bzip2, version 1.0.6)
|
||||
|
||||
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)
|
||||
|
||||
4
3rdparty/bzip2/blocksort.c
vendored
4
3rdparty/bzip2/blocksort.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
87
3rdparty/bzip2/bzip2.cbp
vendored
Normal file
87
3rdparty/bzip2/bzip2.cbp
vendored
Normal 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
231
3rdparty/bzip2/bzip2.vcproj
vendored
Normal 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>
|
||||
186
3rdparty/bzip2/bzip2.vcxproj
vendored
186
3rdparty/bzip2/bzip2.vcxproj
vendored
@@ -1,96 +1,92 @@
|
||||
<?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="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>$(DefaultPlatformToolset)_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)_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>
|
||||
<?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>
|
||||
86
3rdparty/bzip2/bzip2.vcxproj.filters
vendored
86
3rdparty/bzip2/bzip2.vcxproj.filters
vendored
@@ -1,44 +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>
|
||||
<?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
96
3rdparty/bzip2/bzip2_vs2012.vcxproj
vendored
Normal 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>
|
||||
44
3rdparty/bzip2/bzip2_vs2012.vcxproj.filters
vendored
Normal file
44
3rdparty/bzip2/bzip2_vs2012.vcxproj.filters
vendored
Normal 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
96
3rdparty/bzip2/bzip2_vs2013.vcxproj
vendored
Normal 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>
|
||||
44
3rdparty/bzip2/bzip2_vs2013.vcxproj.filters
vendored
Normal file
44
3rdparty/bzip2/bzip2_vs2013.vcxproj.filters
vendored
Normal 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>
|
||||
7
3rdparty/bzip2/bzlib.c
vendored
7
3rdparty/bzip2/bzlib.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
@@ -48,7 +48,7 @@ void BZ2_bz__AssertH__fail ( int errcode )
|
||||
"component, you should also report this bug to the author(s)\n"
|
||||
"of that program. Please make an effort to report this bug;\n"
|
||||
"timely and accurate bug reports eventually lead to higher\n"
|
||||
"quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
|
||||
"quality software. Thanks. Julian Seward, 15 February 2005.\n\n",
|
||||
errcode,
|
||||
BZ2_bzlibVersion()
|
||||
);
|
||||
@@ -598,7 +598,6 @@ Bool unRLE_obuf_to_output_FAST ( DState* s )
|
||||
UInt32 c_tPos = s->tPos;
|
||||
char* cs_next_out = s->strm->next_out;
|
||||
unsigned int cs_avail_out = s->strm->avail_out;
|
||||
Int32 ro_blockSize100k = s->blockSize100k;
|
||||
/* end restore */
|
||||
|
||||
UInt32 avail_out_INIT = cs_avail_out;
|
||||
|
||||
4
3rdparty/bzip2/bzlib.h
vendored
4
3rdparty/bzip2/bzlib.h
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
16
3rdparty/bzip2/bzlib_private.h
vendored
16
3rdparty/bzip2/bzlib_private.h
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.6, 6-Sept-2010"
|
||||
#define BZ_VERSION "1.0.4, 20-Dec-2006"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
@@ -442,15 +442,11 @@ typedef
|
||||
/*-- Macros for decompression. --*/
|
||||
|
||||
#define BZ_GET_FAST(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
s->tPos = s->tt[s->tPos]; \
|
||||
cccc = (UChar)(s->tPos & 0xff); \
|
||||
s->tPos >>= 8;
|
||||
|
||||
#define BZ_GET_FAST_C(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
|
||||
c_tPos = c_tt[c_tPos]; \
|
||||
cccc = (UChar)(c_tPos & 0xff); \
|
||||
c_tPos >>= 8;
|
||||
@@ -473,10 +469,8 @@ typedef
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
4
3rdparty/bzip2/compress.c
vendored
4
3rdparty/bzip2/compress.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
4
3rdparty/bzip2/crctable.c
vendored
4
3rdparty/bzip2/crctable.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
24
3rdparty/bzip2/decompress.c
vendored
24
3rdparty/bzip2/decompress.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
@@ -381,13 +381,6 @@ Int32 BZ2_decompress ( DState* s )
|
||||
es = -1;
|
||||
N = 1;
|
||||
do {
|
||||
/* Check that N doesn't get too big, so that es doesn't
|
||||
go negative. The maximum value that can be
|
||||
RUNA/RUNB encoded is equal to the block size (post
|
||||
the initial RLE), viz, 900k, so bounding N at 2
|
||||
million should guard against overflow without
|
||||
rejecting any legitimate inputs. */
|
||||
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
|
||||
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
|
||||
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
|
||||
N = N * 2;
|
||||
@@ -492,28 +485,15 @@ Int32 BZ2_decompress ( DState* s )
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- Set up cftab to facilitate generation of T^(-1) --*/
|
||||
/* Check: unzftab entries in range. */
|
||||
for (i = 0; i <= 255; i++) {
|
||||
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
/* Actually generate cftab. */
|
||||
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];
|
||||
/* Check: cftab entries in range. */
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* Check: cftab entries non-descending. */
|
||||
for (i = 1; i <= 256; i++) {
|
||||
if (s->cftab[i-1] > s->cftab[i]) {
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
s->state_out_len = 0;
|
||||
s->state_out_ch = 0;
|
||||
|
||||
4
3rdparty/bzip2/huffman.c
vendored
4
3rdparty/bzip2/huffman.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
4
3rdparty/bzip2/randtable.c
vendored
4
3rdparty/bzip2/randtable.c
vendored
@@ -8,8 +8,8 @@
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
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.
|
||||
|
||||
261
3rdparty/google/dense_hash_map
vendored
Normal file
261
3rdparty/google/dense_hash_map
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ----
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// This is just a very thin wrapper over densehashtable.h, just
|
||||
// like sgi stl's stl_hash_map is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// NOTE: this is exactly like sparse_hash_map.h, with the word
|
||||
// "sparse" replaced by "dense", except for the addition of
|
||||
// set_empty_key().
|
||||
//
|
||||
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
|
||||
//
|
||||
// Otherwise your program will die in mysterious ways.
|
||||
//
|
||||
// In other respects, we adhere mostly to the STL semantics for
|
||||
// hash-map. One important exception is that insert() invalidates
|
||||
// iterators entirely. On the plus side, though, erase() doesn't
|
||||
// invalidate iterators at all, or even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// If you want to use erase() you must call set_deleted_key(),
|
||||
// in addition to set_empty_key(), after construction.
|
||||
// The deleted and empty keys must differ.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
//
|
||||
// 3) set_resizing_parameters(0.0, 0.8):
|
||||
// Setting the shrink_resize_percent to 0.0 guarantees
|
||||
// that the hash table will never shrink.
|
||||
//
|
||||
// Guide to what kind of hash_map to use:
|
||||
// (1) dense_hash_map: fastest, uses the most memory
|
||||
// (2) sparse_hash_map: slowest, uses the least memory
|
||||
// (3) hash_map (STL): in the middle
|
||||
// Typically I use sparse_hash_map when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_map otherwise. I
|
||||
// don't personally use dense_hash_map ever; the only use of
|
||||
// dense_hash_map I know of is to work around malloc() bugs in some
|
||||
// systems (dense_hash_map has a particularly simple allocation scheme).
|
||||
//
|
||||
// - dense_hash_map has, typically, a factor of 2 memory overhead (if your
|
||||
// data takes up X bytes, the hash_map uses X more bytes in overhead).
|
||||
// - sparse_hash_map has about 2 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-0.1/dense_hash_map.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _DENSE_HASH_MAP_H_
|
||||
#define _DENSE_HASH_MAP_H_
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <stdio.h> // for FILE * in read()/write()
|
||||
#include <algorithm> // for the default template args
|
||||
#include <functional> // for equal_to
|
||||
#include <memory> // for alloc<>
|
||||
#include <utility> // for pair<>
|
||||
#include HASH_FUN_H // defined in config.h
|
||||
#include <google/sparsehash/densehashtable.h>
|
||||
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
template <class Key, class T,
|
||||
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
|
||||
class EqualKey = STL_NAMESPACE::equal_to<Key>,
|
||||
class Alloc = STL_NAMESPACE::allocator<T> >
|
||||
class dense_hash_map {
|
||||
private:
|
||||
// Apparently select1st is not stl-standard, so we define our own
|
||||
struct SelectKey {
|
||||
const Key& operator()(const pair<const Key, T>& p) const {
|
||||
return p.first;
|
||||
}
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef dense_hashtable<pair<const Key, T>, Key, HashFcn,
|
||||
SelectKey, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef T data_type;
|
||||
typedef T mapped_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
|
||||
// Iterator functions
|
||||
iterator begin() { return rep.begin(); }
|
||||
iterator end() { return rep.end(); }
|
||||
const_iterator begin() const { return rep.begin(); }
|
||||
const_iterator end() const { return rep.end(); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit dense_hash_map(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) { }
|
||||
|
||||
template <class InputIterator>
|
||||
dense_hash_map(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
// This clears the hash map without resizing it down to the minimum
|
||||
// bucket count, but rather keeps the number of buckets constant
|
||||
void clear_no_resize() { rep.clear_no_resize(); }
|
||||
void swap(dense_hash_map& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
return rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) { return rep.find(key); }
|
||||
const_iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
data_type& operator[](const key_type& key) { // This is our value-add!
|
||||
iterator it = find(key);
|
||||
if (it != end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return insert(value_type(key, data_type())).first->second;
|
||||
}
|
||||
}
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
// Insertion routines
|
||||
pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
|
||||
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
|
||||
// required for std::insert_iterator; the passed-in iterator is ignored
|
||||
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
|
||||
|
||||
|
||||
// Deletion and empty routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted and empty buckets. You can change the
|
||||
// deleted key as time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_empty_key(const key_type& key) { // YOU MUST CALL THIS!
|
||||
rep.set_empty_key(value_type(key, data_type())); // rep wants a value
|
||||
}
|
||||
void set_deleted_key(const key_type& key) {
|
||||
rep.set_deleted_key(value_type(key, data_type())); // rep wants a value
|
||||
}
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const dense_hash_map& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const dense_hash_map& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
|
||||
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
|
||||
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
|
||||
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
|
||||
dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
|
||||
hm1.swap(hm2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _DENSE_HASH_MAP_H_ */
|
||||
245
3rdparty/google/dense_hash_set
vendored
Normal file
245
3rdparty/google/dense_hash_set
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ---
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// This is just a very thin wrapper over densehashtable.h, just
|
||||
// like sgi stl's stl_hash_set is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// This is more different from dense_hash_map than you might think,
|
||||
// because all iterators for sets are const (you obviously can't
|
||||
// change the key, and for sets there is no value).
|
||||
//
|
||||
// NOTE: this is exactly like sparse_hash_set.h, with the word
|
||||
// "sparse" replaced by "dense", except for the addition of
|
||||
// set_empty_key().
|
||||
//
|
||||
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
|
||||
//
|
||||
// Otherwise your program will die in mysterious ways.
|
||||
//
|
||||
// In other respects, we adhere mostly to the STL semantics for
|
||||
// hash-set. One important exception is that insert() invalidates
|
||||
// iterators entirely. On the plus side, though, erase() doesn't
|
||||
// invalidate iterators at all, or even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// If you want to use erase() you must call set_deleted_key(),
|
||||
// in addition to set_empty_key(), after construction.
|
||||
// The deleted and empty keys must differ.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
//
|
||||
// 3) set_resizing_parameters(0.0, 0.8):
|
||||
// Setting the shrink_resize_percent to 0.0 guarantees
|
||||
// that the hash table will never shrink.
|
||||
//
|
||||
// Guide to what kind of hash_set to use:
|
||||
// (1) dense_hash_set: fastest, uses the most memory
|
||||
// (2) sparse_hash_set: slowest, uses the least memory
|
||||
// (3) hash_set (STL): in the middle
|
||||
// Typically I use sparse_hash_set when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_set otherwise. I
|
||||
// don't personally use dense_hash_set ever; the only use of
|
||||
// dense_hash_set I know of is to work around malloc() bugs in some
|
||||
// systems (dense_hash_set has a particularly simple allocation scheme).
|
||||
//
|
||||
// - dense_hash_set has, typically, a factor of 2 memory overhead (if your
|
||||
// data takes up X bytes, the hash_set uses X more bytes in overhead).
|
||||
// - sparse_hash_set has about 2 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-0.1/dense_hash_set.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _DENSE_HASH_SET_H_
|
||||
#define _DENSE_HASH_SET_H_
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <stdio.h> // for FILE * in read()/write()
|
||||
#include <algorithm> // for the default template args
|
||||
#include <functional> // for equal_to
|
||||
#include <memory> // for alloc<>
|
||||
#include <utility> // for pair<>
|
||||
#include HASH_FUN_H // defined in config.h
|
||||
#include <google/sparsehash/densehashtable.h>
|
||||
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
template <class Value,
|
||||
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
|
||||
class EqualKey = STL_NAMESPACE::equal_to<Value>,
|
||||
class Alloc = STL_NAMESPACE::allocator<Value> >
|
||||
class dense_hash_set {
|
||||
private:
|
||||
// Apparently identity is not stl-standard, so we define our own
|
||||
struct Identity {
|
||||
Value& operator()(Value& v) const { return v; }
|
||||
const Value& operator()(const Value& v) const { return v; }
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef dense_hashtable<Value, Value, HashFcn, Identity, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::const_pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::const_reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::const_iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
|
||||
|
||||
// Iterator functions -- recall all iterators are const
|
||||
iterator begin() const { return rep.begin(); }
|
||||
iterator end() const { return rep.end(); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit dense_hash_set(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) { }
|
||||
|
||||
template <class InputIterator>
|
||||
dense_hash_set(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
// This clears the hash set without resizing it down to the minimum
|
||||
// bucket count, but rather keeps the number of buckets constant
|
||||
void clear_no_resize() { rep.clear_no_resize(); }
|
||||
void swap(dense_hash_set& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
return rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
// Insertion routines
|
||||
pair<iterator, bool> insert(const value_type& obj) {
|
||||
pair<typename ht::iterator, bool> p = rep.insert(obj);
|
||||
return pair<iterator, bool>(p.first, p.second); // const to non-const
|
||||
}
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
|
||||
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
|
||||
// required for std::insert_iterator; the passed-in iterator is ignored
|
||||
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
|
||||
|
||||
|
||||
// Deletion and empty routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted and empty buckets. You can change the
|
||||
// deleted key as time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_empty_key(const key_type& key) { rep.set_empty_key(key); }
|
||||
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const dense_hash_set& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const dense_hash_set& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
|
||||
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
|
||||
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
|
||||
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
template <class Val, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
|
||||
dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
|
||||
hs1.swap(hs2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _DENSE_HASH_SET_H_ */
|
||||
246
3rdparty/google/sparse_hash_map
vendored
Normal file
246
3rdparty/google/sparse_hash_map
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ---
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// This is just a very thin wrapper over sparsehashtable.h, just
|
||||
// like sgi stl's stl_hash_map is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// We adhere mostly to the STL semantics for hash-map. One important
|
||||
// exception is that insert() invalidates iterators entirely. On the
|
||||
// plus side, though, delete() doesn't invalidate iterators at all, or
|
||||
// even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// Unlike STL's hash_map, if you want to use erase() you
|
||||
// must call set_deleted_key() after construction.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This is what allows you to iterate over a hashtable
|
||||
// and call erase() without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
//
|
||||
// 3) set_resizing_parameters(0.0, 0.8):
|
||||
// Setting the shrink_resize_percent to 0.0 guarantees
|
||||
// that the hash table will never shrink.
|
||||
//
|
||||
// Guide to what kind of hash_map to use:
|
||||
// (1) dense_hash_map: fastest, uses the most memory
|
||||
// (2) sparse_hash_map: slowest, uses the least memory
|
||||
// (3) hash_map (STL): in the middle
|
||||
// Typically I use sparse_hash_map when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_map otherwise. I
|
||||
// don't personally use dense_hash_map ever; the only use of
|
||||
// dense_hash_map I know of is to work around malloc() bugs in some
|
||||
// systems (dense_hash_map has a particularly simple allocation scheme).
|
||||
//
|
||||
// - dense_hash_map has, typically, a factor of 2 memory overhead (if your
|
||||
// data takes up X bytes, the hash_map uses X more bytes in overhead).
|
||||
// - sparse_hash_map has about 2 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-0.1/sparse_hash_map.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _SPARSE_HASH_MAP_H_
|
||||
#define _SPARSE_HASH_MAP_H_
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <stdio.h> // for FILE * in read()/write()
|
||||
#include <algorithm> // for the default template args
|
||||
#include <functional> // for equal_to
|
||||
#include <memory> // for alloc<>
|
||||
#include <utility> // for pair<>
|
||||
#include HASH_FUN_H // defined in config.h
|
||||
#include <google/sparsehash/sparsehashtable.h>
|
||||
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
template <class Key, class T,
|
||||
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
|
||||
class EqualKey = STL_NAMESPACE::equal_to<Key>,
|
||||
class Alloc = STL_NAMESPACE::allocator<T> >
|
||||
class sparse_hash_map {
|
||||
private:
|
||||
// Apparently select1st is not stl-standard, so we define our own
|
||||
struct SelectKey {
|
||||
const Key& operator()(const pair<const Key, T>& p) const {
|
||||
return p.first;
|
||||
}
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef sparse_hashtable<pair<const Key, T>, Key, HashFcn,
|
||||
SelectKey, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef T data_type;
|
||||
typedef T mapped_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
|
||||
// Iterator functions
|
||||
iterator begin() { return rep.begin(); }
|
||||
iterator end() { return rep.end(); }
|
||||
const_iterator begin() const { return rep.begin(); }
|
||||
const_iterator end() const { return rep.end(); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit sparse_hash_map(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) { }
|
||||
|
||||
template <class InputIterator>
|
||||
sparse_hash_map(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
void swap(sparse_hash_map& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
return rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) { return rep.find(key); }
|
||||
const_iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
data_type& operator[](const key_type& key) { // This is our value-add!
|
||||
iterator it = find(key);
|
||||
if (it != end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return insert(value_type(key, data_type())).first->second;
|
||||
}
|
||||
}
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
// Insertion routines
|
||||
pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
|
||||
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
|
||||
// required for std::insert_iterator; the passed-in iterator is ignored
|
||||
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
|
||||
|
||||
|
||||
// Deletion routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted buckets. You can change the key as
|
||||
// time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_deleted_key(const key_type& key) {
|
||||
rep.set_deleted_key(value_type(key, data_type())); // rep wants a value
|
||||
}
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const sparse_hash_map& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const sparse_hash_map& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
|
||||
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
|
||||
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
|
||||
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
|
||||
sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
|
||||
hm1.swap(hm2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _SPARSE_HASH_MAP_H_ */
|
||||
231
3rdparty/google/sparse_hash_set
vendored
Normal file
231
3rdparty/google/sparse_hash_set
vendored
Normal file
@@ -0,0 +1,231 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ---
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// This is just a very thin wrapper over sparsehashtable.h, just
|
||||
// like sgi stl's stl_hash_set is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// This is more different from sparse_hash_map than you might think,
|
||||
// because all iterators for sets are const (you obviously can't
|
||||
// change the key, and for sets there is no value).
|
||||
//
|
||||
// We adhere mostly to the STL semantics for hash-set. One important
|
||||
// exception is that insert() invalidates iterators entirely. On the
|
||||
// plus side, though, delete() doesn't invalidate iterators at all, or
|
||||
// even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// Unlike STL's hash_map, if you want to use erase() you
|
||||
// must call set_deleted_key() after construction.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
//
|
||||
// 3) set_resizing_parameters(0.0, 0.8):
|
||||
// Setting the shrink_resize_percent to 0.0 guarantees
|
||||
// that the hash table will never shrink.
|
||||
//
|
||||
// Guide to what kind of hash_set to use:
|
||||
// (1) dense_hash_set: fastest, uses the most memory
|
||||
// (2) sparse_hash_set: slowest, uses the least memory
|
||||
// (3) hash_set (STL): in the middle
|
||||
// Typically I use sparse_hash_set when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_set otherwise. I
|
||||
// don't personally use dense_hash_set ever; the only use of
|
||||
// dense_hash_set I know of is to work around malloc() bugs in some
|
||||
// systems (dense_hash_set has a particularly simple allocation scheme).
|
||||
//
|
||||
// - dense_hash_set has, typically, a factor of 2 memory overhead (if your
|
||||
// data takes up X bytes, the hash_set uses X more bytes in overhead).
|
||||
// - sparse_hash_set has about 2 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-0.1/sparse_hash_set.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _SPARSE_HASH_SET_H_
|
||||
#define _SPARSE_HASH_SET_H_
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <stdio.h> // for FILE * in read()/write()
|
||||
#include <algorithm> // for the default template args
|
||||
#include <functional> // for equal_to
|
||||
#include <memory> // for alloc<>
|
||||
#include <utility> // for pair<>
|
||||
#include HASH_FUN_H // defined in config.h
|
||||
#include <google/sparsehash/sparsehashtable.h>
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
template <class Value,
|
||||
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
|
||||
class EqualKey = STL_NAMESPACE::equal_to<Value>,
|
||||
class Alloc = STL_NAMESPACE::allocator<Value> >
|
||||
class sparse_hash_set {
|
||||
private:
|
||||
// Apparently identity is not stl-standard, so we define our own
|
||||
struct Identity {
|
||||
Value& operator()(Value& v) const { return v; }
|
||||
const Value& operator()(const Value& v) const { return v; }
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef sparse_hashtable<Value, Value, HashFcn, Identity, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::const_pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::const_reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::const_iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
|
||||
|
||||
// Iterator functions -- recall all iterators are const
|
||||
iterator begin() const { return rep.begin(); }
|
||||
iterator end() const { return rep.end(); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit sparse_hash_set(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) { }
|
||||
|
||||
template <class InputIterator>
|
||||
sparse_hash_set(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal())
|
||||
: rep(expected_max_items_in_table, hf, eql) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
return rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
pair<iterator, iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
// Insertion routines
|
||||
pair<iterator, bool> insert(const value_type& obj) {
|
||||
pair<typename ht::iterator, bool> p = rep.insert(obj);
|
||||
return pair<iterator, bool>(p.first, p.second); // const to non-const
|
||||
}
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
|
||||
void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
|
||||
// required for std::insert_iterator; the passed-in iterator is ignored
|
||||
iterator insert(iterator, const value_type& obj) { return insert(obj).first; }
|
||||
|
||||
|
||||
// Deletion routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted buckets. You can change the key as
|
||||
// time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
bool write_metadata(FILE *fp) { return rep.write_metadata(fp); }
|
||||
bool read_metadata(FILE *fp) { return rep.read_metadata(fp); }
|
||||
bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
|
||||
bool read_nopointer_data(FILE *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
template <class Val, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
|
||||
sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
|
||||
hs1.swap(hs2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _SPARSE_HASH_SET_H_ */
|
||||
986
3rdparty/google/sparsehash/densehashtable.h
vendored
Normal file
986
3rdparty/google/sparsehash/densehashtable.h
vendored
Normal file
@@ -0,0 +1,986 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ---
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// A dense hashtable is a particular implementation of
|
||||
// a hashtable: one that is meant to minimize memory allocation.
|
||||
// It does this by using an array to store all the data. We
|
||||
// steal a value from the key space to indicate "empty" array
|
||||
// elements (ie indices where no item lives) and another to indicate
|
||||
// "deleted" elements.
|
||||
//
|
||||
// (Note it is possible to change the value of the delete key
|
||||
// on the fly; you can even remove it, though after that point
|
||||
// the hashtable is insert_only until you set it again. The empty
|
||||
// value however can't be changed.)
|
||||
//
|
||||
// To minimize allocation and pointer overhead, we use internal
|
||||
// probing, in which the hashtable is a single table, and collisions
|
||||
// are resolved by trying to insert again in another bucket. The
|
||||
// most cache-efficient internal probing schemes are linear probing
|
||||
// (which suffers, alas, from clumping) and quadratic probing, which
|
||||
// is what we implement by default.
|
||||
//
|
||||
// Type requirements: value_type is required to be Copy Constructible
|
||||
// and Default Constructible. It is not required to be (and commonly
|
||||
// isn't) Assignable.
|
||||
//
|
||||
// You probably shouldn't use this code directly. Use
|
||||
// <google/dense_hash_map> or <google/dense_hash_set> instead.
|
||||
|
||||
// You can change the following below:
|
||||
// HT_OCCUPANCY_FLT -- how full before we double size
|
||||
// HT_EMPTY_FLT -- how empty before we halve size
|
||||
// HT_MIN_BUCKETS -- default smallest bucket size
|
||||
//
|
||||
// You can also change enlarge_resize_percent (which defaults to
|
||||
// HT_OCCUPANCY_FLT), and shrink_resize_percent (which defaults to
|
||||
// HT_EMPTY_FLT) with set_resizing_parameters().
|
||||
//
|
||||
// How to decide what values to use?
|
||||
// shrink_resize_percent's default of .4 * OCCUPANCY_FLT, is probably good.
|
||||
// HT_MIN_BUCKETS is probably unnecessary since you can specify
|
||||
// (indirectly) the starting number of buckets at construct-time.
|
||||
// For enlarge_resize_percent, you can use this chart to try to trade-off
|
||||
// expected lookup time to the space taken up. By default, this
|
||||
// code uses quadratic probing, though you can change it to linear
|
||||
// via _JUMP below if you really want to.
|
||||
//
|
||||
// From http://www.augustana.ca/~mohrj/courses/1999.fall/csc210/lecture_notes/hashing.html
|
||||
// NUMBER OF PROBES / LOOKUP Successful Unsuccessful
|
||||
// Quadratic collision resolution 1 - ln(1-L) - L/2 1/(1-L) - L - ln(1-L)
|
||||
// Linear collision resolution [1+1/(1-L)]/2 [1+1/(1-L)2]/2
|
||||
//
|
||||
// -- enlarge_resize_percent -- 0.10 0.50 0.60 0.75 0.80 0.90 0.99
|
||||
// QUADRATIC COLLISION RES.
|
||||
// probes/successful lookup 1.05 1.44 1.62 2.01 2.21 2.85 5.11
|
||||
// probes/unsuccessful lookup 1.11 2.19 2.82 4.64 5.81 11.4 103.6
|
||||
// LINEAR COLLISION RES.
|
||||
// probes/successful lookup 1.06 1.5 1.75 2.5 3.0 5.5 50.5
|
||||
// probes/unsuccessful lookup 1.12 2.5 3.6 8.5 13.0 50.0 5000.0
|
||||
|
||||
#ifndef _DENSEHASHTABLE_H_
|
||||
#define _DENSEHASHTABLE_H_
|
||||
|
||||
// The probing method
|
||||
// Linear probing
|
||||
// #define JUMP_(key, num_probes) ( 1 )
|
||||
// Quadratic-ish probing
|
||||
#define JUMP_(key, num_probes) ( num_probes )
|
||||
|
||||
|
||||
// Hashtable class, used to implement the hashed associative containers
|
||||
// hash_set and hash_map.
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for abort()
|
||||
#include <algorithm> // For swap(), eg
|
||||
#include <iostream> // For cerr
|
||||
#include <memory> // For uninitialized_fill, uninitialized_copy
|
||||
#include <utility> // for pair<>
|
||||
#include <iterator> // for facts about iterator tags
|
||||
#include <google/type_traits.h> // for true_type, integral_constant, etc.
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
template <class Value, class Key, class HashFcn,
|
||||
class ExtractKey, class EqualKey, class Alloc>
|
||||
class dense_hashtable;
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct dense_hashtable_iterator;
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct dense_hashtable_const_iterator;
|
||||
|
||||
// We're just an array, but we need to skip over empty and deleted elements
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct dense_hashtable_iterator {
|
||||
public:
|
||||
typedef dense_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator;
|
||||
typedef dense_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator;
|
||||
|
||||
typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
|
||||
typedef V value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef V& reference; // Value
|
||||
typedef V* pointer;
|
||||
|
||||
// "Real" constructor and default constructor
|
||||
dense_hashtable_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h,
|
||||
pointer it, pointer it_end, bool advance)
|
||||
: ht(h), pos(it), end(it_end) {
|
||||
if (advance) advance_past_empty_and_deleted();
|
||||
}
|
||||
dense_hashtable_iterator() { }
|
||||
// The default destructor is fine; we don't define one
|
||||
// The default operator= is fine; we don't define one
|
||||
|
||||
// Happy dereferencer
|
||||
reference operator*() const { return *pos; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
|
||||
// Arithmetic. The only hard part is making sure that
|
||||
// we're not on an empty or marked-deleted array element
|
||||
void advance_past_empty_and_deleted() {
|
||||
while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) )
|
||||
++pos;
|
||||
}
|
||||
iterator& operator++() {
|
||||
assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this;
|
||||
}
|
||||
iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
|
||||
|
||||
// Comparison.
|
||||
bool operator==(const iterator& it) const { return pos == it.pos; }
|
||||
bool operator!=(const iterator& it) const { return pos != it.pos; }
|
||||
|
||||
|
||||
// The actual data
|
||||
const dense_hashtable<V,K,HF,ExK,EqK,A> *ht;
|
||||
pointer pos, end;
|
||||
};
|
||||
|
||||
|
||||
// Now do it all again, but with const-ness!
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct dense_hashtable_const_iterator {
|
||||
public:
|
||||
typedef dense_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator;
|
||||
typedef dense_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator;
|
||||
|
||||
typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
|
||||
typedef V value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef const V& reference; // Value
|
||||
typedef const V* pointer;
|
||||
|
||||
// "Real" constructor and default constructor
|
||||
dense_hashtable_const_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h,
|
||||
pointer it, pointer it_end, bool advance)
|
||||
: ht(h), pos(it), end(it_end) {
|
||||
if (advance) advance_past_empty_and_deleted();
|
||||
}
|
||||
dense_hashtable_const_iterator() { }
|
||||
// This lets us convert regular iterators to const iterators
|
||||
dense_hashtable_const_iterator(const iterator &it)
|
||||
: ht(it.ht), pos(it.pos), end(it.end) { }
|
||||
// The default destructor is fine; we don't define one
|
||||
// The default operator= is fine; we don't define one
|
||||
|
||||
// Happy dereferencer
|
||||
reference operator*() const { return *pos; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
|
||||
// Arithmetic. The only hard part is making sure that
|
||||
// we're not on an empty or marked-deleted array element
|
||||
void advance_past_empty_and_deleted() {
|
||||
while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) )
|
||||
++pos;
|
||||
}
|
||||
const_iterator& operator++() {
|
||||
assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this;
|
||||
}
|
||||
const_iterator operator++(int) { const_iterator tmp(*this); ++*this; return tmp; }
|
||||
|
||||
// Comparison.
|
||||
bool operator==(const const_iterator& it) const { return pos == it.pos; }
|
||||
bool operator!=(const const_iterator& it) const { return pos != it.pos; }
|
||||
|
||||
|
||||
// The actual data
|
||||
const dense_hashtable<V,K,HF,ExK,EqK,A> *ht;
|
||||
pointer pos, end;
|
||||
};
|
||||
|
||||
template <class Value, class Key, class HashFcn,
|
||||
class ExtractKey, class EqualKey, class Alloc>
|
||||
class dense_hashtable {
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef HashFcn hasher;
|
||||
typedef EqualKey key_equal;
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef dense_hashtable_iterator<Value, Key, HashFcn,
|
||||
ExtractKey, EqualKey, Alloc>
|
||||
iterator;
|
||||
|
||||
typedef dense_hashtable_const_iterator<Value, Key, HashFcn,
|
||||
ExtractKey, EqualKey, Alloc>
|
||||
const_iterator;
|
||||
|
||||
// How full we let the table get before we resize. Knuth says .8 is
|
||||
// good -- higher causes us to probe too much, though saves memory
|
||||
static const float HT_OCCUPANCY_FLT; // = 0.8;
|
||||
|
||||
// How empty we let the table get before we resize lower.
|
||||
// (0.0 means never resize lower.)
|
||||
// It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
|
||||
static const float HT_EMPTY_FLT; // = 0.4 * HT_OCCUPANCY_FLT
|
||||
|
||||
// Minimum size we're willing to let hashtables be.
|
||||
// Must be a power of two, and at least 4.
|
||||
// Note, however, that for a given hashtable, the initial size is a
|
||||
// function of the first constructor arg, and may be >HT_MIN_BUCKETS.
|
||||
static const size_t HT_MIN_BUCKETS = 4;
|
||||
|
||||
// By default, if you don't specify a hashtable size at
|
||||
// construction-time, we use this size. Must be a power of two, and
|
||||
// at least HT_MIN_BUCKETS.
|
||||
static const size_t HT_DEFAULT_STARTING_BUCKETS = 32;
|
||||
|
||||
|
||||
// ITERATOR FUNCTIONS
|
||||
iterator begin() { return iterator(this, table,
|
||||
table + num_buckets, true); }
|
||||
iterator end() { return iterator(this, table + num_buckets,
|
||||
table + num_buckets, true); }
|
||||
const_iterator begin() const { return const_iterator(this, table,
|
||||
table+num_buckets,true);}
|
||||
const_iterator end() const { return const_iterator(this, table + num_buckets,
|
||||
table+num_buckets,true);}
|
||||
|
||||
// ACCESSOR FUNCTIONS for the things we templatize on, basically
|
||||
hasher hash_funct() const { return hash; }
|
||||
key_equal key_eq() const { return equals; }
|
||||
|
||||
// Annoyingly, we can't copy values around, because they might have
|
||||
// const components (they're probably pair<const X, Y>). We use
|
||||
// explicit destructor invocation and placement new to get around
|
||||
// this. Arg.
|
||||
private:
|
||||
void set_value(value_type* dst, const value_type& src) {
|
||||
dst->~value_type();
|
||||
new(dst) value_type(src);
|
||||
}
|
||||
|
||||
void destroy_buckets(size_type first, size_type last) {
|
||||
for ( ; first != last; ++first)
|
||||
table[first].~value_type();
|
||||
}
|
||||
|
||||
// DELETE HELPER FUNCTIONS
|
||||
// This lets the user describe a key that will indicate deleted
|
||||
// table entries. This key should be an "impossible" entry --
|
||||
// if you try to insert it for real, you won't be able to retrieve it!
|
||||
// (NB: while you pass in an entire value, only the key part is looked
|
||||
// at. This is just because I don't know how to assign just a key.)
|
||||
private:
|
||||
void squash_deleted() { // gets rid of any deleted entries we have
|
||||
if ( num_deleted ) { // get rid of deleted before writing
|
||||
dense_hashtable tmp(*this); // copying will get rid of deleted
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
assert(num_deleted == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
void set_deleted_key(const value_type &val) {
|
||||
// the empty indicator (if specified) and the deleted indicator
|
||||
// must be different
|
||||
assert(!use_empty || !equals(get_key(val), get_key(emptyval)));
|
||||
// It's only safe to change what "deleted" means if we purge deleted guys
|
||||
squash_deleted();
|
||||
use_deleted = true;
|
||||
set_value(&delval, val);
|
||||
}
|
||||
void clear_deleted_key() {
|
||||
squash_deleted();
|
||||
use_deleted = false;
|
||||
}
|
||||
|
||||
// These are public so the iterators can use them
|
||||
// True if the item at position bucknum is "deleted" marker
|
||||
bool test_deleted(size_type bucknum) const {
|
||||
// The num_deleted test is crucial for read(): after read(), the ht values
|
||||
// are garbage, and we don't want to think some of them are deleted.
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(table[bucknum])));
|
||||
}
|
||||
bool test_deleted(const iterator &it) const {
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(*it)));
|
||||
}
|
||||
bool test_deleted(const const_iterator &it) const {
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(*it)));
|
||||
}
|
||||
// Set it so test_deleted is true. true if object didn't used to be deleted
|
||||
// See below (at erase()) to explain why we allow const_iterators
|
||||
bool set_deleted(const_iterator &it) {
|
||||
assert(use_deleted); // bad if set_deleted_key() wasn't called
|
||||
bool retval = !test_deleted(it);
|
||||
// &* converts from iterator to value-type
|
||||
set_value(const_cast<value_type*>(&(*it)), delval);
|
||||
return retval;
|
||||
}
|
||||
// Set it so test_deleted is false. true if object used to be deleted
|
||||
bool clear_deleted(const_iterator &it) {
|
||||
assert(use_deleted); // bad if set_deleted_key() wasn't called
|
||||
// happens automatically when we assign something else in its place
|
||||
return test_deleted(it);
|
||||
}
|
||||
|
||||
// EMPTY HELPER FUNCTIONS
|
||||
// This lets the user describe a key that will indicate empty (unused)
|
||||
// table entries. This key should be an "impossible" entry --
|
||||
// if you try to insert it for real, you won't be able to retrieve it!
|
||||
// (NB: while you pass in an entire value, only the key part is looked
|
||||
// at. This is just because I don't know how to assign just a key.)
|
||||
public:
|
||||
// These are public so the iterators can use them
|
||||
// True if the item at position bucknum is "empty" marker
|
||||
bool test_empty(size_type bucknum) const {
|
||||
assert(use_empty); // we always need to know what's empty!
|
||||
return equals(get_key(emptyval), get_key(table[bucknum]));
|
||||
}
|
||||
bool test_empty(const iterator &it) const {
|
||||
assert(use_empty); // we always need to know what's empty!
|
||||
return equals(get_key(emptyval), get_key(*it));
|
||||
}
|
||||
bool test_empty(const const_iterator &it) const {
|
||||
assert(use_empty); // we always need to know what's empty!
|
||||
return equals(get_key(emptyval), get_key(*it));
|
||||
}
|
||||
|
||||
private:
|
||||
// You can either set a range empty or an individual element
|
||||
void set_empty(size_type bucknum) {
|
||||
assert(use_empty);
|
||||
set_value(&table[bucknum], emptyval);
|
||||
}
|
||||
void fill_range_with_empty(value_type* table_start, value_type* table_end) {
|
||||
// Like set_empty(range), but doesn't destroy previous contents
|
||||
STL_NAMESPACE::uninitialized_fill(table_start, table_end, emptyval);
|
||||
}
|
||||
void set_empty(size_type buckstart, size_type buckend) {
|
||||
assert(use_empty);
|
||||
destroy_buckets(buckstart, buckend);
|
||||
fill_range_with_empty(table + buckstart, table + buckend);
|
||||
}
|
||||
|
||||
public:
|
||||
// TODO(csilvers): change all callers of this to pass in a key instead,
|
||||
// and take a const key_type instead of const value_type.
|
||||
void set_empty_key(const value_type &val) {
|
||||
// Once you set the empty key, you can't change it
|
||||
assert(!use_empty);
|
||||
// The deleted indicator (if specified) and the empty indicator
|
||||
// must be different.
|
||||
assert(!use_deleted || !equals(get_key(val), get_key(delval)));
|
||||
use_empty = true;
|
||||
set_value(&emptyval, val);
|
||||
|
||||
assert(!table); // must set before first use
|
||||
// num_buckets was set in constructor even though table was NULL
|
||||
table = (value_type *) malloc(num_buckets * sizeof(*table));
|
||||
assert(table);
|
||||
fill_range_with_empty(table, table + num_buckets);
|
||||
}
|
||||
|
||||
// FUNCTIONS CONCERNING SIZE
|
||||
public:
|
||||
size_type size() const { return num_elements - num_deleted; }
|
||||
// Buckets are always a power of 2
|
||||
size_type max_size() const { return (size_type(-1) >> 1U) + 1; }
|
||||
bool empty() const { return size() == 0; }
|
||||
size_type bucket_count() const { return num_buckets; }
|
||||
size_type max_bucket_count() const { return max_size(); }
|
||||
size_type nonempty_bucket_count() const { return num_elements; }
|
||||
|
||||
private:
|
||||
// Because of the above, size_type(-1) is never legal; use it for errors
|
||||
static const size_type ILLEGAL_BUCKET = size_type(-1);
|
||||
|
||||
private:
|
||||
// This is the smallest size a hashtable can be without being too crowded
|
||||
// If you like, you can give a min #buckets as well as a min #elts
|
||||
size_type min_size(size_type num_elts, size_type min_buckets_wanted) {
|
||||
size_type sz = HT_MIN_BUCKETS; // min buckets allowed
|
||||
while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent )
|
||||
sz *= 2;
|
||||
return sz;
|
||||
}
|
||||
|
||||
// Used after a string of deletes
|
||||
void maybe_shrink() {
|
||||
assert(num_elements >= num_deleted);
|
||||
assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two
|
||||
assert(bucket_count() >= HT_MIN_BUCKETS);
|
||||
|
||||
// If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS,
|
||||
// we'll never shrink until you get relatively big, and we'll never
|
||||
// shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something
|
||||
// like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will
|
||||
// shrink us down to HT_MIN_BUCKETS buckets, which is too small.
|
||||
if (shrink_threshold > 0 &&
|
||||
(num_elements-num_deleted) < shrink_threshold &&
|
||||
bucket_count() > HT_DEFAULT_STARTING_BUCKETS ) {
|
||||
size_type sz = bucket_count() / 2; // find how much we should shrink
|
||||
while ( sz > HT_DEFAULT_STARTING_BUCKETS &&
|
||||
(num_elements - num_deleted) < sz * shrink_resize_percent )
|
||||
sz /= 2; // stay a power of 2
|
||||
dense_hashtable tmp(*this, sz); // Do the actual resizing
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
consider_shrink = false; // because we just considered it
|
||||
}
|
||||
|
||||
// We'll let you resize a hashtable -- though this makes us copy all!
|
||||
// When you resize, you say, "make it big enough for this many more elements"
|
||||
void resize_delta(size_type delta) {
|
||||
if ( consider_shrink ) // see if lots of deletes happened
|
||||
maybe_shrink();
|
||||
if ( bucket_count() > HT_MIN_BUCKETS &&
|
||||
(num_elements + delta) <= enlarge_threshold )
|
||||
return; // we're ok as we are
|
||||
|
||||
// Sometimes, we need to resize just to get rid of all the
|
||||
// "deleted" buckets that are clogging up the hashtable. So when
|
||||
// deciding whether to resize, count the deleted buckets (which
|
||||
// are currently taking up room). But later, when we decide what
|
||||
// size to resize to, *don't* count deleted buckets, since they
|
||||
// get discarded during the resize.
|
||||
const size_type needed_size = min_size(num_elements + delta, 0);
|
||||
if ( needed_size > bucket_count() ) { // we don't have enough buckets
|
||||
const size_type resize_to = min_size(num_elements - num_deleted + delta,
|
||||
0);
|
||||
dense_hashtable tmp(*this, resize_to);
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Increase number of buckets, assuming value_type has trivial copy
|
||||
// constructor and destructor. (Really, we want it to have "trivial
|
||||
// move", because that's what realloc does. But there's no way to
|
||||
// capture that using type_traits, so we pretend that move(x, y) is
|
||||
// equivalent to "x.~T(); new(x) T(y);" which is pretty much
|
||||
// correct, if a bit conservative.)
|
||||
void expand_array(size_t resize_to, true_type) {
|
||||
table = (value_type *) realloc(table, resize_to * sizeof(value_type));
|
||||
assert(table);
|
||||
fill_range_with_empty(table + num_buckets, table + resize_to);
|
||||
}
|
||||
|
||||
// Increase number of buckets, without special assumptions about value_type.
|
||||
// TODO(austern): make this exception safe. Handle exceptions from
|
||||
// value_type's copy constructor.
|
||||
void expand_array(size_t resize_to, false_type) {
|
||||
value_type* new_table =
|
||||
(value_type *) malloc(resize_to * sizeof(value_type));
|
||||
assert(new_table);
|
||||
STL_NAMESPACE::uninitialized_copy(table, table + num_buckets, new_table);
|
||||
fill_range_with_empty(new_table + num_buckets, new_table + resize_to);
|
||||
destroy_buckets(0, num_buckets);
|
||||
free(table);
|
||||
table = new_table;
|
||||
}
|
||||
|
||||
// Used to actually do the rehashing when we grow/shrink a hashtable
|
||||
void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted) {
|
||||
clear(); // clear table, set num_deleted to 0
|
||||
|
||||
// If we need to change the size of our table, do it now
|
||||
const size_type resize_to = min_size(ht.size(), min_buckets_wanted);
|
||||
if ( resize_to > bucket_count() ) { // we don't have enough buckets
|
||||
typedef integral_constant<bool,
|
||||
(has_trivial_copy<value_type>::value &&
|
||||
has_trivial_destructor<value_type>::value)>
|
||||
realloc_ok; // we pretend mv(x,y) == "x.~T(); new(x) T(y)"
|
||||
expand_array(resize_to, realloc_ok());
|
||||
num_buckets = resize_to;
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// We use a normal iterator to get non-deleted bcks from ht
|
||||
// We could use insert() here, but since we know there are
|
||||
// no duplicates and no deleted items, we can be more efficient
|
||||
assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
|
||||
for ( const_iterator it = ht.begin(); it != ht.end(); ++it ) {
|
||||
size_type num_probes = 0; // how many times we've probed
|
||||
size_type bucknum;
|
||||
const size_type bucket_count_minus_one = bucket_count() - 1;
|
||||
for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
|
||||
!test_empty(bucknum); // not empty
|
||||
bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) {
|
||||
++num_probes;
|
||||
assert(num_probes < bucket_count()); // or else the hashtable is full
|
||||
}
|
||||
set_value(&table[bucknum], *it); // copies the value to here
|
||||
num_elements++;
|
||||
}
|
||||
}
|
||||
|
||||
// Required by the spec for hashed associative container
|
||||
public:
|
||||
// Though the docs say this should be num_buckets, I think it's much
|
||||
// more useful as req_elements. As a special feature, calling with
|
||||
// req_elements==0 will cause us to shrink if we can, saving space.
|
||||
void resize(size_type req_elements) { // resize to this or larger
|
||||
if ( consider_shrink || req_elements == 0 )
|
||||
maybe_shrink();
|
||||
if ( req_elements > num_elements )
|
||||
return resize_delta(req_elements - num_elements);
|
||||
}
|
||||
|
||||
// Change the value of shrink_resize_percent and
|
||||
// enlarge_resize_percent. The description at the beginning of this
|
||||
// file explains how to choose the values. Setting the shrink
|
||||
// parameter to 0.0 ensures that the table never shrinks.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
assert(shrink >= 0.0);
|
||||
assert(grow <= 1.0);
|
||||
assert(shrink <= grow/2.0);
|
||||
shrink_resize_percent = shrink;
|
||||
enlarge_resize_percent = grow;
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// CONSTRUCTORS -- as required by the specs, we take a size,
|
||||
// but also let you specify a hashfunction, key comparator,
|
||||
// and key extractor. We also define a copy constructor and =.
|
||||
// DESTRUCTOR -- needs to free the table
|
||||
explicit dense_hashtable(size_type expected_max_items_in_table = 0,
|
||||
const HashFcn& hf = HashFcn(),
|
||||
const EqualKey& eql = EqualKey(),
|
||||
const ExtractKey& ext = ExtractKey())
|
||||
: hash(hf), equals(eql), get_key(ext), num_deleted(0),
|
||||
use_deleted(false), use_empty(false),
|
||||
delval(), emptyval(), enlarge_resize_percent(HT_OCCUPANCY_FLT),
|
||||
shrink_resize_percent(HT_EMPTY_FLT), table(NULL),
|
||||
num_buckets(expected_max_items_in_table == 0
|
||||
? HT_DEFAULT_STARTING_BUCKETS
|
||||
: min_size(expected_max_items_in_table, 0)),
|
||||
num_elements(0) {
|
||||
// table is NULL until emptyval is set. However, we set num_buckets
|
||||
// here so we know how much space to allocate once emptyval is set
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// As a convenience for resize(), we allow an optional second argument
|
||||
// which lets you make this new hashtable a different size than ht
|
||||
dense_hashtable(const dense_hashtable& ht,
|
||||
size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
|
||||
: hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_deleted(0),
|
||||
use_deleted(ht.use_deleted), use_empty(ht.use_empty),
|
||||
delval(ht.delval), emptyval(ht.emptyval),
|
||||
enlarge_resize_percent(ht.enlarge_resize_percent),
|
||||
shrink_resize_percent(ht.shrink_resize_percent), table(NULL),
|
||||
num_buckets(0), num_elements(0) {
|
||||
reset_thresholds();
|
||||
copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries
|
||||
}
|
||||
|
||||
dense_hashtable& operator= (const dense_hashtable& ht) {
|
||||
if (&ht == this) return *this; // don't copy onto ourselves
|
||||
clear();
|
||||
hash = ht.hash;
|
||||
equals = ht.equals;
|
||||
get_key = ht.get_key;
|
||||
use_deleted = ht.use_deleted;
|
||||
use_empty = ht.use_empty;
|
||||
set_value(&delval, ht.delval);
|
||||
set_value(&emptyval, ht.emptyval);
|
||||
enlarge_resize_percent = ht.enlarge_resize_percent;
|
||||
shrink_resize_percent = ht.shrink_resize_percent;
|
||||
copy_from(ht, HT_MIN_BUCKETS); // sets num_deleted to 0 too
|
||||
return *this;
|
||||
}
|
||||
|
||||
~dense_hashtable() {
|
||||
if (table) {
|
||||
destroy_buckets(0, num_buckets);
|
||||
free(table);
|
||||
}
|
||||
}
|
||||
|
||||
// Many STL algorithms use swap instead of copy constructors
|
||||
void swap(dense_hashtable& ht) {
|
||||
STL_NAMESPACE::swap(hash, ht.hash);
|
||||
STL_NAMESPACE::swap(equals, ht.equals);
|
||||
STL_NAMESPACE::swap(get_key, ht.get_key);
|
||||
STL_NAMESPACE::swap(num_deleted, ht.num_deleted);
|
||||
STL_NAMESPACE::swap(use_deleted, ht.use_deleted);
|
||||
STL_NAMESPACE::swap(use_empty, ht.use_empty);
|
||||
STL_NAMESPACE::swap(enlarge_resize_percent, ht.enlarge_resize_percent);
|
||||
STL_NAMESPACE::swap(shrink_resize_percent, ht.shrink_resize_percent);
|
||||
{ value_type tmp; // for annoying reasons, swap() doesn't work
|
||||
set_value(&tmp, delval);
|
||||
set_value(&delval, ht.delval);
|
||||
set_value(&ht.delval, tmp);
|
||||
}
|
||||
{ value_type tmp; // for annoying reasons, swap() doesn't work
|
||||
set_value(&tmp, emptyval);
|
||||
set_value(&emptyval, ht.emptyval);
|
||||
set_value(&ht.emptyval, tmp);
|
||||
}
|
||||
STL_NAMESPACE::swap(table, ht.table);
|
||||
STL_NAMESPACE::swap(num_buckets, ht.num_buckets);
|
||||
STL_NAMESPACE::swap(num_elements, ht.num_elements);
|
||||
reset_thresholds();
|
||||
ht.reset_thresholds();
|
||||
}
|
||||
|
||||
// It's always nice to be able to clear a table without deallocating it
|
||||
void clear() {
|
||||
if (table)
|
||||
destroy_buckets(0, num_buckets);
|
||||
num_buckets = min_size(0,0); // our new size
|
||||
reset_thresholds();
|
||||
table = (value_type *) realloc(table, num_buckets * sizeof(*table));
|
||||
assert(table);
|
||||
fill_range_with_empty(table, table + num_buckets);
|
||||
num_elements = 0;
|
||||
num_deleted = 0;
|
||||
}
|
||||
|
||||
// Clear the table without resizing it.
|
||||
// Mimicks the stl_hashtable's behaviour when clear()-ing in that it
|
||||
// does not modify the bucket count
|
||||
void clear_no_resize() {
|
||||
if (table) {
|
||||
set_empty(0, num_buckets);
|
||||
}
|
||||
// don't consider to shrink before another erase()
|
||||
reset_thresholds();
|
||||
num_elements = 0;
|
||||
num_deleted = 0;
|
||||
}
|
||||
|
||||
// LOOKUP ROUTINES
|
||||
private:
|
||||
// Returns a pair of positions: 1st where the object is, 2nd where
|
||||
// it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET
|
||||
// if object is not found; 2nd is ILLEGAL_BUCKET if it is.
|
||||
// Note: because of deletions where-to-insert is not trivial: it's the
|
||||
// first deleted bucket we see, as long as we don't find the key later
|
||||
pair<size_type, size_type> find_position(const key_type &key) const {
|
||||
size_type num_probes = 0; // how many times we've probed
|
||||
const size_type bucket_count_minus_one = bucket_count() - 1;
|
||||
size_type bucknum = hash(key) & bucket_count_minus_one;
|
||||
size_type insert_pos = ILLEGAL_BUCKET; // where we would insert
|
||||
while ( 1 ) { // probe until something happens
|
||||
if ( test_empty(bucknum) ) { // bucket is empty
|
||||
if ( insert_pos == ILLEGAL_BUCKET ) // found no prior place to insert
|
||||
return pair<size_type,size_type>(ILLEGAL_BUCKET, bucknum);
|
||||
else
|
||||
return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos);
|
||||
|
||||
} else if ( test_deleted(bucknum) ) {// keep searching, but mark to insert
|
||||
if ( insert_pos == ILLEGAL_BUCKET )
|
||||
insert_pos = bucknum;
|
||||
|
||||
} else if ( equals(key, get_key(table[bucknum])) ) {
|
||||
return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET);
|
||||
}
|
||||
++num_probes; // we're doing another probe
|
||||
bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
|
||||
assert(num_probes < bucket_count()); // don't probe too many times!
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
iterator find(const key_type& key) {
|
||||
if ( size() == 0 ) return end();
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
|
||||
return end();
|
||||
else
|
||||
return iterator(this, table + pos.first, table + num_buckets, false);
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& key) const {
|
||||
if ( size() == 0 ) return end();
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
|
||||
return end();
|
||||
else
|
||||
return const_iterator(this, table + pos.first, table+num_buckets, false);
|
||||
}
|
||||
|
||||
// Counts how many elements have key key. For maps, it's either 0 or 1.
|
||||
size_type count(const key_type &key) const {
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
return pos.first == ILLEGAL_BUCKET ? 0 : 1;
|
||||
}
|
||||
|
||||
// Likewise, equal_range doesn't really make sense for us. Oh well.
|
||||
pair<iterator,iterator> equal_range(const key_type& key) {
|
||||
const iterator pos = find(key); // either an iterator or end
|
||||
return pair<iterator,iterator>(pos, pos);
|
||||
}
|
||||
pair<const_iterator,const_iterator> equal_range(const key_type& key) const {
|
||||
const const_iterator pos = find(key); // either an iterator or end
|
||||
return pair<iterator,iterator>(pos, pos);
|
||||
}
|
||||
|
||||
|
||||
// INSERTION ROUTINES
|
||||
private:
|
||||
// If you know *this is big enough to hold obj, use this routine
|
||||
pair<iterator, bool> insert_noresize(const value_type& obj) {
|
||||
// First, double-check we're not inserting delval or emptyval
|
||||
assert(!use_empty || !equals(get_key(obj), get_key(emptyval)));
|
||||
assert(!use_deleted || !equals(get_key(obj), get_key(delval)));
|
||||
const pair<size_type,size_type> pos = find_position(get_key(obj));
|
||||
if ( pos.first != ILLEGAL_BUCKET) { // object was already there
|
||||
return pair<iterator,bool>(iterator(this, table + pos.first,
|
||||
table + num_buckets, false),
|
||||
false); // false: we didn't insert
|
||||
} else { // pos.second says where to put it
|
||||
if ( test_deleted(pos.second) ) { // just replace if it's been del.
|
||||
const_iterator delpos(this, table + pos.second, // shrug:
|
||||
table + num_buckets, false);// shouldn't need const
|
||||
clear_deleted(delpos);
|
||||
assert( num_deleted > 0);
|
||||
--num_deleted; // used to be, now it isn't
|
||||
} else {
|
||||
++num_elements; // replacing an empty bucket
|
||||
}
|
||||
set_value(&table[pos.second], obj);
|
||||
return pair<iterator,bool>(iterator(this, table + pos.second,
|
||||
table + num_buckets, false),
|
||||
true); // true: we did insert
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// This is the normal insert routine, used by the outside world
|
||||
pair<iterator, bool> insert(const value_type& obj) {
|
||||
resize_delta(1); // adding an object, grow if need be
|
||||
return insert_noresize(obj);
|
||||
}
|
||||
|
||||
// When inserting a lot at a time, we specialize on the type of iterator
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) {
|
||||
// specializes on iterator type
|
||||
insert(f, l, typename STL_NAMESPACE::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
|
||||
// Iterator supports operator-, resize before inserting
|
||||
template <class ForwardIterator>
|
||||
void insert(ForwardIterator f, ForwardIterator l,
|
||||
STL_NAMESPACE::forward_iterator_tag) {
|
||||
size_type n = STL_NAMESPACE::distance(f, l); // TODO(csilvers): standard?
|
||||
resize_delta(n);
|
||||
for ( ; n > 0; --n, ++f)
|
||||
insert_noresize(*f);
|
||||
}
|
||||
|
||||
// Arbitrary iterator, can't tell how much to resize
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l,
|
||||
STL_NAMESPACE::input_iterator_tag) {
|
||||
for ( ; f != l; ++f)
|
||||
insert(*f);
|
||||
}
|
||||
|
||||
|
||||
// DELETION ROUTINES
|
||||
size_type erase(const key_type& key) {
|
||||
// First, double-check we're not trying to erase delval or emptyval
|
||||
assert(!use_empty || !equals(key, get_key(emptyval)));
|
||||
assert(!use_deleted || !equals(key, get_key(delval)));
|
||||
const_iterator pos = find(key); // shrug: shouldn't need to be const
|
||||
if ( pos != end() ) {
|
||||
assert(!test_deleted(pos)); // or find() shouldn't have returned it
|
||||
set_deleted(pos);
|
||||
++num_deleted;
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
return 1; // because we deleted one thing
|
||||
} else {
|
||||
return 0; // because we deleted nothing
|
||||
}
|
||||
}
|
||||
|
||||
// This is really evil: really it should be iterator, not const_iterator.
|
||||
// But...the only reason keys are const is to allow lookup.
|
||||
// Since that's a moot issue for deleted keys, we allow const_iterators
|
||||
void erase(const_iterator pos) {
|
||||
if ( pos == end() ) return; // sanity check
|
||||
if ( set_deleted(pos) ) { // true if object has been newly deleted
|
||||
++num_deleted;
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
}
|
||||
}
|
||||
|
||||
void erase(const_iterator f, const_iterator l) {
|
||||
for ( ; f != l; ++f) {
|
||||
if ( set_deleted(f) ) // should always be true
|
||||
++num_deleted;
|
||||
}
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
}
|
||||
|
||||
|
||||
// COMPARISON
|
||||
bool operator==(const dense_hashtable& ht) const {
|
||||
if (size() != ht.size()) {
|
||||
return false;
|
||||
} else if (this == &ht) {
|
||||
return true;
|
||||
} else {
|
||||
// Iterate through the elements in "this" and see if the
|
||||
// corresponding element is in ht
|
||||
for ( const_iterator it = begin(); it != end(); ++it ) {
|
||||
const_iterator it2 = ht.find(get_key(*it));
|
||||
if ((it2 == ht.end()) || (*it != *it2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool operator!=(const dense_hashtable& ht) const {
|
||||
return !(*this == ht);
|
||||
}
|
||||
|
||||
|
||||
// I/O
|
||||
// We support reading and writing hashtables to disk. Alas, since
|
||||
// I don't know how to write a hasher or key_equal, you have to make
|
||||
// sure everything but the table is the same. We compact before writing
|
||||
//
|
||||
// NOTE: These functions are currently TODO. They've not been implemented.
|
||||
bool write_metadata(FILE *fp) {
|
||||
squash_deleted(); // so we don't have to worry about delval
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
bool read_metadata(FILE *fp) {
|
||||
num_deleted = 0; // since we got rid before writing
|
||||
assert(use_empty); // have to set this before calling us
|
||||
if (table) free(table); // we'll make our own
|
||||
// TODO: read magic number
|
||||
// TODO: read num_buckets
|
||||
reset_thresholds();
|
||||
table = (value_type *) malloc(num_buckets * sizeof(*table));
|
||||
assert(table);
|
||||
fill_range_with_empty(table, table + num_buckets);
|
||||
// TODO: read num_elements
|
||||
for ( size_type i = 0; i < num_elements; ++i ) {
|
||||
// TODO: read bucket_num
|
||||
// TODO: set with non-empty, non-deleted value
|
||||
}
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
// If your keys and values are simple enough, we can write them to
|
||||
// disk for you. "simple enough" means value_type is a POD type
|
||||
// that contains no pointers. However, we don't try to normalize
|
||||
// endianness
|
||||
bool write_nopointer_data(FILE *fp) const {
|
||||
for ( const_iterator it = begin(); it != end(); ++it ) {
|
||||
// TODO: skip empty/deleted values
|
||||
if ( !fwrite(&*it, sizeof(*it), 1, fp) ) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// When reading, we have to override the potential const-ness of *it
|
||||
bool read_nopointer_data(FILE *fp) {
|
||||
for ( iterator it = begin(); it != end(); ++it ) {
|
||||
// TODO: skip empty/deleted values
|
||||
if ( !fread(reinterpret_cast<void*>(&(*it)), sizeof(*it), 1, fp) )
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// The actual data
|
||||
hasher hash; // required by hashed_associative_container
|
||||
key_equal equals;
|
||||
ExtractKey get_key;
|
||||
size_type num_deleted; // how many occupied buckets are marked deleted
|
||||
bool use_deleted; // false until delval has been set
|
||||
bool use_empty; // you must do this before you start
|
||||
value_type delval; // which key marks deleted entries
|
||||
value_type emptyval; // which key marks unused entries
|
||||
float enlarge_resize_percent; // how full before resize
|
||||
float shrink_resize_percent; // how empty before resize
|
||||
size_type shrink_threshold; // num_buckets * shrink_resize_percent
|
||||
size_type enlarge_threshold; // num_buckets * enlarge_resize_percent
|
||||
value_type *table;
|
||||
size_type num_buckets;
|
||||
size_type num_elements;
|
||||
bool consider_shrink; // true if we should try to shrink before next insert
|
||||
|
||||
void reset_thresholds() {
|
||||
enlarge_threshold = static_cast<size_type>(num_buckets
|
||||
* enlarge_resize_percent);
|
||||
shrink_threshold = static_cast<size_type>(num_buckets
|
||||
* shrink_resize_percent);
|
||||
consider_shrink = false; // whatever caused us to reset already considered
|
||||
}
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
inline void swap(dense_hashtable<V,K,HF,ExK,EqK,A> &x,
|
||||
dense_hashtable<V,K,HF,ExK,EqK,A> &y) {
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
#undef JUMP_
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const typename dense_hashtable<V,K,HF,ExK,EqK,A>::size_type
|
||||
dense_hashtable<V,K,HF,ExK,EqK,A>::ILLEGAL_BUCKET;
|
||||
|
||||
// How full we let the table get before we resize. Knuth says .8 is
|
||||
// good -- higher causes us to probe too much, though saves memory
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const float dense_hashtable<V,K,HF,ExK,EqK,A>::HT_OCCUPANCY_FLT = 0.5f;
|
||||
|
||||
// How empty we let the table get before we resize lower.
|
||||
// It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const float dense_hashtable<V,K,HF,ExK,EqK,A>::HT_EMPTY_FLT = 0.4f *
|
||||
dense_hashtable<V,K,HF,ExK,EqK,A>::HT_OCCUPANCY_FLT;
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _DENSEHASHTABLE_H_ */
|
||||
74
3rdparty/google/sparsehash/sparseconfig.h
vendored
Normal file
74
3rdparty/google/sparsehash/sparseconfig.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef SPARSEHASH_SPARSECONFIG_H__
|
||||
#define SPARSEHASH_SPARSECONFIG_H__
|
||||
|
||||
// [AIR] : I couldn't make the google "windows" folder concept work.
|
||||
// This does, and we only care of GCC and MSVC right now anyway.
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
|
||||
#define GOOGLE_NAMESPACE google
|
||||
#define HASH_NAMESPACE stdext
|
||||
#define HASH_FUN_H <hash_map>
|
||||
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
|
||||
#undef HAVE_UINT16_T
|
||||
#undef HAVE_U_INT16_T
|
||||
#define HAVE___UINT16 1
|
||||
#define HAVE_LONG_LONG 1
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#undef HAVE_STDINT_H
|
||||
#undef HAVE_INTTYPES_H
|
||||
#define HAVE_MEMCPY 1
|
||||
#define STL_NAMESPACE std
|
||||
#define _END_GOOGLE_NAMESPACE_ }
|
||||
#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
|
||||
|
||||
#else //if defined( GNUC )
|
||||
|
||||
/* Namespace for Google classes */
|
||||
#define GOOGLE_NAMESPACE google
|
||||
|
||||
/* the location of <hash_fun.h>/<stl_hash_fun.h> */
|
||||
#define HASH_FUN_H <backward/hash_fun.h>
|
||||
|
||||
/* the namespace of hash_map/hash_set */
|
||||
#define HASH_NAMESPACE __gnu_cxx
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#define HAVE_UINT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `u_int16_t'. */
|
||||
#define HAVE_U_INT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `__uint16'. */
|
||||
/* #undef HAVE___UINT16 */
|
||||
|
||||
/* The system-provided hash function including the namespace. */
|
||||
#define SPARSEHASH_HASH HASH_NAMESPACE::hash
|
||||
|
||||
/* the namespace where STL code like vector<> is defined */
|
||||
#define STL_NAMESPACE std
|
||||
|
||||
/* Stops putting the code inside the Google namespace */
|
||||
#define _END_GOOGLE_NAMESPACE_ }
|
||||
|
||||
/* Puts following code inside the Google namespace */
|
||||
#define _START_GOOGLE_NAMESPACE_ namespace google {
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
941
3rdparty/google/sparsehash/sparsehashtable.h
vendored
Normal file
941
3rdparty/google/sparsehash/sparsehashtable.h
vendored
Normal file
@@ -0,0 +1,941 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ---
|
||||
// Author: Craig Silverstein
|
||||
//
|
||||
// A sparse hashtable is a particular implementation of
|
||||
// a hashtable: one that is meant to minimize memory use.
|
||||
// It does this by using a *sparse table* (cf sparsetable.h),
|
||||
// which uses between 1 and 2 bits to store empty buckets
|
||||
// (we may need another bit for hashtables that support deletion).
|
||||
//
|
||||
// When empty buckets are so cheap, an appealing hashtable
|
||||
// implementation is internal probing, in which the hashtable
|
||||
// is a single table, and collisions are resolved by trying
|
||||
// to insert again in another bucket. The most cache-efficient
|
||||
// internal probing schemes are linear probing (which suffers,
|
||||
// alas, from clumping) and quadratic probing, which is what
|
||||
// we implement by default.
|
||||
//
|
||||
// Deleted buckets are a bit of a pain. We have to somehow mark
|
||||
// deleted buckets (the probing must distinguish them from empty
|
||||
// buckets). The most principled way is to have another bitmap,
|
||||
// but that's annoying and takes up space. Instead we let the
|
||||
// user specify an "impossible" key. We set deleted buckets
|
||||
// to have the impossible key.
|
||||
//
|
||||
// Note it is possible to change the value of the delete key
|
||||
// on the fly; you can even remove it, though after that point
|
||||
// the hashtable is insert_only until you set it again.
|
||||
//
|
||||
// You probably shouldn't use this code directly. Use
|
||||
// <google/sparse_hash_table> or <google/sparse_hash_set> instead.
|
||||
//
|
||||
// You can modify the following, below:
|
||||
// HT_OCCUPANCY_FLT -- how full before we double size
|
||||
// HT_EMPTY_FLT -- how empty before we halve size
|
||||
// HT_MIN_BUCKETS -- smallest bucket size
|
||||
// HT_DEFAULT_STARTING_BUCKETS -- default bucket size at construct-time
|
||||
//
|
||||
// You can also change enlarge_resize_percent (which defaults to
|
||||
// HT_OCCUPANCY_FLT), and shrink_resize_percent (which defaults to
|
||||
// HT_EMPTY_FLT) with set_resizing_parameters().
|
||||
//
|
||||
// How to decide what values to use?
|
||||
// shrink_resize_percent's default of .4 * OCCUPANCY_FLT, is probably good.
|
||||
// HT_MIN_BUCKETS is probably unnecessary since you can specify
|
||||
// (indirectly) the starting number of buckets at construct-time.
|
||||
// For enlarge_resize_percent, you can use this chart to try to trade-off
|
||||
// expected lookup time to the space taken up. By default, this
|
||||
// code uses quadratic probing, though you can change it to linear
|
||||
// via _JUMP below if you really want to.
|
||||
//
|
||||
// From http://www.augustana.ca/~mohrj/courses/1999.fall/csc210/lecture_notes/hashing.html
|
||||
// NUMBER OF PROBES / LOOKUP Successful Unsuccessful
|
||||
// Quadratic collision resolution 1 - ln(1-L) - L/2 1/(1-L) - L - ln(1-L)
|
||||
// Linear collision resolution [1+1/(1-L)]/2 [1+1/(1-L)2]/2
|
||||
//
|
||||
// -- enlarge_resize_percent -- 0.10 0.50 0.60 0.75 0.80 0.90 0.99
|
||||
// QUADRATIC COLLISION RES.
|
||||
// probes/successful lookup 1.05 1.44 1.62 2.01 2.21 2.85 5.11
|
||||
// probes/unsuccessful lookup 1.11 2.19 2.82 4.64 5.81 11.4 103.6
|
||||
// LINEAR COLLISION RES.
|
||||
// probes/successful lookup 1.06 1.5 1.75 2.5 3.0 5.5 50.5
|
||||
// probes/unsuccessful lookup 1.12 2.5 3.6 8.5 13.0 50.0 5000.0
|
||||
//
|
||||
// The value type is required to be copy constructible and default
|
||||
// constructible, but it need not be (and commonly isn't) assignable.
|
||||
|
||||
#ifndef _SPARSEHASHTABLE_H_
|
||||
#define _SPARSEHASHTABLE_H_
|
||||
|
||||
#ifndef SPARSEHASH_STAT_UPDATE
|
||||
#define SPARSEHASH_STAT_UPDATE(x) ((void) 0)
|
||||
#endif
|
||||
|
||||
// The probing method
|
||||
// Linear probing
|
||||
// #define JUMP_(key, num_probes) ( 1 )
|
||||
// Quadratic-ish probing
|
||||
#define JUMP_(key, num_probes) ( num_probes )
|
||||
|
||||
|
||||
// Hashtable class, used to implement the hashed associative containers
|
||||
// hash_set and hash_map.
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <assert.h>
|
||||
#include <algorithm> // For swap(), eg
|
||||
#include <iterator> // for facts about iterator tags
|
||||
#include <utility> // for pair<>
|
||||
#include <google/sparsetable> // Since that's basically what we are
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
using STL_NAMESPACE::pair;
|
||||
|
||||
// Alloc is completely ignored. It is present as a template parameter only
|
||||
// for the sake of being compatible with the old SGI hashtable interface.
|
||||
// TODO(csilvers): is that the right thing to do?
|
||||
|
||||
template <class Value, class Key, class HashFcn,
|
||||
class ExtractKey, class EqualKey, class Alloc>
|
||||
class sparse_hashtable;
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct sparse_hashtable_iterator;
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct sparse_hashtable_const_iterator;
|
||||
|
||||
// As far as iterating, we're basically just a sparsetable
|
||||
// that skips over deleted elements.
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct sparse_hashtable_iterator {
|
||||
public:
|
||||
typedef sparse_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator;
|
||||
typedef sparse_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator;
|
||||
typedef typename sparsetable<V>::nonempty_iterator st_iterator;
|
||||
|
||||
typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
|
||||
typedef V value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef V& reference; // Value
|
||||
typedef V* pointer;
|
||||
|
||||
// "Real" constructor and default constructor
|
||||
sparse_hashtable_iterator(const sparse_hashtable<V,K,HF,ExK,EqK,A> *h,
|
||||
st_iterator it, st_iterator it_end)
|
||||
: ht(h), pos(it), end(it_end) { advance_past_deleted(); }
|
||||
sparse_hashtable_iterator() { } // not ever used internally
|
||||
// The default destructor is fine; we don't define one
|
||||
// The default operator= is fine; we don't define one
|
||||
|
||||
// Happy dereferencer
|
||||
reference operator*() const { return *pos; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
|
||||
// Arithmetic. The only hard part is making sure that
|
||||
// we're not on a marked-deleted array element
|
||||
void advance_past_deleted() {
|
||||
while ( pos != end && ht->test_deleted(*this) )
|
||||
++pos;
|
||||
}
|
||||
iterator& operator++() {
|
||||
assert(pos != end); ++pos; advance_past_deleted(); return *this;
|
||||
}
|
||||
iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
|
||||
|
||||
// Comparison.
|
||||
bool operator==(const iterator& it) const { return pos == it.pos; }
|
||||
bool operator!=(const iterator& it) const { return pos != it.pos; }
|
||||
|
||||
|
||||
// The actual data
|
||||
const sparse_hashtable<V,K,HF,ExK,EqK,A> *ht;
|
||||
st_iterator pos, end;
|
||||
};
|
||||
|
||||
// Now do it all again, but with const-ness!
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct sparse_hashtable_const_iterator {
|
||||
public:
|
||||
typedef sparse_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator;
|
||||
typedef sparse_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator;
|
||||
typedef typename sparsetable<V>::const_nonempty_iterator st_iterator;
|
||||
|
||||
typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
|
||||
typedef V value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef const V& reference; // Value
|
||||
typedef const V* pointer;
|
||||
|
||||
// "Real" constructor and default constructor
|
||||
sparse_hashtable_const_iterator(const sparse_hashtable<V,K,HF,ExK,EqK,A> *h,
|
||||
st_iterator it, st_iterator it_end)
|
||||
: ht(h), pos(it), end(it_end) { advance_past_deleted(); }
|
||||
// This lets us convert regular iterators to const iterators
|
||||
sparse_hashtable_const_iterator() { } // never used internally
|
||||
sparse_hashtable_const_iterator(const iterator &it)
|
||||
: ht(it.ht), pos(it.pos), end(it.end) { }
|
||||
// The default destructor is fine; we don't define one
|
||||
// The default operator= is fine; we don't define one
|
||||
|
||||
// Happy dereferencer
|
||||
reference operator*() const { return *pos; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
|
||||
// Arithmetic. The only hard part is making sure that
|
||||
// we're not on a marked-deleted array element
|
||||
void advance_past_deleted() {
|
||||
while ( pos != end && ht->test_deleted(*this) )
|
||||
++pos;
|
||||
}
|
||||
const_iterator& operator++() {
|
||||
assert(pos != end); ++pos; advance_past_deleted(); return *this;
|
||||
}
|
||||
const_iterator operator++(int) { const_iterator tmp(*this); ++*this; return tmp; }
|
||||
|
||||
// Comparison.
|
||||
bool operator==(const const_iterator& it) const { return pos == it.pos; }
|
||||
bool operator!=(const const_iterator& it) const { return pos != it.pos; }
|
||||
|
||||
|
||||
// The actual data
|
||||
const sparse_hashtable<V,K,HF,ExK,EqK,A> *ht;
|
||||
st_iterator pos, end;
|
||||
};
|
||||
|
||||
// And once again, but this time freeing up memory as we iterate
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
struct sparse_hashtable_destructive_iterator {
|
||||
public:
|
||||
typedef sparse_hashtable_destructive_iterator<V,K,HF,ExK,EqK,A> iterator;
|
||||
typedef typename sparsetable<V>::destructive_iterator st_iterator;
|
||||
|
||||
typedef STL_NAMESPACE::forward_iterator_tag iterator_category;
|
||||
typedef V value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef V& reference; // Value
|
||||
typedef V* pointer;
|
||||
|
||||
// "Real" constructor and default constructor
|
||||
sparse_hashtable_destructive_iterator(const
|
||||
sparse_hashtable<V,K,HF,ExK,EqK,A> *h,
|
||||
st_iterator it, st_iterator it_end)
|
||||
: ht(h), pos(it), end(it_end) { advance_past_deleted(); }
|
||||
sparse_hashtable_destructive_iterator() { } // never used internally
|
||||
// The default destructor is fine; we don't define one
|
||||
// The default operator= is fine; we don't define one
|
||||
|
||||
// Happy dereferencer
|
||||
reference operator*() const { return *pos; }
|
||||
pointer operator->() const { return &(operator*()); }
|
||||
|
||||
// Arithmetic. The only hard part is making sure that
|
||||
// we're not on a marked-deleted array element
|
||||
void advance_past_deleted() {
|
||||
while ( pos != end && ht->test_deleted(*this) )
|
||||
++pos;
|
||||
}
|
||||
iterator& operator++() {
|
||||
assert(pos != end); ++pos; advance_past_deleted(); return *this;
|
||||
}
|
||||
iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
|
||||
|
||||
// Comparison.
|
||||
bool operator==(const iterator& it) const { return pos == it.pos; }
|
||||
bool operator!=(const iterator& it) const { return pos != it.pos; }
|
||||
|
||||
|
||||
// The actual data
|
||||
const sparse_hashtable<V,K,HF,ExK,EqK,A> *ht;
|
||||
st_iterator pos, end;
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class Key, class HashFcn,
|
||||
class ExtractKey, class EqualKey, class Alloc>
|
||||
class sparse_hashtable {
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef HashFcn hasher;
|
||||
typedef EqualKey key_equal;
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef sparse_hashtable_iterator<Value, Key, HashFcn,
|
||||
ExtractKey, EqualKey, Alloc>
|
||||
iterator;
|
||||
|
||||
typedef sparse_hashtable_const_iterator<Value, Key, HashFcn,
|
||||
ExtractKey, EqualKey, Alloc>
|
||||
const_iterator;
|
||||
|
||||
typedef sparse_hashtable_destructive_iterator<Value, Key, HashFcn,
|
||||
ExtractKey, EqualKey, Alloc>
|
||||
destructive_iterator;
|
||||
|
||||
|
||||
// How full we let the table get before we resize. Knuth says .8 is
|
||||
// good -- higher causes us to probe too much, though saves memory
|
||||
static const float HT_OCCUPANCY_FLT; // = 0.8f;
|
||||
|
||||
// How empty we let the table get before we resize lower.
|
||||
// It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
|
||||
static const float HT_EMPTY_FLT; // = 0.4 * HT_OCCUPANCY_FLT;
|
||||
|
||||
// Minimum size we're willing to let hashtables be.
|
||||
// Must be a power of two, and at least 4.
|
||||
// Note, however, that for a given hashtable, the minimum size is
|
||||
// determined by the first constructor arg, and may be >HT_MIN_BUCKETS.
|
||||
static const size_t HT_MIN_BUCKETS = 4;
|
||||
|
||||
// By default, if you don't specify a hashtable size at
|
||||
// construction-time, we use this size. Must be a power of two, and
|
||||
// at least HT_MIN_BUCKETS.
|
||||
static const size_t HT_DEFAULT_STARTING_BUCKETS = 32;
|
||||
|
||||
// ITERATOR FUNCTIONS
|
||||
iterator begin() { return iterator(this, table.nonempty_begin(),
|
||||
table.nonempty_end()); }
|
||||
iterator end() { return iterator(this, table.nonempty_end(),
|
||||
table.nonempty_end()); }
|
||||
const_iterator begin() const { return const_iterator(this,
|
||||
table.nonempty_begin(),
|
||||
table.nonempty_end()); }
|
||||
const_iterator end() const { return const_iterator(this,
|
||||
table.nonempty_end(),
|
||||
table.nonempty_end()); }
|
||||
|
||||
// This is used when resizing
|
||||
destructive_iterator destructive_begin() {
|
||||
return destructive_iterator(this, table.destructive_begin(),
|
||||
table.destructive_end());
|
||||
}
|
||||
destructive_iterator destructive_end() {
|
||||
return destructive_iterator(this, table.destructive_end(),
|
||||
table.destructive_end());
|
||||
}
|
||||
|
||||
|
||||
// ACCESSOR FUNCTIONS for the things we templatize on, basically
|
||||
hasher hash_funct() const { return hash; }
|
||||
key_equal key_eq() const { return equals; }
|
||||
|
||||
// We need to copy values when we set the special marker for deleted
|
||||
// elements, but, annoyingly, we can't just use the copy assignment
|
||||
// operator because value_type might not be assignable (it's often
|
||||
// pair<const X, Y>). We use explicit destructor invocation and
|
||||
// placement new to get around this. Arg.
|
||||
private:
|
||||
void set_value(value_type* dst, const value_type src) {
|
||||
dst->~value_type(); // delete the old value, if any
|
||||
new(dst) value_type(src);
|
||||
}
|
||||
|
||||
// This is used as a tag for the copy constructor, saying to destroy its
|
||||
// arg We have two ways of destructively copying: with potentially growing
|
||||
// the hashtable as we copy, and without. To make sure the outside world
|
||||
// can't do a destructive copy, we make the typename private.
|
||||
enum MoveDontCopyT {MoveDontCopy, MoveDontGrow};
|
||||
|
||||
|
||||
// DELETE HELPER FUNCTIONS
|
||||
// This lets the user describe a key that will indicate deleted
|
||||
// table entries. This key should be an "impossible" entry --
|
||||
// if you try to insert it for real, you won't be able to retrieve it!
|
||||
// (NB: while you pass in an entire value, only the key part is looked
|
||||
// at. This is just because I don't know how to assign just a key.)
|
||||
private:
|
||||
void squash_deleted() { // gets rid of any deleted entries we have
|
||||
if ( num_deleted ) { // get rid of deleted before writing
|
||||
sparse_hashtable tmp(MoveDontGrow, *this);
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
assert(num_deleted == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
void set_deleted_key(const value_type &val) {
|
||||
// It's only safe to change what "deleted" means if we purge deleted guys
|
||||
squash_deleted();
|
||||
use_deleted = true;
|
||||
set_value(&delval, val); // save the key (and rest of val too)
|
||||
}
|
||||
void clear_deleted_key() {
|
||||
squash_deleted();
|
||||
use_deleted = false;
|
||||
}
|
||||
|
||||
// These are public so the iterators can use them
|
||||
// True if the item at position bucknum is "deleted" marker
|
||||
bool test_deleted(size_type bucknum) const {
|
||||
// The num_deleted test is crucial for read(): after read(), the ht values
|
||||
// are garbage, and we don't want to think some of them are deleted.
|
||||
return (use_deleted && num_deleted > 0 && table.test(bucknum) &&
|
||||
equals(get_key(delval), get_key(table.get(bucknum))));
|
||||
}
|
||||
bool test_deleted(const iterator &it) const {
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(*it)));
|
||||
}
|
||||
bool test_deleted(const const_iterator &it) const {
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(*it)));
|
||||
}
|
||||
bool test_deleted(const destructive_iterator &it) const {
|
||||
return (use_deleted && num_deleted > 0 &&
|
||||
equals(get_key(delval), get_key(*it)));
|
||||
}
|
||||
// Set it so test_deleted is true. true if object didn't used to be deleted
|
||||
// See below (at erase()) to explain why we allow const_iterators
|
||||
bool set_deleted(const_iterator &it) {
|
||||
assert(use_deleted); // bad if set_deleted_key() wasn't called
|
||||
bool retval = !test_deleted(it);
|
||||
// &* converts from iterator to value-type
|
||||
set_value(const_cast<value_type*>(&(*it)), delval);
|
||||
return retval;
|
||||
}
|
||||
// Set it so test_deleted is false. true if object used to be deleted
|
||||
bool clear_deleted(const_iterator &it) {
|
||||
assert(use_deleted); // bad if set_deleted_key() wasn't called
|
||||
// happens automatically when we assign something else in its place
|
||||
return test_deleted(it);
|
||||
}
|
||||
|
||||
|
||||
// FUNCTIONS CONCERNING SIZE
|
||||
size_type size() const { return table.num_nonempty() - num_deleted; }
|
||||
// Buckets are always a power of 2
|
||||
size_type max_size() const { return (size_type(-1) >> 1U) + 1; }
|
||||
bool empty() const { return size() == 0; }
|
||||
size_type bucket_count() const { return table.size(); }
|
||||
size_type max_bucket_count() const { return max_size(); }
|
||||
|
||||
private:
|
||||
// Because of the above, size_type(-1) is never legal; use it for errors
|
||||
static const size_type ILLEGAL_BUCKET = size_type(-1);
|
||||
|
||||
private:
|
||||
// This is the smallest size a hashtable can be without being too crowded
|
||||
// If you like, you can give a min #buckets as well as a min #elts
|
||||
size_type min_size(size_type num_elts, size_type min_buckets_wanted) {
|
||||
size_type sz = HT_MIN_BUCKETS;
|
||||
while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent )
|
||||
sz *= 2;
|
||||
return sz;
|
||||
}
|
||||
|
||||
// Used after a string of deletes
|
||||
void maybe_shrink() {
|
||||
assert(table.num_nonempty() >= num_deleted);
|
||||
assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two
|
||||
assert(bucket_count() >= HT_MIN_BUCKETS);
|
||||
|
||||
// If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS,
|
||||
// we'll never shrink until you get relatively big, and we'll never
|
||||
// shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something
|
||||
// like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will
|
||||
// shrink us down to HT_MIN_BUCKETS buckets, which is too small.
|
||||
if (shrink_threshold > 0
|
||||
&& (table.num_nonempty()-num_deleted) < shrink_threshold &&
|
||||
bucket_count() > HT_DEFAULT_STARTING_BUCKETS ) {
|
||||
size_type sz = bucket_count() / 2; // find how much we should shrink
|
||||
while ( sz > HT_DEFAULT_STARTING_BUCKETS &&
|
||||
(table.num_nonempty() - num_deleted) <= sz *
|
||||
shrink_resize_percent )
|
||||
sz /= 2; // stay a power of 2
|
||||
sparse_hashtable tmp(MoveDontCopy, *this, sz);
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
consider_shrink = false; // because we just considered it
|
||||
}
|
||||
|
||||
// We'll let you resize a hashtable -- though this makes us copy all!
|
||||
// When you resize, you say, "make it big enough for this many more elements"
|
||||
void resize_delta(size_type delta) {
|
||||
if ( consider_shrink ) // see if lots of deletes happened
|
||||
maybe_shrink();
|
||||
if ( bucket_count() >= HT_MIN_BUCKETS &&
|
||||
(table.num_nonempty() + delta) <= enlarge_threshold )
|
||||
return; // we're ok as we are
|
||||
|
||||
// Sometimes, we need to resize just to get rid of all the
|
||||
// "deleted" buckets that are clogging up the hashtable. So when
|
||||
// deciding whether to resize, count the deleted buckets (which
|
||||
// are currently taking up room). But later, when we decide what
|
||||
// size to resize to, *don't* count deleted buckets, since they
|
||||
// get discarded during the resize.
|
||||
const size_type needed_size = min_size(table.num_nonempty() + delta, 0);
|
||||
if ( needed_size > bucket_count() ) { // we don't have enough buckets
|
||||
const size_type resize_to = min_size(table.num_nonempty() - num_deleted
|
||||
+ delta, 0);
|
||||
sparse_hashtable tmp(MoveDontCopy, *this, resize_to);
|
||||
swap(tmp); // now we are tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Used to actually do the rehashing when we grow/shrink a hashtable
|
||||
void copy_from(const sparse_hashtable &ht, size_type min_buckets_wanted) {
|
||||
clear(); // clear table, set num_deleted to 0
|
||||
|
||||
// If we need to change the size of our table, do it now
|
||||
const size_type resize_to = min_size(ht.size(), min_buckets_wanted);
|
||||
if ( resize_to > bucket_count() ) { // we don't have enough buckets
|
||||
table.resize(resize_to); // sets the number of buckets
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// We use a normal iterator to get non-deleted bcks from ht
|
||||
// We could use insert() here, but since we know there are
|
||||
// no duplicates and no deleted items, we can be more efficient
|
||||
assert( (bucket_count() & (bucket_count()-1)) == 0); // a power of two
|
||||
for ( const_iterator it = ht.begin(); it != ht.end(); ++it ) {
|
||||
size_type num_probes = 0; // how many times we've probed
|
||||
size_type bucknum;
|
||||
const size_type bucket_count_minus_one = bucket_count() - 1;
|
||||
for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
|
||||
table.test(bucknum); // not empty
|
||||
bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) {
|
||||
++num_probes;
|
||||
assert(num_probes < bucket_count()); // or else the hashtable is full
|
||||
}
|
||||
table.set(bucknum, *it); // copies the value to here
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation is like copy_from, but it destroys the table of the
|
||||
// "from" guy by freeing sparsetable memory as we iterate. This is
|
||||
// useful in resizing, since we're throwing away the "from" guy anyway.
|
||||
void move_from(MoveDontCopyT mover, sparse_hashtable &ht,
|
||||
size_type min_buckets_wanted) {
|
||||
clear(); // clear table, set num_deleted to 0
|
||||
|
||||
// If we need to change the size of our table, do it now
|
||||
size_t resize_to;
|
||||
if ( mover == MoveDontGrow )
|
||||
resize_to = ht.bucket_count(); // keep same size as old ht
|
||||
else // MoveDontCopy
|
||||
resize_to = min_size(ht.size(), min_buckets_wanted);
|
||||
if ( resize_to > bucket_count() ) { // we don't have enough buckets
|
||||
table.resize(resize_to); // sets the number of buckets
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// We use a normal iterator to get non-deleted bcks from ht
|
||||
// We could use insert() here, but since we know there are
|
||||
// no duplicates and no deleted items, we can be more efficient
|
||||
assert( (bucket_count() & (bucket_count()-1)) == 0); // a power of two
|
||||
// THIS IS THE MAJOR LINE THAT DIFFERS FROM COPY_FROM():
|
||||
for ( destructive_iterator it = ht.destructive_begin();
|
||||
it != ht.destructive_end(); ++it ) {
|
||||
size_type num_probes = 0; // how many times we've probed
|
||||
size_type bucknum;
|
||||
for ( bucknum = hash(get_key(*it)) & (bucket_count()-1); // h % buck_cnt
|
||||
table.test(bucknum); // not empty
|
||||
bucknum = (bucknum + JUMP_(key, num_probes)) & (bucket_count()-1) ) {
|
||||
++num_probes;
|
||||
assert(num_probes < bucket_count()); // or else the hashtable is full
|
||||
}
|
||||
table.set(bucknum, *it); // copies the value to here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Required by the spec for hashed associative container
|
||||
public:
|
||||
// Though the docs say this should be num_buckets, I think it's much
|
||||
// more useful as num_elements. As a special feature, calling with
|
||||
// req_elements==0 will cause us to shrink if we can, saving space.
|
||||
void resize(size_type req_elements) { // resize to this or larger
|
||||
if ( consider_shrink || req_elements == 0 )
|
||||
maybe_shrink();
|
||||
if ( req_elements > table.num_nonempty() ) // we only grow
|
||||
resize_delta(req_elements - table.num_nonempty());
|
||||
}
|
||||
|
||||
// Change the value of shrink_resize_percent and
|
||||
// enlarge_resize_percent. The description at the beginning of this
|
||||
// file explains how to choose the values. Setting the shrink
|
||||
// parameter to 0.0 ensures that the table never shrinks.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
assert(shrink >= 0.0);
|
||||
assert(grow <= 1.0);
|
||||
assert(shrink <= grow/2.0);
|
||||
shrink_resize_percent = shrink;
|
||||
enlarge_resize_percent = grow;
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// CONSTRUCTORS -- as required by the specs, we take a size,
|
||||
// but also let you specify a hashfunction, key comparator,
|
||||
// and key extractor. We also define a copy constructor and =.
|
||||
// DESTRUCTOR -- the default is fine, surprisingly.
|
||||
explicit sparse_hashtable(size_type expected_max_items_in_table = 0,
|
||||
const HashFcn& hf = HashFcn(),
|
||||
const EqualKey& eql = EqualKey(),
|
||||
const ExtractKey& ext = ExtractKey())
|
||||
: hash(hf), equals(eql), get_key(ext), num_deleted(0), use_deleted(false),
|
||||
delval(), enlarge_resize_percent(HT_OCCUPANCY_FLT),
|
||||
shrink_resize_percent(HT_EMPTY_FLT),
|
||||
table(expected_max_items_in_table == 0
|
||||
? HT_DEFAULT_STARTING_BUCKETS
|
||||
: min_size(expected_max_items_in_table, 0)) {
|
||||
reset_thresholds();
|
||||
}
|
||||
|
||||
// As a convenience for resize(), we allow an optional second argument
|
||||
// which lets you make this new hashtable a different size than ht.
|
||||
// We also provide a mechanism of saying you want to "move" the ht argument
|
||||
// into us instead of copying.
|
||||
sparse_hashtable(const sparse_hashtable& ht,
|
||||
size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
|
||||
: hash(ht.hash), equals(ht.equals), get_key(ht.get_key),
|
||||
num_deleted(0), use_deleted(ht.use_deleted), delval(ht.delval),
|
||||
enlarge_resize_percent(ht.enlarge_resize_percent),
|
||||
shrink_resize_percent(ht.shrink_resize_percent),
|
||||
table() {
|
||||
reset_thresholds();
|
||||
copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries
|
||||
}
|
||||
sparse_hashtable(MoveDontCopyT mover, sparse_hashtable& ht,
|
||||
size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
|
||||
: hash(ht.hash), equals(ht.equals), get_key(ht.get_key),
|
||||
num_deleted(0), use_deleted(ht.use_deleted), delval(ht.delval),
|
||||
enlarge_resize_percent(ht.enlarge_resize_percent),
|
||||
shrink_resize_percent(ht.shrink_resize_percent),
|
||||
table() {
|
||||
reset_thresholds();
|
||||
move_from(mover, ht, min_buckets_wanted); // ignores deleted entries
|
||||
}
|
||||
|
||||
sparse_hashtable& operator= (const sparse_hashtable& ht) {
|
||||
if (&ht == this) return *this; // don't copy onto ourselves
|
||||
clear();
|
||||
hash = ht.hash;
|
||||
equals = ht.equals;
|
||||
get_key = ht.get_key;
|
||||
use_deleted = ht.use_deleted;
|
||||
set_value(&delval, ht.delval);
|
||||
copy_from(ht, HT_MIN_BUCKETS); // sets num_deleted to 0 too
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Many STL algorithms use swap instead of copy constructors
|
||||
void swap(sparse_hashtable& ht) {
|
||||
STL_NAMESPACE::swap(hash, ht.hash);
|
||||
STL_NAMESPACE::swap(equals, ht.equals);
|
||||
STL_NAMESPACE::swap(get_key, ht.get_key);
|
||||
STL_NAMESPACE::swap(num_deleted, ht.num_deleted);
|
||||
STL_NAMESPACE::swap(use_deleted, ht.use_deleted);
|
||||
STL_NAMESPACE::swap(enlarge_resize_percent, ht.enlarge_resize_percent);
|
||||
STL_NAMESPACE::swap(shrink_resize_percent, ht.shrink_resize_percent);
|
||||
{ value_type tmp; // for annoying reasons, swap() doesn't work
|
||||
set_value(&tmp, delval);
|
||||
set_value(&delval, ht.delval);
|
||||
set_value(&ht.delval, tmp);
|
||||
}
|
||||
table.swap(ht.table);
|
||||
reset_thresholds();
|
||||
ht.reset_thresholds();
|
||||
}
|
||||
|
||||
// It's always nice to be able to clear a table without deallocating it
|
||||
void clear() {
|
||||
table.clear();
|
||||
reset_thresholds();
|
||||
num_deleted = 0;
|
||||
}
|
||||
|
||||
|
||||
// LOOKUP ROUTINES
|
||||
private:
|
||||
// Returns a pair of positions: 1st where the object is, 2nd where
|
||||
// it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET
|
||||
// if object is not found; 2nd is ILLEGAL_BUCKET if it is.
|
||||
// Note: because of deletions where-to-insert is not trivial: it's the
|
||||
// first deleted bucket we see, as long as we don't find the key later
|
||||
pair<size_type, size_type> find_position(const key_type &key) const {
|
||||
size_type num_probes = 0; // how many times we've probed
|
||||
const size_type bucket_count_minus_one = bucket_count() - 1;
|
||||
size_type bucknum = hash(key) & bucket_count_minus_one;
|
||||
size_type insert_pos = ILLEGAL_BUCKET; // where we would insert
|
||||
SPARSEHASH_STAT_UPDATE(total_lookups += 1);
|
||||
while ( 1 ) { // probe until something happens
|
||||
if ( !table.test(bucknum) ) { // bucket is empty
|
||||
SPARSEHASH_STAT_UPDATE(total_probes += num_probes);
|
||||
if ( insert_pos == ILLEGAL_BUCKET ) // found no prior place to insert
|
||||
return pair<size_type,size_type>(ILLEGAL_BUCKET, bucknum);
|
||||
else
|
||||
return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos);
|
||||
|
||||
} else if ( test_deleted(bucknum) ) {// keep searching, but mark to insert
|
||||
if ( insert_pos == ILLEGAL_BUCKET )
|
||||
insert_pos = bucknum;
|
||||
|
||||
} else if ( equals(key, get_key(table.get(bucknum))) ) {
|
||||
SPARSEHASH_STAT_UPDATE(total_probes += num_probes);
|
||||
return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET);
|
||||
}
|
||||
++num_probes; // we're doing another probe
|
||||
bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
|
||||
assert(num_probes < bucket_count()); // don't probe too many times!
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
iterator find(const key_type& key) {
|
||||
if ( size() == 0 ) return end();
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
|
||||
return end();
|
||||
else
|
||||
return iterator(this, table.get_iter(pos.first), table.nonempty_end());
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& key) const {
|
||||
if ( size() == 0 ) return end();
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
if ( pos.first == ILLEGAL_BUCKET ) // alas, not there
|
||||
return end();
|
||||
else
|
||||
return const_iterator(this,
|
||||
table.get_iter(pos.first), table.nonempty_end());
|
||||
}
|
||||
|
||||
// Counts how many elements have key key. For maps, it's either 0 or 1.
|
||||
size_type count(const key_type &key) const {
|
||||
pair<size_type, size_type> pos = find_position(key);
|
||||
return pos.first == ILLEGAL_BUCKET ? 0 : 1;
|
||||
}
|
||||
|
||||
// Likewise, equal_range doesn't really make sense for us. Oh well.
|
||||
pair<iterator,iterator> equal_range(const key_type& key) {
|
||||
const iterator pos = find(key); // either an iterator or end
|
||||
return pair<iterator,iterator>(pos, pos);
|
||||
}
|
||||
pair<const_iterator,const_iterator> equal_range(const key_type& key) const {
|
||||
const const_iterator pos = find(key); // either an iterator or end
|
||||
return pair<iterator,iterator>(pos, pos);
|
||||
}
|
||||
|
||||
|
||||
// INSERTION ROUTINES
|
||||
private:
|
||||
// If you know *this is big enough to hold obj, use this routine
|
||||
pair<iterator, bool> insert_noresize(const value_type& obj) {
|
||||
// First, double-check we're not inserting delval
|
||||
assert(!use_deleted || !equals(get_key(obj), get_key(delval)));
|
||||
const pair<size_type,size_type> pos = find_position(get_key(obj));
|
||||
if ( pos.first != ILLEGAL_BUCKET) { // object was already there
|
||||
return pair<iterator,bool>(iterator(this, table.get_iter(pos.first),
|
||||
table.nonempty_end()),
|
||||
false); // false: we didn't insert
|
||||
} else { // pos.second says where to put it
|
||||
if ( test_deleted(pos.second) ) { // just replace if it's been del.
|
||||
// The set() below will undelete this object. We just worry about stats
|
||||
assert(num_deleted > 0);
|
||||
--num_deleted; // used to be, now it isn't
|
||||
}
|
||||
table.set(pos.second, obj);
|
||||
return pair<iterator,bool>(iterator(this, table.get_iter(pos.second),
|
||||
table.nonempty_end()),
|
||||
true); // true: we did insert
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// This is the normal insert routine, used by the outside world
|
||||
pair<iterator, bool> insert(const value_type& obj) {
|
||||
resize_delta(1); // adding an object, grow if need be
|
||||
return insert_noresize(obj);
|
||||
}
|
||||
|
||||
// When inserting a lot at a time, we specialize on the type of iterator
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l) {
|
||||
// specializes on iterator type
|
||||
insert(f, l, typename STL_NAMESPACE::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
|
||||
// Iterator supports operator-, resize before inserting
|
||||
template <class ForwardIterator>
|
||||
void insert(ForwardIterator f, ForwardIterator l,
|
||||
STL_NAMESPACE::forward_iterator_tag) {
|
||||
size_type n = STL_NAMESPACE::distance(f, l); // TODO(csilvers): standard?
|
||||
resize_delta(n);
|
||||
for ( ; n > 0; --n, ++f)
|
||||
insert_noresize(*f);
|
||||
}
|
||||
|
||||
// Arbitrary iterator, can't tell how much to resize
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator f, InputIterator l,
|
||||
STL_NAMESPACE::input_iterator_tag) {
|
||||
for ( ; f != l; ++f)
|
||||
insert(*f);
|
||||
}
|
||||
|
||||
|
||||
// DELETION ROUTINES
|
||||
size_type erase(const key_type& key) {
|
||||
// First, double-check we're not erasing delval
|
||||
assert(!use_deleted || !equals(key, get_key(delval)));
|
||||
const_iterator pos = find(key); // shrug: shouldn't need to be const
|
||||
if ( pos != end() ) {
|
||||
assert(!test_deleted(pos)); // or find() shouldn't have returned it
|
||||
set_deleted(pos);
|
||||
++num_deleted;
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
return 1; // because we deleted one thing
|
||||
} else {
|
||||
return 0; // because we deleted nothing
|
||||
}
|
||||
}
|
||||
|
||||
// This is really evil: really it should be iterator, not const_iterator.
|
||||
// But...the only reason keys are const is to allow lookup.
|
||||
// Since that's a moot issue for deleted keys, we allow const_iterators
|
||||
void erase(const_iterator pos) {
|
||||
if ( pos == end() ) return; // sanity check
|
||||
if ( set_deleted(pos) ) { // true if object has been newly deleted
|
||||
++num_deleted;
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
}
|
||||
}
|
||||
|
||||
void erase(const_iterator f, const_iterator l) {
|
||||
for ( ; f != l; ++f) {
|
||||
if ( set_deleted(f) ) // should always be true
|
||||
++num_deleted;
|
||||
}
|
||||
consider_shrink = true; // will think about shrink after next insert
|
||||
}
|
||||
|
||||
|
||||
// COMPARISON
|
||||
bool operator==(const sparse_hashtable& ht) const {
|
||||
// We really want to check that the hash functions are the same
|
||||
// but alas there's no way to do this. We just hope.
|
||||
return ( num_deleted == ht.num_deleted && table == ht.table );
|
||||
}
|
||||
bool operator!=(const sparse_hashtable& ht) const {
|
||||
return !(*this == ht);
|
||||
}
|
||||
|
||||
|
||||
// I/O
|
||||
// We support reading and writing hashtables to disk. NOTE that
|
||||
// this only stores the hashtable metadata, not the stuff you've
|
||||
// actually put in the hashtable! Alas, since I don't know how to
|
||||
// write a hasher or key_equal, you have to make sure everything
|
||||
// but the table is the same. We compact before writing.
|
||||
bool write_metadata(FILE *fp) {
|
||||
squash_deleted(); // so we don't have to worry about delkey
|
||||
return table.write_metadata(fp);
|
||||
}
|
||||
|
||||
bool read_metadata(FILE *fp) {
|
||||
num_deleted = 0; // since we got rid before writing
|
||||
bool result = table.read_metadata(fp);
|
||||
reset_thresholds();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Only meaningful if value_type is a POD.
|
||||
bool write_nopointer_data(FILE *fp) {
|
||||
return table.write_nopointer_data(fp);
|
||||
}
|
||||
|
||||
// Only meaningful if value_type is a POD.
|
||||
bool read_nopointer_data(FILE *fp) {
|
||||
return table.read_nopointer_data(fp);
|
||||
}
|
||||
|
||||
private:
|
||||
// The actual data
|
||||
hasher hash; // required by hashed_associative_container
|
||||
key_equal equals;
|
||||
ExtractKey get_key;
|
||||
size_type num_deleted; // how many occupied buckets are marked deleted
|
||||
bool use_deleted; // false until delval has been set
|
||||
value_type delval; // which key marks deleted entries
|
||||
float enlarge_resize_percent; // how full before resize
|
||||
float shrink_resize_percent; // how empty before resize
|
||||
size_type shrink_threshold; // table.size() * shrink_resize_percent
|
||||
size_type enlarge_threshold; // table.size() * enlarge_resize_percent
|
||||
sparsetable<value_type> table; // holds num_buckets and num_elements too
|
||||
bool consider_shrink; // true if we should try to shrink before next insert
|
||||
|
||||
void reset_thresholds() {
|
||||
enlarge_threshold = static_cast<size_type>(table.size()
|
||||
* enlarge_resize_percent);
|
||||
shrink_threshold = static_cast<size_type>(table.size()
|
||||
* shrink_resize_percent);
|
||||
consider_shrink = false; // whatever caused us to reset already considered
|
||||
}
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
inline void swap(sparse_hashtable<V,K,HF,ExK,EqK,A> &x,
|
||||
sparse_hashtable<V,K,HF,ExK,EqK,A> &y) {
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
#undef JUMP_
|
||||
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const typename sparse_hashtable<V,K,HF,ExK,EqK,A>::size_type
|
||||
sparse_hashtable<V,K,HF,ExK,EqK,A>::ILLEGAL_BUCKET;
|
||||
|
||||
// How full we let the table get before we resize. Knuth says .8 is
|
||||
// good -- higher causes us to probe too much, though saves memory
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const float sparse_hashtable<V,K,HF,ExK,EqK,A>::HT_OCCUPANCY_FLT = 0.8f;
|
||||
|
||||
// How empty we let the table get before we resize lower.
|
||||
// It should be less than OCCUPANCY_FLT / 2 or we thrash resizing
|
||||
template <class V, class K, class HF, class ExK, class EqK, class A>
|
||||
const float sparse_hashtable<V,K,HF,ExK,EqK,A>::HT_EMPTY_FLT = 0.4f *
|
||||
sparse_hashtable<V,K,HF,ExK,EqK,A>::HT_OCCUPANCY_FLT;
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _SPARSEHASHTABLE_H_ */
|
||||
1451
3rdparty/google/sparsetable
vendored
Normal file
1451
3rdparty/google/sparsetable
vendored
Normal file
File diff suppressed because it is too large
Load Diff
250
3rdparty/google/type_traits.h
vendored
Normal file
250
3rdparty/google/type_traits.h
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "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 COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS 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.
|
||||
|
||||
// ----
|
||||
// Author: Matt Austern
|
||||
//
|
||||
// Define a small subset of tr1 type traits. The traits we define are:
|
||||
// is_integral
|
||||
// is_floating_point
|
||||
// is_pointer
|
||||
// is_reference
|
||||
// is_pod
|
||||
// has_trivial_constructor
|
||||
// has_trivial_copy
|
||||
// has_trivial_assign
|
||||
// has_trivial_destructor
|
||||
// remove_const
|
||||
// remove_volatile
|
||||
// remove_cv
|
||||
// remove_reference
|
||||
// remove_pointer
|
||||
// is_convertible
|
||||
// We can add more type traits as required.
|
||||
|
||||
#ifndef BASE_TYPE_TRAITS_H_
|
||||
#define BASE_TYPE_TRAITS_H_
|
||||
|
||||
#include <google/sparsehash/sparseconfig.h>
|
||||
#include <utility> // For pair
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// integral_constant, defined in tr1, is a wrapper for an integer
|
||||
// value. We don't really need this generality; we could get away
|
||||
// with hardcoding the integer type to bool. We use the fully
|
||||
// general integer_constant for compatibility with tr1.
|
||||
|
||||
template<class T, T v>
|
||||
struct integral_constant {
|
||||
static const T value = v;
|
||||
typedef T value_type;
|
||||
typedef integral_constant<T, v> type;
|
||||
};
|
||||
|
||||
template <class T, T v> const T integral_constant<T, v>::value;
|
||||
|
||||
// Abbreviations: true_type and false_type are structs that represent
|
||||
// boolean true and false values.
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
// Types small_ and big_ are guaranteed such that sizeof(small_) <
|
||||
// sizeof(big_)
|
||||
typedef char small_;
|
||||
|
||||
struct big_ {
|
||||
char dummy[2];
|
||||
};
|
||||
|
||||
// is_integral is false except for the built-in integer types.
|
||||
template <class T> struct is_integral : false_type { };
|
||||
template<> struct is_integral<bool> : true_type { };
|
||||
template<> struct is_integral<char> : true_type { };
|
||||
template<> struct is_integral<unsigned char> : true_type { };
|
||||
template<> struct is_integral<signed char> : true_type { };
|
||||
#if defined(_MSC_VER)
|
||||
// wchar_t is not by default a distinct type from unsigned short in
|
||||
// Microsoft C.
|
||||
// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
|
||||
template<> struct is_integral<__wchar_t> : true_type { };
|
||||
#else
|
||||
template<> struct is_integral<wchar_t> : true_type { };
|
||||
#endif
|
||||
template<> struct is_integral<short> : true_type { };
|
||||
template<> struct is_integral<unsigned short> : true_type { };
|
||||
template<> struct is_integral<int> : true_type { };
|
||||
template<> struct is_integral<unsigned int> : true_type { };
|
||||
template<> struct is_integral<long> : true_type { };
|
||||
template<> struct is_integral<unsigned long> : true_type { };
|
||||
#ifdef HAVE_LONG_LONG
|
||||
template<> struct is_integral<long long> : true_type { };
|
||||
template<> struct is_integral<unsigned long long> : true_type { };
|
||||
#endif
|
||||
|
||||
|
||||
// is_floating_point is false except for the built-in floating-point types.
|
||||
template <class T> struct is_floating_point : false_type { };
|
||||
template<> struct is_floating_point<float> : true_type { };
|
||||
template<> struct is_floating_point<double> : true_type { };
|
||||
template<> struct is_floating_point<long double> : true_type { };
|
||||
|
||||
|
||||
// is_pointer is false except for pointer types.
|
||||
template <class T> struct is_pointer : false_type { };
|
||||
template <class T> struct is_pointer<T*> : true_type { };
|
||||
|
||||
|
||||
// is_reference is false except for reference types.
|
||||
template<typename T> struct is_reference : false_type {};
|
||||
template<typename T> struct is_reference<T&> : true_type {};
|
||||
|
||||
|
||||
// We can't get is_pod right without compiler help, so fail conservatively.
|
||||
// We will assume it's false except for arithmetic types and pointers,
|
||||
// and const versions thereof. Note that std::pair is not a POD.
|
||||
template <class T> struct is_pod
|
||||
: integral_constant<bool, (is_integral<T>::value ||
|
||||
is_floating_point<T>::value ||
|
||||
is_pointer<T>::value)> { };
|
||||
template <class T> struct is_pod<const T> : is_pod<T> { };
|
||||
|
||||
|
||||
// We can't get has_trivial_constructor right without compiler help, so
|
||||
// fail conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial
|
||||
// constructors. (3) array of a type with a trivial constructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_constructor : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_constructor<T>::value &&
|
||||
has_trivial_constructor<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_constructor<A[N]>
|
||||
: has_trivial_constructor<A> { };
|
||||
template <class T> struct has_trivial_constructor<const T>
|
||||
: has_trivial_constructor<T> { };
|
||||
|
||||
// We can't get has_trivial_copy right without compiler help, so fail
|
||||
// conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial copy
|
||||
// constructors. (3) array of a type with a trivial copy constructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_copy : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_copy<T>::value &&
|
||||
has_trivial_copy<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_copy<A[N]>
|
||||
: has_trivial_copy<A> { };
|
||||
template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
|
||||
|
||||
// We can't get has_trivial_assign right without compiler help, so fail
|
||||
// conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial copy
|
||||
// constructors. (3) array of a type with a trivial assign constructor.
|
||||
template <class T> struct has_trivial_assign : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_assign<T>::value &&
|
||||
has_trivial_assign<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_assign<A[N]>
|
||||
: has_trivial_assign<A> { };
|
||||
|
||||
// We can't get has_trivial_destructor right without compiler help, so
|
||||
// fail conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial
|
||||
// destructors. (3) array of a type with a trivial destructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_destructor : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_destructor<T>::value &&
|
||||
has_trivial_destructor<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_destructor<A[N]>
|
||||
: has_trivial_destructor<A> { };
|
||||
template <class T> struct has_trivial_destructor<const T>
|
||||
: has_trivial_destructor<T> { };
|
||||
|
||||
// Specified by TR1 [4.7.1]
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<T const> { typedef T type; };
|
||||
template<typename T> struct remove_volatile { typedef T type; };
|
||||
template<typename T> struct remove_volatile<T volatile> { typedef T type; };
|
||||
template<typename T> struct remove_cv {
|
||||
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
|
||||
};
|
||||
|
||||
|
||||
// Specified by TR1 [4.7.2]
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
// Specified by TR1 [4.7.4] Pointer modifications.
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* const> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* const volatile> {
|
||||
typedef T type; };
|
||||
|
||||
// Specified by TR1 [4.6] Relationships between types
|
||||
#ifndef _MSC_VER
|
||||
namespace internal {
|
||||
|
||||
// This class is an implementation detail for is_convertible, and you
|
||||
// don't need to know how it works to use is_convertible. For those
|
||||
// who care: we declare two different functions, one whose argument is
|
||||
// of type To and one with a variadic argument list. We give them
|
||||
// return types of different size, so we can use sizeof to trick the
|
||||
// compiler into telling us which function it would have chosen if we
|
||||
// had called it with an argument of type From. See Alexandrescu's
|
||||
// _Modern C++ Design_ for more details on this sort of trick.
|
||||
|
||||
template <typename From, typename To>
|
||||
struct ConvertHelper {
|
||||
static small_ Test(To);
|
||||
static big_ Test(...);
|
||||
static From Create();
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
// Inherits from true_type if From is convertible to To, false_type otherwise.
|
||||
template <typename From, typename To>
|
||||
struct is_convertible
|
||||
: integral_constant<bool,
|
||||
sizeof(internal::ConvertHelper<From, To>::Test(
|
||||
internal::ConvertHelper<From, To>::Create()))
|
||||
== sizeof(small_)> {
|
||||
};
|
||||
#endif
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // BASE_TYPE_TRAITS_H_
|
||||
442
3rdparty/libjpeg/libjpeg.vcproj
vendored
Normal file
442
3rdparty/libjpeg/libjpeg.vcproj
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="libjpeg7"
|
||||
ProjectGUID="{BC236261-77E8-4567-8D09-45CD02965EB6}"
|
||||
RootNamespace="libjpeg"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
<DefaultToolFile
|
||||
FileName="masm.rules"
|
||||
/>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<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="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
WholeProgramOptimization="false"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<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="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
<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=".\jaricom.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcapimin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcapistd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcarith.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jccoefct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jccolor.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcdctmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jchuff.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcinit.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcmainct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcmarker.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcmaster.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcomapi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jconfig.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcparam.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcprepct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jcsample.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jctrans.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdapimin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdapistd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdarith.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdatadst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdatasrc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdcoefct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdcolor.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdct.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jddctmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdhuff.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdinput.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdmainct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdmarker.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdmaster.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdmerge.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdpostct.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdsample.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jdtrans.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jerror.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jerror.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jfdctflt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jfdctfst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jfdctint.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jidctflt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jidctfst.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jidctint.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jinclude.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jmemansi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jmemmgr.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jmemsys.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jmorecfg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jpegint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jpeglib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jquant1.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jquant2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jutils.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jversion.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\change.log"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filelist.txt"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\README"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\readme.pcsx2.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
327
3rdparty/libjpeg/libjpeg.vcxproj
vendored
327
3rdparty/libjpeg/libjpeg.vcxproj
vendored
@@ -1,166 +1,163 @@
|
||||
<?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="Devel|Win32">
|
||||
<Configuration>Devel</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>libjpeg7</ProjectName>
|
||||
<ProjectGuid>{BC236261-77E8-4567-8D09-45CD02965EB6}</ProjectGuid>
|
||||
<RootNamespace>libjpeg</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</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>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c" />
|
||||
<ClCompile Include="jcapimin.c" />
|
||||
<ClCompile Include="jcapistd.c" />
|
||||
<ClCompile Include="jcarith.c" />
|
||||
<ClCompile Include="jccoefct.c" />
|
||||
<ClCompile Include="jccolor.c" />
|
||||
<ClCompile Include="jcdctmgr.c" />
|
||||
<ClCompile Include="jchuff.c" />
|
||||
<ClCompile Include="jcinit.c" />
|
||||
<ClCompile Include="jcmainct.c" />
|
||||
<ClCompile Include="jcmarker.c" />
|
||||
<ClCompile Include="jcmaster.c" />
|
||||
<ClCompile Include="jcomapi.c" />
|
||||
<ClCompile Include="jcparam.c" />
|
||||
<ClCompile Include="jcprepct.c" />
|
||||
<ClCompile Include="jcsample.c" />
|
||||
<ClCompile Include="jctrans.c" />
|
||||
<ClCompile Include="jdapimin.c" />
|
||||
<ClCompile Include="jdapistd.c" />
|
||||
<ClCompile Include="jdarith.c" />
|
||||
<ClCompile Include="jdatadst.c" />
|
||||
<ClCompile Include="jdatasrc.c" />
|
||||
<ClCompile Include="jdcoefct.c" />
|
||||
<ClCompile Include="jdcolor.c" />
|
||||
<ClCompile Include="jddctmgr.c" />
|
||||
<ClCompile Include="jdhuff.c" />
|
||||
<ClCompile Include="jdinput.c" />
|
||||
<ClCompile Include="jdmainct.c" />
|
||||
<ClCompile Include="jdmarker.c" />
|
||||
<ClCompile Include="jdmaster.c" />
|
||||
<ClCompile Include="jdmerge.c" />
|
||||
<ClCompile Include="jdpostct.c" />
|
||||
<ClCompile Include="jdsample.c" />
|
||||
<ClCompile Include="jdtrans.c" />
|
||||
<ClCompile Include="jerror.c" />
|
||||
<ClCompile Include="jfdctflt.c" />
|
||||
<ClCompile Include="jfdctfst.c" />
|
||||
<ClCompile Include="jfdctint.c" />
|
||||
<ClCompile Include="jidctflt.c" />
|
||||
<ClCompile Include="jidctfst.c" />
|
||||
<ClCompile Include="jidctint.c" />
|
||||
<ClCompile Include="jmemansi.c" />
|
||||
<ClCompile Include="jmemmgr.c" />
|
||||
<ClCompile Include="jquant1.c" />
|
||||
<ClCompile Include="jquant2.c" />
|
||||
<ClCompile Include="jutils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h" />
|
||||
<ClInclude Include="jdct.h" />
|
||||
<ClInclude Include="jerror.h" />
|
||||
<ClInclude Include="jinclude.h" />
|
||||
<ClInclude Include="jmemsys.h" />
|
||||
<ClInclude Include="jmorecfg.h" />
|
||||
<ClInclude Include="jpegint.h" />
|
||||
<ClInclude Include="jpeglib.h" />
|
||||
<ClInclude Include="jversion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
<?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">
|
||||
<ProjectName>libjpeg7</ProjectName>
|
||||
<ProjectGuid>{BC236261-77E8-4567-8D09-45CD02965EB6}</ProjectGuid>
|
||||
<RootNamespace>libjpeg</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</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>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c" />
|
||||
<ClCompile Include="jcapimin.c" />
|
||||
<ClCompile Include="jcapistd.c" />
|
||||
<ClCompile Include="jcarith.c" />
|
||||
<ClCompile Include="jccoefct.c" />
|
||||
<ClCompile Include="jccolor.c" />
|
||||
<ClCompile Include="jcdctmgr.c" />
|
||||
<ClCompile Include="jchuff.c" />
|
||||
<ClCompile Include="jcinit.c" />
|
||||
<ClCompile Include="jcmainct.c" />
|
||||
<ClCompile Include="jcmarker.c" />
|
||||
<ClCompile Include="jcmaster.c" />
|
||||
<ClCompile Include="jcomapi.c" />
|
||||
<ClCompile Include="jcparam.c" />
|
||||
<ClCompile Include="jcprepct.c" />
|
||||
<ClCompile Include="jcsample.c" />
|
||||
<ClCompile Include="jctrans.c" />
|
||||
<ClCompile Include="jdapimin.c" />
|
||||
<ClCompile Include="jdapistd.c" />
|
||||
<ClCompile Include="jdarith.c" />
|
||||
<ClCompile Include="jdatadst.c" />
|
||||
<ClCompile Include="jdatasrc.c" />
|
||||
<ClCompile Include="jdcoefct.c" />
|
||||
<ClCompile Include="jdcolor.c" />
|
||||
<ClCompile Include="jddctmgr.c" />
|
||||
<ClCompile Include="jdhuff.c" />
|
||||
<ClCompile Include="jdinput.c" />
|
||||
<ClCompile Include="jdmainct.c" />
|
||||
<ClCompile Include="jdmarker.c" />
|
||||
<ClCompile Include="jdmaster.c" />
|
||||
<ClCompile Include="jdmerge.c" />
|
||||
<ClCompile Include="jdpostct.c" />
|
||||
<ClCompile Include="jdsample.c" />
|
||||
<ClCompile Include="jdtrans.c" />
|
||||
<ClCompile Include="jerror.c" />
|
||||
<ClCompile Include="jfdctflt.c" />
|
||||
<ClCompile Include="jfdctfst.c" />
|
||||
<ClCompile Include="jfdctint.c" />
|
||||
<ClCompile Include="jidctflt.c" />
|
||||
<ClCompile Include="jidctfst.c" />
|
||||
<ClCompile Include="jidctint.c" />
|
||||
<ClCompile Include="jmemansi.c" />
|
||||
<ClCompile Include="jmemmgr.c" />
|
||||
<ClCompile Include="jquant1.c" />
|
||||
<ClCompile Include="jquant2.c" />
|
||||
<ClCompile Include="jutils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h" />
|
||||
<ClInclude Include="jdct.h" />
|
||||
<ClInclude Include="jerror.h" />
|
||||
<ClInclude Include="jinclude.h" />
|
||||
<ClInclude Include="jmemsys.h" />
|
||||
<ClInclude Include="jmorecfg.h" />
|
||||
<ClInclude Include="jpegint.h" />
|
||||
<ClInclude Include="jpeglib.h" />
|
||||
<ClInclude Include="jversion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
366
3rdparty/libjpeg/libjpeg.vcxproj.filters
vendored
366
3rdparty/libjpeg/libjpeg.vcxproj.filters
vendored
@@ -1,184 +1,184 @@
|
||||
<?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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcdctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jchuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcinit.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcomapi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcparam.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcprepct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jctrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatadst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatasrc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jddctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdhuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmerge.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdpostct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdtrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jerror.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemansi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jutils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jdct.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jerror.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jinclude.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmemsys.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmorecfg.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpegint.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpeglib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jversion.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
<?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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcdctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jchuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcinit.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcomapi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcparam.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcprepct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jctrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatadst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatasrc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jddctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdhuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmerge.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdpostct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdtrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jerror.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemansi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jutils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jdct.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jerror.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jinclude.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmemsys.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmorecfg.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpegint.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpeglib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jversion.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
165
3rdparty/libjpeg/libjpeg_vs2012.vcxproj
vendored
Normal file
165
3rdparty/libjpeg/libjpeg_vs2012.vcxproj
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
<?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">
|
||||
<ProjectName>libjpeg7</ProjectName>
|
||||
<ProjectGuid>{BC236261-77E8-4567-8D09-45CD02965EB6}</ProjectGuid>
|
||||
<RootNamespace>libjpeg</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</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>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c" />
|
||||
<ClCompile Include="jcapimin.c" />
|
||||
<ClCompile Include="jcapistd.c" />
|
||||
<ClCompile Include="jcarith.c" />
|
||||
<ClCompile Include="jccoefct.c" />
|
||||
<ClCompile Include="jccolor.c" />
|
||||
<ClCompile Include="jcdctmgr.c" />
|
||||
<ClCompile Include="jchuff.c" />
|
||||
<ClCompile Include="jcinit.c" />
|
||||
<ClCompile Include="jcmainct.c" />
|
||||
<ClCompile Include="jcmarker.c" />
|
||||
<ClCompile Include="jcmaster.c" />
|
||||
<ClCompile Include="jcomapi.c" />
|
||||
<ClCompile Include="jcparam.c" />
|
||||
<ClCompile Include="jcprepct.c" />
|
||||
<ClCompile Include="jcsample.c" />
|
||||
<ClCompile Include="jctrans.c" />
|
||||
<ClCompile Include="jdapimin.c" />
|
||||
<ClCompile Include="jdapistd.c" />
|
||||
<ClCompile Include="jdarith.c" />
|
||||
<ClCompile Include="jdatadst.c" />
|
||||
<ClCompile Include="jdatasrc.c" />
|
||||
<ClCompile Include="jdcoefct.c" />
|
||||
<ClCompile Include="jdcolor.c" />
|
||||
<ClCompile Include="jddctmgr.c" />
|
||||
<ClCompile Include="jdhuff.c" />
|
||||
<ClCompile Include="jdinput.c" />
|
||||
<ClCompile Include="jdmainct.c" />
|
||||
<ClCompile Include="jdmarker.c" />
|
||||
<ClCompile Include="jdmaster.c" />
|
||||
<ClCompile Include="jdmerge.c" />
|
||||
<ClCompile Include="jdpostct.c" />
|
||||
<ClCompile Include="jdsample.c" />
|
||||
<ClCompile Include="jdtrans.c" />
|
||||
<ClCompile Include="jerror.c" />
|
||||
<ClCompile Include="jfdctflt.c" />
|
||||
<ClCompile Include="jfdctfst.c" />
|
||||
<ClCompile Include="jfdctint.c" />
|
||||
<ClCompile Include="jidctflt.c" />
|
||||
<ClCompile Include="jidctfst.c" />
|
||||
<ClCompile Include="jidctint.c" />
|
||||
<ClCompile Include="jmemansi.c" />
|
||||
<ClCompile Include="jmemmgr.c" />
|
||||
<ClCompile Include="jquant1.c" />
|
||||
<ClCompile Include="jquant2.c" />
|
||||
<ClCompile Include="jutils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h" />
|
||||
<ClInclude Include="jdct.h" />
|
||||
<ClInclude Include="jerror.h" />
|
||||
<ClInclude Include="jinclude.h" />
|
||||
<ClInclude Include="jmemsys.h" />
|
||||
<ClInclude Include="jmorecfg.h" />
|
||||
<ClInclude Include="jpegint.h" />
|
||||
<ClInclude Include="jpeglib.h" />
|
||||
<ClInclude Include="jversion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
183
3rdparty/libjpeg/libjpeg_vs2012.vcxproj.filters
vendored
Normal file
183
3rdparty/libjpeg/libjpeg_vs2012.vcxproj.filters
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
<?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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcdctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jchuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcinit.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcomapi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcparam.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcprepct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jctrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatadst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatasrc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jddctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdhuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmerge.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdpostct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdtrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jerror.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemansi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jutils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jdct.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jerror.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jinclude.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmemsys.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmorecfg.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpegint.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpeglib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jversion.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
166
3rdparty/libjpeg/libjpeg_vs2013.vcxproj
vendored
Normal file
166
3rdparty/libjpeg/libjpeg_vs2013.vcxproj
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?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">
|
||||
<ProjectName>libjpeg7</ProjectName>
|
||||
<ProjectGuid>{BC236261-77E8-4567-8D09-45CD02965EB6}</ProjectGuid>
|
||||
<RootNamespace>libjpeg</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</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>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Devel|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c" />
|
||||
<ClCompile Include="jcapimin.c" />
|
||||
<ClCompile Include="jcapistd.c" />
|
||||
<ClCompile Include="jcarith.c" />
|
||||
<ClCompile Include="jccoefct.c" />
|
||||
<ClCompile Include="jccolor.c" />
|
||||
<ClCompile Include="jcdctmgr.c" />
|
||||
<ClCompile Include="jchuff.c" />
|
||||
<ClCompile Include="jcinit.c" />
|
||||
<ClCompile Include="jcmainct.c" />
|
||||
<ClCompile Include="jcmarker.c" />
|
||||
<ClCompile Include="jcmaster.c" />
|
||||
<ClCompile Include="jcomapi.c" />
|
||||
<ClCompile Include="jcparam.c" />
|
||||
<ClCompile Include="jcprepct.c" />
|
||||
<ClCompile Include="jcsample.c" />
|
||||
<ClCompile Include="jctrans.c" />
|
||||
<ClCompile Include="jdapimin.c" />
|
||||
<ClCompile Include="jdapistd.c" />
|
||||
<ClCompile Include="jdarith.c" />
|
||||
<ClCompile Include="jdatadst.c" />
|
||||
<ClCompile Include="jdatasrc.c" />
|
||||
<ClCompile Include="jdcoefct.c" />
|
||||
<ClCompile Include="jdcolor.c" />
|
||||
<ClCompile Include="jddctmgr.c" />
|
||||
<ClCompile Include="jdhuff.c" />
|
||||
<ClCompile Include="jdinput.c" />
|
||||
<ClCompile Include="jdmainct.c" />
|
||||
<ClCompile Include="jdmarker.c" />
|
||||
<ClCompile Include="jdmaster.c" />
|
||||
<ClCompile Include="jdmerge.c" />
|
||||
<ClCompile Include="jdpostct.c" />
|
||||
<ClCompile Include="jdsample.c" />
|
||||
<ClCompile Include="jdtrans.c" />
|
||||
<ClCompile Include="jerror.c" />
|
||||
<ClCompile Include="jfdctflt.c" />
|
||||
<ClCompile Include="jfdctfst.c" />
|
||||
<ClCompile Include="jfdctint.c" />
|
||||
<ClCompile Include="jidctflt.c" />
|
||||
<ClCompile Include="jidctfst.c" />
|
||||
<ClCompile Include="jidctint.c" />
|
||||
<ClCompile Include="jmemansi.c" />
|
||||
<ClCompile Include="jmemmgr.c" />
|
||||
<ClCompile Include="jquant1.c" />
|
||||
<ClCompile Include="jquant2.c" />
|
||||
<ClCompile Include="jutils.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h" />
|
||||
<ClInclude Include="jdct.h" />
|
||||
<ClInclude Include="jerror.h" />
|
||||
<ClInclude Include="jinclude.h" />
|
||||
<ClInclude Include="jmemsys.h" />
|
||||
<ClInclude Include="jmorecfg.h" />
|
||||
<ClInclude Include="jpegint.h" />
|
||||
<ClInclude Include="jpeglib.h" />
|
||||
<ClInclude Include="jversion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
184
3rdparty/libjpeg/libjpeg_vs2013.vcxproj.filters
vendored
Normal file
184
3rdparty/libjpeg/libjpeg_vs2013.vcxproj.filters
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jaricom.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jccolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcdctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jchuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcinit.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcomapi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcparam.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcprepct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jcsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jctrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapimin.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdapistd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdarith.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatadst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdatasrc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcoefct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdcolor.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jddctmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdhuff.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdinput.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmainct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmarker.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmaster.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdmerge.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdpostct.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdsample.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jdtrans.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jerror.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jfdctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctflt.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctfst.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jidctint.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemansi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jmemmgr.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant1.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jquant2.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="jutils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jconfig.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jdct.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jerror.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jinclude.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmemsys.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jmorecfg.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpegint.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jpeglib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jversion.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="change.log" />
|
||||
<None Include="filelist.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="readme.pcsx2.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
72
3rdparty/libpng/ANNOUNCE
vendored
72
3rdparty/libpng/ANNOUNCE
vendored
@@ -1,72 +0,0 @@
|
||||
Libpng 1.6.17 - March 26, 2015
|
||||
|
||||
This is a public release of libpng, intended for use in production codes.
|
||||
|
||||
Files available for download:
|
||||
|
||||
Source files with LF line endings (for Unix/Linux) and with a
|
||||
"configure" script
|
||||
|
||||
libpng-1.6.17.tar.xz (LZMA-compressed, recommended)
|
||||
libpng-1.6.17.tar.gz
|
||||
|
||||
Source files with CRLF line endings (for Windows), without the
|
||||
"configure" script
|
||||
|
||||
lpng1617.7z (LZMA-compressed, recommended)
|
||||
lpng1617.zip
|
||||
|
||||
Other information:
|
||||
|
||||
libpng-1.6.17-README.txt
|
||||
libpng-1.6.17-LICENSE.txt
|
||||
libpng-1.6.17-*.asc (armored detached GPG signatures)
|
||||
|
||||
Changes since the last public release (1.6.16):
|
||||
|
||||
Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h
|
||||
Corrected the width limit calculation in png_check_IHDR().
|
||||
Removed user limits from pngfix. Also pass NULL pointers to
|
||||
png_read_row to skip the unnecessary row de-interlace stuff.
|
||||
Added testing of png_set_packing() to pngvalid.c
|
||||
Regenerated configure scripts in the *.tar distributions with libtool-2.4.4
|
||||
Implement previously untested cases of libpng transforms in pngvalid.c
|
||||
Fixed byte order in 2-byte filler, in png_do_read_filler().
|
||||
Made the check for out-of-range values in png_set_tRNS() detect
|
||||
values that are exactly 2^bit_depth, and work on 16-bit platforms.
|
||||
Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47.
|
||||
Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and
|
||||
pngset.c to avoid warnings about dead code.
|
||||
Do not build png_product2() when it is unused.
|
||||
Display user limits in the output from pngtest.
|
||||
Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column
|
||||
and 1-million-row default limits in pnglibconf.dfa, that can be reset
|
||||
by the user at build time or run time. This provides a more robust
|
||||
defense against DOS and as-yet undiscovered overflows.
|
||||
Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default.
|
||||
Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins).
|
||||
Rebuilt configure scripts with automake-1.15 and libtool-2.4.6
|
||||
Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block
|
||||
of png.h.
|
||||
Avoid runtime checks when converting integer to png_byte with
|
||||
Visual Studio (Sergey Kosarevsky)
|
||||
Removed some comments that the configure script did not handle
|
||||
properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt.
|
||||
Free the unknown_chunks structure even when it contains no data.
|
||||
Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF
|
||||
for consistency, and remove some useless tests (Alexey Petruchik).
|
||||
Remove pnglibconf.h, pnglibconf.c, pnglibconf.pre, pnglibconf.dfn,
|
||||
and pnglibconf.out instead of pnglibconf.* in "make clean" (Cosmin).
|
||||
Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha
|
||||
value was wrong. It's not clear if this affected the final stored
|
||||
value; in the obvious code path the upper and lower 8-bits of the
|
||||
alpha value were identical and the alpha was truncated to 8-bits
|
||||
rather than dividing by 257 (John Bowler).
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
|
||||
to subscribe)
|
||||
or to glennrp at users.sourceforge.net
|
||||
|
||||
Glenn R-P
|
||||
5214
3rdparty/libpng/CHANGES
vendored
5214
3rdparty/libpng/CHANGES
vendored
File diff suppressed because it is too large
Load Diff
387
3rdparty/libpng/INSTALL
vendored
387
3rdparty/libpng/INSTALL
vendored
@@ -1,387 +0,0 @@
|
||||
|
||||
Installing libpng
|
||||
|
||||
Contents
|
||||
|
||||
I. Simple installation
|
||||
II. Rebuilding the configure scripts
|
||||
III. Using scripts/makefile*
|
||||
IV. Using cmake
|
||||
V. Directory structure
|
||||
VI. Building with project files
|
||||
VII. Building with makefiles
|
||||
VIII. Configuring libpng for 16-bit platforms
|
||||
IX. Configuring for DOS
|
||||
X. Configuring for Medium Model
|
||||
XI. Prepending a prefix to exported symbols
|
||||
XII. Configuring for compiler xxx:
|
||||
XIII. Removing unwanted object code
|
||||
XIV. Changes to the build and configuration of libpng in libpng-1.5.x
|
||||
XV. Setjmp/longjmp issues
|
||||
XVI. Other sources of information about libpng
|
||||
|
||||
I. Simple installation
|
||||
|
||||
On Unix/Linux and similar systems, you can simply type
|
||||
|
||||
./configure [--prefix=/path]
|
||||
make check
|
||||
make install
|
||||
|
||||
and ignore the rest of this document. "/path" is the path to the directory
|
||||
where you want to install the libpng "lib", "include", and "bin"
|
||||
subdirectories.
|
||||
|
||||
If you downloaded a GIT clone, you will need to run ./autogen.sh before
|
||||
running ./configure, to create "configure" and "Makefile.in" which are
|
||||
not included in the GIT repository.
|
||||
|
||||
Note that "configure" is only included in the "*.tar" distributions and not
|
||||
in the "*.zip" or "*.7z" distributions. If you downloaded one of those
|
||||
distributions, see "Building with project files" or "Building with makefiles",
|
||||
below.
|
||||
|
||||
II. Rebuilding the configure scripts
|
||||
|
||||
If configure does not work on your system, or if you have a need to
|
||||
change configure.ac or Makefile.am, and you have a reasonably
|
||||
up-to-date set of tools, running ./autogen.sh in a git clone before
|
||||
running ./configure may fix the problem. To be really sure that you
|
||||
aren't using any of the included pre-built scripts, you can do this:
|
||||
|
||||
./configure --enable-maintainer-mode
|
||||
make maintainer-clean
|
||||
./autogen.sh --maintainer --clean
|
||||
./autogen.sh --maintainer
|
||||
./configure [--prefix=/path] [other options]
|
||||
make
|
||||
make install
|
||||
make check
|
||||
|
||||
III. Using scripts/makefile*
|
||||
|
||||
Instead, you can use one of the custom-built makefiles in the
|
||||
"scripts" directory
|
||||
|
||||
cp scripts/pnglibconf.h.prebuilt pnglibconf.h
|
||||
cp scripts/makefile.system makefile
|
||||
make test
|
||||
make install
|
||||
|
||||
The files that are presently available in the scripts directory
|
||||
are listed and described in scripts/README.txt.
|
||||
|
||||
Or you can use one of the "projects" in the "projects" directory.
|
||||
|
||||
Before installing libpng, you must first install zlib, if it
|
||||
is not already on your system. zlib can usually be found
|
||||
wherever you got libpng; otherwise go to http://zlib.net. You can place
|
||||
zlib in in the same directory as libpng or in another directory.
|
||||
|
||||
If your system already has a preinstalled zlib you will still need
|
||||
to have access to the zlib.h and zconf.h include files that
|
||||
correspond to the version of zlib that's installed.
|
||||
|
||||
If you wish to test with a particular zlib that is not first in the
|
||||
standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS,
|
||||
and LD_LIBRARY_PATH in your environment before running "make test"
|
||||
or "make distcheck":
|
||||
|
||||
ZLIBLIB=/path/to/lib export ZLIBLIB
|
||||
ZLIBINC=/path/to/include export ZLIBINC
|
||||
CPPFLAGS="-I$ZLIBINC" export CPPFLAGS
|
||||
LDFLAGS="-L$ZLIBLIB" export LDFLAGS
|
||||
LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH
|
||||
|
||||
If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC
|
||||
in your environment and type "make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test".
|
||||
|
||||
IV. Using cmake
|
||||
|
||||
If you want to use "cmake" (see www.cmake.org), type
|
||||
|
||||
cmake . -DCMAKE_INSTALL_PREFIX=/path
|
||||
make
|
||||
make install
|
||||
|
||||
As when using the simple configure method described above, "/path" points to
|
||||
the installation directory where you want to put the libpng "lib", "include",
|
||||
and "bin" subdirectories.
|
||||
|
||||
V. Directory structure
|
||||
|
||||
You can rename the directories that you downloaded (they
|
||||
might be called "libpng-x.y.z" or "libpngNN" and "zlib-1.2.8"
|
||||
or "zlib128") so that you have directories called "zlib" and "libpng".
|
||||
|
||||
Your directory structure should look like this:
|
||||
|
||||
.. (the parent directory)
|
||||
libpng (this directory)
|
||||
INSTALL (this file)
|
||||
README
|
||||
*.h, *.c => libpng source files
|
||||
CMakeLists.txt => "cmake" script
|
||||
configuration files:
|
||||
configure.ac, configure, Makefile.am, Makefile.in,
|
||||
autogen.sh, config.guess, ltmain.sh, missing, libpng.pc.in,
|
||||
libpng-config.in, aclocal.m4, config.h.in, config.sub,
|
||||
depcomp, install-sh, mkinstalldirs, test-pngtest.sh
|
||||
contrib
|
||||
arm-neon, conftest, examples, gregbook, libtests, pngminim,
|
||||
pngminus, pngsuite, tools, visupng
|
||||
projects
|
||||
cbuilder5, owatcom, visualc71, vstudio, xcode
|
||||
scripts
|
||||
makefile.*
|
||||
*.def (module definition files)
|
||||
etc.
|
||||
pngtest.png
|
||||
etc.
|
||||
zlib
|
||||
README, *.h, *.c contrib, etc.
|
||||
|
||||
If the line endings in the files look funny, you may wish to get the other
|
||||
distribution of libpng. It is available in both tar.gz (UNIX style line
|
||||
endings) and zip (DOS style line endings) formats.
|
||||
|
||||
VI. Building with project files
|
||||
|
||||
If you are building libpng with MSVC, you can enter the
|
||||
libpng projects\visualc71 or vstudio directory and follow the instructions
|
||||
in README.txt.
|
||||
|
||||
Otherwise enter the zlib directory and follow the instructions in zlib/README,
|
||||
then come back here and run "configure" or choose the appropriate
|
||||
makefile.sys in the scripts directory.
|
||||
|
||||
VII. Building with makefiles
|
||||
|
||||
Copy the file (or files) that you need from the
|
||||
scripts directory into this directory, for example
|
||||
|
||||
MSDOS example: copy scripts\makefile.msc makefile
|
||||
copy scripts\pnglibconf.h.prebuilt pnglibconf.h
|
||||
UNIX example: cp scripts/makefile.std makefile
|
||||
cp scripts/pnglibconf.h.prebuilt pnglibconf.h
|
||||
|
||||
Read the makefile to see if you need to change any source or
|
||||
target directories to match your preferences.
|
||||
|
||||
Then read pnglibconf.dfa to see if you want to make any configuration
|
||||
changes.
|
||||
|
||||
Then just run "make" which will create the libpng library in
|
||||
this directory and "make test" which will run a quick test that reads
|
||||
the "pngtest.png" file and writes a "pngout.png" file that should be
|
||||
identical to it. Look for "9782 zero samples" in the output of the
|
||||
test. For more confidence, you can run another test by typing
|
||||
"pngtest pngnow.png" and looking for "289 zero samples" in the output.
|
||||
Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare
|
||||
your output with the result shown in contrib/pngsuite/README.
|
||||
|
||||
Most of the makefiles will allow you to run "make install" to
|
||||
put the library in its final resting place (if you want to
|
||||
do that, run "make install" in the zlib directory first if necessary).
|
||||
Some also allow you to run "make test-installed" after you have
|
||||
run "make install".
|
||||
|
||||
VIII. Configuring libpng for 16-bit platforms
|
||||
|
||||
You will want to look into zconf.h to tell zlib (and thus libpng) that
|
||||
it cannot allocate more than 64K at a time. Even if you can, the memory
|
||||
won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
|
||||
|
||||
IX. Configuring for DOS
|
||||
|
||||
For DOS users who only have access to the lower 640K, you will
|
||||
have to limit zlib's memory usage via a png_set_compression_mem_level()
|
||||
call. See zlib.h or zconf.h in the zlib library for more information.
|
||||
|
||||
X. Configuring for Medium Model
|
||||
|
||||
Libpng's support for medium model has been tested on most of the popular
|
||||
compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
|
||||
defined, and FAR gets defined to far in pngconf.h, and you should be
|
||||
all set. Everything in the library (except for zlib's structure) is
|
||||
expecting far data. You must use the typedefs with the p or pp on
|
||||
the end for pointers (or at least look at them and be careful). Make
|
||||
note that the rows of data are defined as png_bytepp, which is
|
||||
an "unsigned char far * far *".
|
||||
|
||||
XI. Prepending a prefix to exported symbols
|
||||
|
||||
Starting with libpng-1.6.0, you can configure libpng (when using the
|
||||
"configure" script) to prefix all exported symbols by means of the
|
||||
configuration option "--with-libpng-prefix=FOO_", where FOO_ can be any
|
||||
string beginning with a letter and containing only uppercase
|
||||
and lowercase letters, digits, and the underscore (i.e., a C language
|
||||
identifier). This creates a set of macros in pnglibconf.h, so this is
|
||||
transparent to applications; their function calls get transformed by
|
||||
the macros to use the modified names.
|
||||
|
||||
XII. Configuring for compiler xxx:
|
||||
|
||||
All includes for libpng are in pngconf.h. If you need to add, change
|
||||
or delete an include, this is the place to do it.
|
||||
The includes that are not needed outside libpng are placed in pngpriv.h,
|
||||
which is only used by the routines inside libpng itself.
|
||||
The files in libpng proper only include pngpriv.h and png.h, which
|
||||
in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
|
||||
As of libpng-1.5.0, pngpriv.h also includes three other private header
|
||||
files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material
|
||||
that previously appeared in the public headers.
|
||||
|
||||
XIII. Removing unwanted object code
|
||||
|
||||
There are a bunch of #define's in pngconf.h that control what parts of
|
||||
libpng are compiled. All the defines end in _SUPPORTED. If you are
|
||||
never going to use a capability, you can change the #define to #undef
|
||||
before recompiling libpng and save yourself code and data space, or
|
||||
you can turn off individual capabilities with defines that begin with
|
||||
PNG_NO_.
|
||||
|
||||
In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
|
||||
|
||||
You can also turn all of the transforms and ancillary chunk capabilities
|
||||
off en masse with compiler directives that define
|
||||
PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
|
||||
or all four, along with directives to turn on any of the capabilities that
|
||||
you do want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the
|
||||
extra transformations but still leave the library fully capable of reading
|
||||
and writing PNG files with all known public chunks. Use of the
|
||||
PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
|
||||
that is incapable of reading or writing ancillary chunks. If you are
|
||||
not using the progressive reading capability, you can turn that off
|
||||
with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
|
||||
capability, which you'll still have).
|
||||
|
||||
All the reading and writing specific code are in separate files, so the
|
||||
linker should only grab the files it needs. However, if you want to
|
||||
make sure, or if you are building a stand alone library, all the
|
||||
reading files start with "pngr" and all the writing files start with "pngw".
|
||||
The files that don't match either (like png.c, pngtrans.c, etc.)
|
||||
are used for both reading and writing, and always need to be included.
|
||||
The progressive reader is in pngpread.c
|
||||
|
||||
If you are creating or distributing a dynamically linked library (a .so
|
||||
or DLL file), you should not remove or disable any parts of the library,
|
||||
as this will cause applications linked with different versions of the
|
||||
library to fail if they call functions not available in your library.
|
||||
The size of the library itself should not be an issue, because only
|
||||
those sections that are actually used will be loaded into memory.
|
||||
|
||||
XIV. Changes to the build and configuration of libpng in libpng-1.5.x
|
||||
|
||||
Details of internal changes to the library code can be found in the CHANGES
|
||||
file and in the GIT repository logs. These will be of no concern to the vast
|
||||
majority of library users or builders; however, the few who configure libpng
|
||||
to a non-default feature set may need to change how this is done.
|
||||
|
||||
There should be no need for library builders to alter build scripts if
|
||||
these use the distributed build support - configure or the makefiles -
|
||||
however, users of the makefiles may care to update their build scripts
|
||||
to build pnglibconf.h where the corresponding makefile does not do so.
|
||||
|
||||
Building libpng with a non-default configuration has changed completely.
|
||||
The old method using pngusr.h should still work correctly even though the
|
||||
way pngusr.h is used in the build has been changed; however, library
|
||||
builders will probably want to examine the changes to take advantage of
|
||||
new capabilities and to simplify their build system.
|
||||
|
||||
A. Specific changes to library configuration capabilities
|
||||
|
||||
The exact mechanism used to control attributes of API functions has
|
||||
changed. A single set of operating system independent macro definitions
|
||||
is used and operating system specific directives are defined in
|
||||
pnglibconf.h
|
||||
|
||||
As part of this the mechanism used to choose procedure call standards on
|
||||
those systems that allow a choice has been changed. At present this only
|
||||
affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems
|
||||
running on Intel processors. As before, PNGAPI is defined where required
|
||||
to control the exported API functions; however, two new macros, PNGCBAPI
|
||||
and PNGCAPI, are used instead for callback functions (PNGCBAPI) and
|
||||
(PNGCAPI) for functions that must match a C library prototype (currently
|
||||
only png_longjmp_ptr, which must match the C longjmp function.) The new
|
||||
approach is documented in pngconf.h
|
||||
|
||||
Despite these changes, libpng 1.5.0 only supports the native C function
|
||||
calling standard on those platforms tested so far (__cdecl on Microsoft
|
||||
Windows). This is because the support requirements for alternative
|
||||
calling conventions seem to no longer exist. Developers who find it
|
||||
necessary to set PNG_API_RULE to 1 should advise the mailing list
|
||||
(png-mng-implement) of this and library builders who use Openwatcom and
|
||||
therefore set PNG_API_RULE to 2 should also contact the mailing list.
|
||||
|
||||
B. Changes to the configuration mechanism
|
||||
|
||||
Prior to libpng-1.5.0 library builders who needed to configure libpng
|
||||
had either to modify the exported pngconf.h header file to add system
|
||||
specific configuration or had to write feature selection macros into
|
||||
pngusr.h and cause this to be included into pngconf.h by defining
|
||||
PNG_USER_CONFIG. The latter mechanism had the disadvantage that an
|
||||
application built without PNG_USER_CONFIG defined would see the
|
||||
unmodified, default, libpng API and thus would probably fail to link.
|
||||
|
||||
These mechanisms still work in the configure build and in any makefile
|
||||
build that builds pnglibconf.h, although the feature selection macros
|
||||
have changed somewhat as described above. In 1.5.0, however, pngusr.h is
|
||||
processed only once, at the time the exported header file pnglibconf.h is
|
||||
built. pngconf.h no longer includes pngusr.h; therefore, pngusr.h is ignored
|
||||
after the build of pnglibconf.h and it is never included in an application
|
||||
build.
|
||||
|
||||
The formerly used alternative of adding a list of feature macros to the
|
||||
CPPFLAGS setting in the build also still works; however, the macros will be
|
||||
copied to pnglibconf.h and this may produce macro redefinition warnings
|
||||
when the individual C files are compiled.
|
||||
|
||||
All configuration now only works if pnglibconf.h is built from
|
||||
scripts/pnglibconf.dfa. This requires the program awk. Brian Kernighan
|
||||
(the original author of awk) maintains C source code of that awk and this
|
||||
and all known later implementations (often called by subtly different
|
||||
names - nawk and gawk for example) are adequate to build pnglibconf.h.
|
||||
The Sun Microsystems (now Oracle) program 'awk' is an earlier version
|
||||
and does not work; this may also apply to other systems that have a
|
||||
functioning awk called 'nawk'.
|
||||
|
||||
Configuration options are now documented in scripts/pnglibconf.dfa. This
|
||||
file also includes dependency information that ensures a configuration is
|
||||
consistent; that is, if a feature is switched off, dependent features are
|
||||
also switched off. As a recommended alternative to using feature macros in
|
||||
pngusr.h a system builder may also define equivalent options in pngusr.dfa
|
||||
(or, indeed, any file) and add that to the configuration by setting
|
||||
DFA_XTRA to the file name. The makefiles in contrib/pngminim illustrate
|
||||
how to do this, and also illustrate a case where pngusr.h is still required.
|
||||
|
||||
After you have built libpng, the definitions that were recorded in
|
||||
pnglibconf.h are available to your application (pnglibconf.h is included
|
||||
in png.h and gets installed alongside png.h and pngconf.h in your
|
||||
$PREFIX/include directory). Do not edit pnglibconf.h after you have built
|
||||
libpng, because than the settings would not accurately reflect the settings
|
||||
that were used to build libpng.
|
||||
|
||||
XV. Setjmp/longjmp issues
|
||||
|
||||
Libpng uses setjmp()/longjmp() for error handling. Unfortunately setjmp()
|
||||
is known to be not thread-safe on some platforms and we don't know of
|
||||
any platform where it is guaranteed to be thread-safe. Therefore, if
|
||||
your application is going to be using multiple threads, you should
|
||||
configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with
|
||||
-DPNG_NO_SETJMP on your compile line, or with
|
||||
|
||||
#undef PNG_SETJMP_SUPPORTED
|
||||
|
||||
in your pnglibconf.h or pngusr.h.
|
||||
|
||||
Starting with libpng-1.6.0, the library included a "simplified API".
|
||||
This requires setjmp/longjmp, so you must either build the library
|
||||
with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
|
||||
|
||||
XVI. Other sources of information about libpng:
|
||||
|
||||
Further information can be found in the README and libpng-manual.txt
|
||||
files, in the individual makefiles, in png.h, and the manual pages
|
||||
libpng.3 and png.5.
|
||||
215
3rdparty/libpng/README
vendored
215
3rdparty/libpng/README
vendored
@@ -1,215 +0,0 @@
|
||||
README for libpng version 1.6.17 - March 26, 2015 (shared library 16.0)
|
||||
See the note about version numbers near the top of png.h
|
||||
|
||||
See INSTALL for instructions on how to install libpng.
|
||||
|
||||
Libpng comes in several distribution formats. Get libpng-*.tar.gz or
|
||||
libpng-*.tar.xz or if you want UNIX-style line endings in the text files,
|
||||
or lpng*.7z or lpng*.zip if you want DOS-style line endings.
|
||||
|
||||
Version 0.89 was the first official release of libpng. Don't let the
|
||||
fact that it's the first release fool you. The libpng library has been in
|
||||
extensive use and testing since mid-1995. By late 1997 it had
|
||||
finally gotten to the stage where there hadn't been significant
|
||||
changes to the API in some time, and people have a bad feeling about
|
||||
libraries with versions < 1.0. Version 1.0.0 was released in
|
||||
March 1998.
|
||||
|
||||
****
|
||||
Note that some of the changes to the png_info structure render this
|
||||
version of the library binary incompatible with libpng-0.89 or
|
||||
earlier versions if you are using a shared library. The type of the
|
||||
"filler" parameter for png_set_filler() has changed from png_byte to
|
||||
png_uint_32, which will affect shared-library applications that use
|
||||
this function.
|
||||
|
||||
To avoid problems with changes to the internals of png info_struct,
|
||||
new APIs have been made available in 0.95 to avoid direct application
|
||||
access to info_ptr. These functions are the png_set_<chunk> and
|
||||
png_get_<chunk> functions. These functions should be used when
|
||||
accessing/storing the info_struct data, rather than manipulating it
|
||||
directly, to avoid such problems in the future.
|
||||
|
||||
It is important to note that the APIs did not make current programs
|
||||
that access the info struct directly incompatible with the new
|
||||
library, through libpng-1.2.x. In libpng-1.4.x, which was meant to
|
||||
be a transitional release, members of the png_struct and the
|
||||
info_struct can still be accessed, but the compiler will issue a
|
||||
warning about deprecated usage. Since libpng-1.5.0, direct access
|
||||
to these structs is not allowed, and the definitions of the structs
|
||||
reside in private pngstruct.h and pnginfo.h header files that are not
|
||||
accessible to applications. It is strongly suggested that new
|
||||
programs use the new APIs (as shown in example.c and pngtest.c), and
|
||||
older programs be converted to the new format, to facilitate upgrades
|
||||
in the future.
|
||||
****
|
||||
|
||||
Additions since 0.90 include the ability to compile libpng as a
|
||||
Windows DLL, and new APIs for accessing data in the info struct.
|
||||
Experimental functions include the ability to set weighting and cost
|
||||
factors for row filter selection, direct reads of integers from buffers
|
||||
on big-endian processors that support misaligned data access, faster
|
||||
methods of doing alpha composition, and more accurate 16->8 bit color
|
||||
conversion.
|
||||
|
||||
The additions since 0.89 include the ability to read from a PNG stream
|
||||
which has had some (or all) of the signature bytes read by the calling
|
||||
application. This also allows the reading of embedded PNG streams that
|
||||
do not have the PNG file signature. As well, it is now possible to set
|
||||
the library action on the detection of chunk CRC errors. It is possible
|
||||
to set different actions based on whether the CRC error occurred in a
|
||||
critical or an ancillary chunk.
|
||||
|
||||
The changes made to the library, and bugs fixed are based on discussions
|
||||
on the PNG-implement mailing list and not on material submitted
|
||||
privately to Guy, Andreas, or Glenn. They will forward any good
|
||||
suggestions to the list.
|
||||
|
||||
For a detailed description on using libpng, read libpng-manual.txt. For
|
||||
examples of libpng in a program, see example.c and pngtest.c. For usage
|
||||
information and restrictions (what little they are) on libpng, see
|
||||
png.h. For a description on using zlib (the compression library used by
|
||||
libpng) and zlib's restrictions, see zlib.h
|
||||
|
||||
I have included a general makefile, as well as several machine and
|
||||
compiler specific ones, but you may have to modify one for your own needs.
|
||||
|
||||
You should use zlib 1.0.4 or later to run this, but it MAY work with
|
||||
versions as old as zlib 0.95. Even so, there are bugs in older zlib
|
||||
versions which can cause the output of invalid compression streams for
|
||||
some images. You will definitely need zlib 1.0.4 or later if you are
|
||||
taking advantage of the MS-DOS "far" structure allocation for the small
|
||||
and medium memory models. You should also note that zlib is a
|
||||
compression library that is useful for more things than just PNG files.
|
||||
You can use zlib as a drop-in replacement for fread() and fwrite() if
|
||||
you are so inclined.
|
||||
|
||||
zlib should be available at the same place that libpng is, or at zlib.net.
|
||||
|
||||
You may also want a copy of the PNG specification. It is available
|
||||
as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find
|
||||
these at http://www.libpng.org/pub/png/documents/
|
||||
|
||||
This code is currently being archived at libpng.sf.net in the
|
||||
[DOWNLOAD] area, and at ftp://ftp.simplesystems.org. If you can't find it
|
||||
in any of those places, e-mail me, and I'll help you find it.
|
||||
|
||||
I am not a lawyer, but I believe that the Export Control Classification
|
||||
Number (ECCN) for libpng is EAR99, which means not subject to export
|
||||
controls or International Traffic in Arms Regulations (ITAR) because it
|
||||
is open source, publicly available software, that does not contain any
|
||||
encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b).
|
||||
|
||||
If you have any code changes, requests, problems, etc., please e-mail
|
||||
them to me. Also, I'd appreciate any make files or project files,
|
||||
and any modifications you needed to make to get libpng to compile,
|
||||
along with a #define variable to tell what compiler/system you are on.
|
||||
If you needed to add transformations to libpng, or wish libpng would
|
||||
provide the image in a different way, drop me a note (and code, if
|
||||
possible), so I can consider supporting the transformation.
|
||||
Finally, if you get any warning messages when compiling libpng
|
||||
(note: not zlib), and they are easy to fix, I'd appreciate the
|
||||
fix. Please mention "libpng" somewhere in the subject line. Thanks.
|
||||
|
||||
This release was created and will be supported by myself (of course
|
||||
based in a large way on Guy's and Andreas' earlier work), and the PNG
|
||||
development group.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at
|
||||
lists.sourceforge.net (subscription required; visit
|
||||
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
|
||||
to subscribe) or to glennrp at users.sourceforge.net
|
||||
|
||||
You can't reach Guy, the original libpng author, at the addresses
|
||||
given in previous versions of this document. He and Andreas will
|
||||
read mail addressed to the png-implement list, however.
|
||||
|
||||
Please do not send general questions about PNG. Send them to
|
||||
png-mng-misc at lists.sf.net (subscription required; visit
|
||||
https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
|
||||
subscribe). If you have a question about something
|
||||
in the PNG specification that is related to using libpng, send it
|
||||
to me. Send me any questions that start with "I was using libpng,
|
||||
and ...". If in doubt, send questions to me. I'll bounce them
|
||||
to others, if necessary.
|
||||
|
||||
Please do not send suggestions on how to change PNG. We have
|
||||
been discussing PNG for nineteen years now, and it is official and
|
||||
finished. If you have suggestions for libpng, however, I'll
|
||||
gladly listen. Even if your suggestion is not used immediately,
|
||||
it may be used later.
|
||||
|
||||
Files in this distribution:
|
||||
|
||||
ANNOUNCE => Announcement of this version, with recent changes
|
||||
CHANGES => Description of changes between libpng versions
|
||||
KNOWNBUG => List of known bugs and deficiencies
|
||||
LICENSE => License to use and redistribute libpng
|
||||
README => This file
|
||||
TODO => Things not implemented in the current library
|
||||
Y2KINFO => Statement of Y2K compliance
|
||||
example.c => Example code for using libpng functions
|
||||
libpng.3 => manual page for libpng (includes libpng-manual.txt)
|
||||
libpng-manual.txt => Description of libpng and its functions
|
||||
libpngpf.3 => manual page for libpng's private functions
|
||||
png.5 => manual page for the PNG format
|
||||
png.c => Basic interface functions common to library
|
||||
png.h => Library function and interface declarations (public)
|
||||
pngpriv.h => Library function and interface declarations (private)
|
||||
pngconf.h => System specific library configuration (public)
|
||||
pngstruct.h => png_struct declaration (private)
|
||||
pnginfo.h => png_info struct declaration (private)
|
||||
pngdebug.h => debugging macros (private)
|
||||
pngerror.c => Error/warning message I/O functions
|
||||
pngget.c => Functions for retrieving info from struct
|
||||
pngmem.c => Memory handling functions
|
||||
pngbar.png => PNG logo, 88x31
|
||||
pngnow.png => PNG logo, 98x31
|
||||
pngpread.c => Progressive reading functions
|
||||
pngread.c => Read data/helper high-level functions
|
||||
pngrio.c => Lowest-level data read I/O functions
|
||||
pngrtran.c => Read data transformation functions
|
||||
pngrutil.c => Read data utility functions
|
||||
pngset.c => Functions for storing data into the info_struct
|
||||
pngtest.c => Library test program
|
||||
pngtest.png => Library test sample image
|
||||
pngtrans.c => Common data transformation functions
|
||||
pngwio.c => Lowest-level write I/O functions
|
||||
pngwrite.c => High-level write functions
|
||||
pngwtran.c => Write data transformations
|
||||
pngwutil.c => Write utility functions
|
||||
arm => Contains optimized code for the ARM platform
|
||||
contrib => Contributions
|
||||
examples => Example programs
|
||||
gregbook => source code for PNG reading and writing, from
|
||||
Greg Roelofs' "PNG: The Definitive Guide",
|
||||
O'Reilly, 1999
|
||||
libtests => Test programs
|
||||
pngminim => Minimal decoder, encoder, and progressive decoder
|
||||
programs demonstrating use of pngusr.dfa
|
||||
pngminus => Simple pnm2png and png2pnm programs
|
||||
pngsuite => Test images
|
||||
tools => Various tools
|
||||
visupng => Contains a MSVC workspace for VisualPng
|
||||
projects => Contains project files and workspaces for
|
||||
building a DLL
|
||||
owatcom => Contains a WATCOM project for building libpng
|
||||
visualc71 => Contains a Microsoft Visual C++ (MSVC)
|
||||
workspace for building libpng and zlib
|
||||
vstudio => Contains a Microsoft Visual C++ (MSVC)
|
||||
workspace for building libpng and zlib
|
||||
scripts => Directory containing scripts for building libpng:
|
||||
(see scripts/README.txt for the list of scripts)
|
||||
|
||||
Good luck, and happy coding.
|
||||
|
||||
-Glenn Randers-Pehrson (current maintainer, since 1998)
|
||||
Internet: glennrp at users.sourceforge.net
|
||||
|
||||
-Andreas Eric Dilger (former maintainer, 1996-1997)
|
||||
Internet: adilger at enel.ucalgary.ca
|
||||
Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
|
||||
|
||||
-Guy Eric Schalnat (original author and former maintainer, 1995-1996)
|
||||
(formerly of Group 42, Inc)
|
||||
Internet: gschal at infinet.com
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user