diff options
Diffstat (limited to 'Src/adpcm')
-rw-r--r-- | Src/adpcm/adpcm.rc | 76 | ||||
-rw-r--r-- | Src/adpcm/adpcm.sln | 31 | ||||
-rw-r--r-- | Src/adpcm/adpcm.vcxproj | 253 | ||||
-rw-r--r-- | Src/adpcm/adpcm.vcxproj.filters | 56 | ||||
-rw-r--r-- | Src/adpcm/api.h | 5 | ||||
-rw-r--r-- | Src/adpcm/avi_adpcm_decoder.cpp | 233 | ||||
-rw-r--r-- | Src/adpcm/avi_adpcm_decoder.h | 38 | ||||
-rw-r--r-- | Src/adpcm/avi_ima_adpcm_decoder.cpp | 236 | ||||
-rw-r--r-- | Src/adpcm/avi_ima_adpcm_decoder.h | 24 | ||||
-rw-r--r-- | Src/adpcm/flv_adpcm_decoder.cpp | 141 | ||||
-rw-r--r-- | Src/adpcm/flv_adpcm_decoder.h | 35 | ||||
-rw-r--r-- | Src/adpcm/main.cpp | 78 | ||||
-rw-r--r-- | Src/adpcm/resource.h | 14 | ||||
-rw-r--r-- | Src/adpcm/version.rc2 | 39 |
14 files changed, 1259 insertions, 0 deletions
diff --git a/Src/adpcm/adpcm.rc b/Src/adpcm/adpcm.rc new file mode 100644 index 00000000..fcff7711 --- /dev/null +++ b/Src/adpcm/adpcm.rc @@ -0,0 +1,76 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/adpcm/adpcm.sln b/Src/adpcm/adpcm.sln new file mode 100644 index 00000000..db03d252 --- /dev/null +++ b/Src/adpcm/adpcm.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29424.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adpcm", "adpcm.vcxproj", "{7748B57A-BF73-4784-8CDF-1866FF545762}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7748B57A-BF73-4784-8CDF-1866FF545762}.Debug|Win32.ActiveCfg = Debug|Win32 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Debug|Win32.Build.0 = Debug|Win32 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Release|Win32.ActiveCfg = Release|Win32 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Release|Win32.Build.0 = Release|Win32 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Debug|x64.ActiveCfg = Debug|x64 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Debug|x64.Build.0 = Debug|x64 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Release|x64.ActiveCfg = Release|x64 + {7748B57A-BF73-4784-8CDF-1866FF545762}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {516129C3-ADEE-4078-B855-A65A93418B6E} + EndGlobalSection +EndGlobal diff --git a/Src/adpcm/adpcm.vcxproj b/Src/adpcm/adpcm.vcxproj new file mode 100644 index 00000000..a318b2c5 --- /dev/null +++ b/Src/adpcm/adpcm.vcxproj @@ -0,0 +1,253 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.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="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7748B57A-BF73-4784-8CDF-1866FF545762}</ProjectGuid> + <RootNamespace>adpcm</RootNamespace> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </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" /> + </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" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <TargetExt>.w5s</TargetExt> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ADPCM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;ADPCM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ADPCM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;ADPCM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\f263\BitReader.h" /> + <ClInclude Include="api.h" /> + <ClInclude Include="avi_adpcm_decoder.h" /> + <ClInclude Include="avi_ima_adpcm_decoder.h" /> + <ClInclude Include="flv_adpcm_decoder.h" /> + <ClInclude Include="resource.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\f263\BitReader.cpp" /> + <ClCompile Include="avi_adpcm_decoder.cpp" /> + <ClCompile Include="avi_ima_adpcm_decoder.cpp" /> + <ClCompile Include="flv_adpcm_decoder.cpp" /> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="adpcm.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Wasabi\Wasabi.vcxproj"> + <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Src/adpcm/adpcm.vcxproj.filters b/Src/adpcm/adpcm.vcxproj.filters new file mode 100644 index 00000000..b6c906ac --- /dev/null +++ b/Src/adpcm/adpcm.vcxproj.filters @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="avi_adpcm_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="avi_ima_adpcm_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\f263\BitReader.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="flv_adpcm_decoder.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="api.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_adpcm_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="avi_ima_adpcm_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\f263\BitReader.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="flv_adpcm_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{844ebf96-e3e0-4951-b990-056179a1de29}</UniqueIdentifier> + </Filter> + <Filter Include="Ressource Files"> + <UniqueIdentifier>{0ca25780-ee00-4a1f-a79e-4ba9db32bffc}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{7c46a456-de59-4c16-8bcb-91e182a5438c}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="adpcm.rc"> + <Filter>Ressource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Src/adpcm/api.h b/Src/adpcm/api.h new file mode 100644 index 00000000..6555c035 --- /dev/null +++ b/Src/adpcm/api.h @@ -0,0 +1,5 @@ +#pragma once + +#include <api/service/api_service.h> +extern api_service *serviceManager; +#define WASABI_API_SVC serviceManager diff --git a/Src/adpcm/avi_adpcm_decoder.cpp b/Src/adpcm/avi_adpcm_decoder.cpp new file mode 100644 index 00000000..46c6ac57 --- /dev/null +++ b/Src/adpcm/avi_adpcm_decoder.cpp @@ -0,0 +1,233 @@ +#include "avi_adpcm_decoder.h" +#include "avi_ima_adpcm_decoder.h" + +#pragma pack(push, 1) +typedef int16_t ms_adpcm_coefficients[2]; +struct ms_adpcm_format +{ + nsavi::audio_format format; + uint16_t samples_per_block; + uint16_t number_of_coefficients; + ms_adpcm_coefficients coefficients[1]; +}; +#pragma pack(pop) + +int AVIDecoder::CreateAudioDecoder(const nsavi::AVIH *avi_header, + const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, + unsigned int preferred_bits, unsigned int max_channels, bool floating_point, + ifc_aviaudiodecoder **decoder) +{ + const nsavi::audio_format *format = (const nsavi::audio_format *)stream_format; + + if (format->format == nsavi::audio_format_ms_adpcm) + { + // TODO: verify waveformat sizes + *decoder = new MS_ADPCM_AVIDecoder( (const ms_adpcm_format *)format, stream_header); + return CREATEDECODER_SUCCESS; + } + else if (format->format == nsavi::audio_format_ima_adpcm) + { + // TODO: verify waveformat sizes + *decoder = new IMA_ADPCM_AVIDecoder((const ima_adpcm_format *)format, stream_header); + return CREATEDECODER_SUCCESS; + } + + return CREATEDECODER_NOT_MINE; + +} + +#define CBCLASS AVIDecoder +START_DISPATCH; +CB(CREATE_AUDIO_DECODER, CreateAudioDecoder) +END_DISPATCH; +#undef CBCLASS + +int ms_adpcm_adaptationtable[] = { 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 }; +//int ms_adpcm_adaptcoeff1[] = { 256, 512, 0, 192, 240, 460, 392 } ; +//int ms_adpcm_adaptcoeff2[] = { 0, -256, 0, 64, 0, -208, -232 } ; + + +MS_ADPCM_AVIDecoder::MS_ADPCM_AVIDecoder(const ms_adpcm_format *adpcmformat, const nsavi::STRH *stream_header) : adpcmformat(adpcmformat), stream_header(stream_header) +{ +} + +int MS_ADPCM_AVIDecoder::OutputFrameSize(size_t *frame_size) +{ + int channels = adpcmformat->format.channels; + *frame_size = ((adpcmformat->format.block_align - 7*channels)*2 + 2*channels) * 2; + return AVI_SUCCESS; +} + +int MS_ADPCM_AVIDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat) +{ + if (adpcmformat) + { + *sampleRate = adpcmformat->format.sample_rate; + *channels = adpcmformat->format.channels; + *bitsPerSample = 16; + *isFloat = false; + return AVI_SUCCESS; + } + else + { + return AVI_FAILURE; + } +} + +int MS_ADPCM_AVIDecoder::DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes) +{ + const ms_adpcm_coefficients *ms_adpcm_adaptcoeff = adpcmformat->coefficients; + // TODO: use default coef values if they aren't present + if (adpcmformat->format.channels == 1) + { + size_t adpcm_stream_length = *inputBufferBytes; + if (adpcm_stream_length < adpcmformat->format.block_align) // i'm not even going to consider the possibility of adpcm frames split across avi chunks + return AVI_FAILURE; + + adpcm_stream_length = adpcmformat->format.block_align; // do one block at a time, in_avi will call us again + + if (adpcm_stream_length < 7) + return AVI_FAILURE; + + int16_t *out16 = (int16_t *)outputBuffer; + size_t out16_length = *outputBufferBytes/2; + + const uint8_t *adpcm8 = (const uint8_t *)(*inputBuffer); + + uint8_t block_predictor = *adpcm8++; + if (block_predictor > adpcmformat->number_of_coefficients) + return AVI_FAILURE; + + int32_t coef1 = ms_adpcm_adaptcoeff[block_predictor][0]; + int32_t coef2 = ms_adpcm_adaptcoeff[block_predictor][1]; + + const uint16_t *adpcm16 = (const uint16_t *)adpcm8; + + int16_t delta = *adpcm16++; + + int16_t sample1 = out16[1] = *adpcm16++; + int16_t sample2 = out16[0] = *adpcm16++; + int i=2; + adpcm_stream_length-=7; + adpcm8 = (const uint8_t *)adpcm16; + while (adpcm_stream_length-- && out16_length) + { + int32_t predictor = ((int32_t)sample1 * coef1 + (int32_t)sample2 * coef2)>>8; + uint32_t nibble = *adpcm8 >> 4; + int32_t signed_nibble = ((int32_t)nibble << 28) >> 28; + predictor += signed_nibble*delta; + predictor = max(predictor, -32768); + predictor = min(predictor, 32767); + sample2=sample1; + sample1=out16[i++]=predictor; + out16_length--; + delta = (ms_adpcm_adaptationtable[nibble]*delta)>>8; + delta = max(delta, 16); + + predictor = ((int32_t)sample1 * coef1 + (int32_t)sample2 * coef2)>>8; + nibble = *adpcm8++ & 0x0F; + signed_nibble = ((int32_t)nibble << 28) >> 28; + predictor += signed_nibble*delta; + predictor = max(predictor, -32768); + predictor = min(predictor, 32767); + sample2=sample1; + sample1=out16[i++]=predictor; + out16_length--; + delta = (ms_adpcm_adaptationtable[nibble]*delta)>>8; + delta = max(delta, 16); + } + *inputBufferBytes -= adpcmformat->format.block_align; + *inputBuffer = (void *)adpcm8; + *outputBufferBytes = i*2; + return AVI_SUCCESS; + } + else if (adpcmformat->format.channels == 2) + { + size_t adpcm_stream_length = *inputBufferBytes; + if (adpcm_stream_length < adpcmformat->format.block_align) // i'm not even going to consider the possibility of adpcm frames split across avi chunks + return AVI_FAILURE; + + adpcm_stream_length = adpcmformat->format.block_align; // do one block at a time, in_avi will call us again + + if (adpcm_stream_length < 14) + return AVI_FAILURE; + + int16_t *out16 = (int16_t *)outputBuffer; + size_t out16_length = *outputBufferBytes/2; + + const uint8_t *adpcm8 = (const uint8_t *)(*inputBuffer); + + uint8_t block_predictor_left = *adpcm8++; + if (block_predictor_left > adpcmformat->number_of_coefficients) + return AVI_FAILURE; + + uint8_t block_predictor_right = *adpcm8++; + if (block_predictor_right > adpcmformat->number_of_coefficients) + return AVI_FAILURE; + + int32_t coef1_left = ms_adpcm_adaptcoeff[block_predictor_left][0]; + int32_t coef2_left = ms_adpcm_adaptcoeff[block_predictor_left][1]; + int32_t coef1_right = ms_adpcm_adaptcoeff[block_predictor_right][0]; + int32_t coef2_right = ms_adpcm_adaptcoeff[block_predictor_right][1]; + + const uint16_t *adpcm16 = (const uint16_t *)adpcm8; + + int16_t delta_left = *adpcm16++; + int16_t delta_right = *adpcm16++; + + int16_t sample1_left = out16[2] = *adpcm16++; + int16_t sample1_right = out16[3] = *adpcm16++; + int16_t sample2_left = out16[0] = *adpcm16++; + int16_t sample2_right = out16[1] = *adpcm16++; + int i=4; + adpcm_stream_length-=14; + adpcm8 = (const uint8_t *)adpcm16; + while (adpcm_stream_length-- && out16_length) + { + int32_t predictor = ((int32_t)sample1_left * coef1_left + (int32_t)sample2_left * coef2_left)>>8; + uint32_t nibble = *adpcm8 >> 4; + int32_t signed_nibble = ((int32_t)nibble << 28) >> 28; + predictor += signed_nibble*delta_left; + predictor = max(predictor, -32768); + predictor = min(predictor, 32767); + sample2_left=sample1_left; + sample1_left=out16[i++]=predictor; + out16_length--; + delta_left = (ms_adpcm_adaptationtable[nibble]*delta_left)>>8; + delta_left = max(delta_left, 16); + + predictor = ((int32_t)sample1_right * coef1_right + (int32_t)sample2_right * coef2_right)>>8; + nibble = *adpcm8++ & 0x0F; + signed_nibble = ((int32_t)nibble << 28) >> 28; + predictor += signed_nibble*delta_right; + predictor = max(predictor, -32768); + predictor = min(predictor, 32767); + sample2_right=sample1_right; + sample1_right=out16[i++]=predictor; + out16_length--; + delta_right = (ms_adpcm_adaptationtable[nibble]*delta_right)>>8; + delta_right = max(delta_right, 16); + } + *inputBufferBytes -= adpcmformat->format.block_align; + *inputBuffer = (void *)adpcm8; + *outputBufferBytes = i*2; + return AVI_SUCCESS; + } + + return AVI_FAILURE; + +} + +void MS_ADPCM_AVIDecoder::Close() +{ + delete this; +} + +#define CBCLASS MS_ADPCM_AVIDecoder +START_DISPATCH; +CB(OUTPUT_FRAME_SIZE, OutputFrameSize) +CB(GET_OUTPUT_PROPERTIES, GetOutputProperties) +CB(DECODE_CHUNK, DecodeChunk) +VCB(CLOSE, Close) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/adpcm/avi_adpcm_decoder.h b/Src/adpcm/avi_adpcm_decoder.h new file mode 100644 index 00000000..6fcb91aa --- /dev/null +++ b/Src/adpcm/avi_adpcm_decoder.h @@ -0,0 +1,38 @@ +#pragma once +#include "../Plugins/Input/in_avi/svc_avidecoder.h" +#include "../Plugins/Input/in_avi/ifc_aviaudiodecoder.h" + +// {E0BCBBDF-F1DC-4459-8C0A-4F3FFECFC80E} +static const GUID avi_adpcm_guid = +{ 0xe0bcbbdf, 0xf1dc, 0x4459, { 0x8c, 0xa, 0x4f, 0x3f, 0xfe, 0xcf, 0xc8, 0xe } }; + +struct ms_adpcm_format; + +class AVIDecoder : public svc_avidecoder +{ +public: + static const char *getServiceName() { return "ADPCM AVI Decoder"; } + static GUID getServiceGuid() { return avi_adpcm_guid; } + int CreateAudioDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, unsigned int preferred_bits, unsigned int max_channels, bool floating_point, ifc_aviaudiodecoder **decoder); +protected: + RECVS_DISPATCH; +}; + +class MS_ADPCM_AVIDecoder : public ifc_aviaudiodecoder +{ +public: + MS_ADPCM_AVIDecoder(const ms_adpcm_format *adpcmformat, const nsavi::STRH *stream_header); + +protected: + RECVS_DISPATCH; +private: + /* ifc_aviaudiodecoder implementation */ + int OutputFrameSize(size_t *frame_size); + int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat); + int DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes); + void Close(); + +private: + const ms_adpcm_format *adpcmformat; + const nsavi::STRH *stream_header; +};
\ No newline at end of file diff --git a/Src/adpcm/avi_ima_adpcm_decoder.cpp b/Src/adpcm/avi_ima_adpcm_decoder.cpp new file mode 100644 index 00000000..5050a66d --- /dev/null +++ b/Src/adpcm/avi_ima_adpcm_decoder.cpp @@ -0,0 +1,236 @@ +#include "avi_ima_adpcm_decoder.h" +#include "../f263/BitReader.h" + +#pragma pack(push, 1) +struct ima_adpcm_format +{ + nsavi::audio_format format; + uint16_t samples_per_block; +}; +#pragma pack(pop) + +IMA_ADPCM_AVIDecoder::IMA_ADPCM_AVIDecoder(const ima_adpcm_format *adpcmformat, const nsavi::STRH *stream_header) : adpcmformat(adpcmformat), stream_header(stream_header) +{ +} + +int IMA_ADPCM_AVIDecoder::OutputFrameSize(size_t *frame_size) +{ + int channels = adpcmformat->format.channels; + *frame_size = ((adpcmformat->format.block_align - 7*channels)*2 + 2*channels) * 2; + return AVI_SUCCESS; +} + +int IMA_ADPCM_AVIDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat) +{ + if (adpcmformat) + { + *sampleRate = adpcmformat->format.sample_rate; + *channels = adpcmformat->format.channels; + *bitsPerSample = 16; + *isFloat = false; + return AVI_SUCCESS; + } + else + { + return AVI_FAILURE; + } +} + +static int index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +static int step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +int IMA_ADPCM_AVIDecoder::DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes) +{ + if (adpcmformat->format.channels == 1) + { + size_t adpcm_stream_length = *inputBufferBytes; + if (adpcm_stream_length < adpcmformat->format.block_align) // i'm not even going to consider the possibility of adpcm frames split across avi chunks + return AVI_FAILURE; + + adpcm_stream_length = adpcmformat->format.block_align; // do one block at a time, in_avi will call us again + + if (adpcm_stream_length < 7) + return AVI_FAILURE; + + int16_t *out16 = (int16_t *)outputBuffer; + size_t out16_length = *outputBufferBytes/2; + + const uint8_t *adpcm_data = (const uint8_t *)(*inputBuffer); + + int predictor = *(int16_t *)adpcm_data; + *out16++ = predictor; + adpcm_data+=2; + out16_length--; + int step_index = *adpcm_data; + if (step_index > 88) + return AVI_FAILURE; + adpcm_data+=2; + + BitReader reader; + reader.data = adpcm_data; + reader.numBits = (uint32_t)(*inputBufferBytes - 4)*8; + + while (reader.numBits >= 8 && out16_length) + { + int diff, step, nibble; + + step = step_table[step_index]; + nibble = reader.getbits(4); + step_index += index_table[nibble]; + step_index = min(step_index, 88); + step_index = max(step_index, 0); + + diff = step>>3; + if(nibble&4) + diff += step; + if(nibble&2) + diff += step>>1; + if(nibble&1) + diff += step>>2; + + if (nibble&8) + predictor -= diff; + else + predictor += diff; + predictor = min(predictor, 32767); + predictor = max(predictor, -32768); + *out16++ = predictor; + out16_length--; + } + *inputBuffer = (uint8_t *)(*inputBuffer) + adpcm_stream_length; + *inputBufferBytes -= adpcm_stream_length; + *outputBufferBytes = adpcmformat->samples_per_block*2; + return AVI_SUCCESS; + } + else if (adpcmformat->format.channels == 2) + { + size_t adpcm_stream_length = *inputBufferBytes; + if (adpcm_stream_length < adpcmformat->format.block_align) // i'm not even going to consider the possibility of adpcm frames split across avi chunks + return AVI_FAILURE; + + adpcm_stream_length = adpcmformat->format.block_align; // do one block at a time, in_avi will call us again + + if (adpcm_stream_length < 8) + return AVI_FAILURE; + + int16_t *out16 = (int16_t *)outputBuffer; + size_t out16_length = *outputBufferBytes/2; + + const uint8_t *adpcm_data = (const uint8_t *)(*inputBuffer); + + int predictor_left = *(int16_t *)adpcm_data; + *out16++ = predictor_left; + adpcm_data+=2; + out16_length--; + int step_index_left = *adpcm_data; + if (step_index_left > 88) + return AVI_FAILURE; + adpcm_data+=2; + + int predictor_right = *(int16_t *)adpcm_data; + *out16++ = predictor_right; + adpcm_data+=2; + out16_length--; + int step_index_right = *adpcm_data; + if (step_index_right > 88) + return AVI_FAILURE; + adpcm_data+=2; + + BitReader reader; + reader.data = adpcm_data; + reader.numBits = (uint32_t)(*inputBufferBytes - 8)*8; + + while (reader.numBits >= 8 && out16_length > 15) + { + int nibbles_left[8] = {0}; + int nibbles_right[8] = {0}; + for (int i=0;i<8;i++) + nibbles_left[i] = reader.getbits(4); + + for (int i=0;i<8;i++) + nibbles_right[i] = reader.getbits(4); + + for (int i=0;i<8;i++) + { + int diff, step, nibble; + step = step_table[step_index_left]; + nibble = nibbles_left[i]; + step_index_left += index_table[nibble]; + step_index_left = min(step_index_left, 88); + step_index_left = max(step_index_left, 0); + + diff = step>>3; + if(nibble&4) + diff += step; + if(nibble&2) + diff += step>>1; + if(nibble&1) + diff += step>>2; + + if (nibble&8) + predictor_left -= diff; + else + predictor_left += diff; + predictor_left = min(predictor_left, 32767); + predictor_left = max(predictor_left, -32768); + *out16++ = predictor_left; + out16_length--; + + step = step_table[step_index_right]; + nibble =nibbles_right[i]; + step_index_right += index_table[nibble]; + step_index_right = min(step_index_right, 88); + step_index_right = max(step_index_right, 0); + diff = step>>3; + if(nibble&4) + diff += step; + if(nibble&2) + diff += step>>1; + if(nibble&1) + diff += step>>2; + if (nibble&8) + predictor_right -= diff; + else + predictor_right += diff; + predictor_right = min(predictor_right, 32767); + predictor_right = max(predictor_right, -32768); + *out16++ = predictor_right; + out16_length--; + } + } + *inputBuffer = (uint8_t *)(*inputBuffer) + adpcm_stream_length; + *inputBufferBytes -= adpcm_stream_length; + *outputBufferBytes = adpcmformat->samples_per_block*4; + return AVI_SUCCESS; + } + + return AVI_FAILURE; +} + +void IMA_ADPCM_AVIDecoder::Close() +{ + delete this; +} + +#define CBCLASS IMA_ADPCM_AVIDecoder +START_DISPATCH; +CB(OUTPUT_FRAME_SIZE, OutputFrameSize) +CB(GET_OUTPUT_PROPERTIES, GetOutputProperties) +CB(DECODE_CHUNK, DecodeChunk) +VCB(CLOSE, Close) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/adpcm/avi_ima_adpcm_decoder.h b/Src/adpcm/avi_ima_adpcm_decoder.h new file mode 100644 index 00000000..849ab758 --- /dev/null +++ b/Src/adpcm/avi_ima_adpcm_decoder.h @@ -0,0 +1,24 @@ +#pragma once +#include "../Plugins/Input/in_avi/ifc_aviaudiodecoder.h" +#include "../nsavi/avi_header.h" + +struct ima_adpcm_format; + +class IMA_ADPCM_AVIDecoder : public ifc_aviaudiodecoder +{ +public: + IMA_ADPCM_AVIDecoder(const ima_adpcm_format *adpcmformat, const nsavi::STRH *stream_header); + +protected: + RECVS_DISPATCH; +private: + /* ifc_aviaudiodecoder implementation */ + int OutputFrameSize(size_t *frame_size); + int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat); + int DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes); + void Close(); + +private: + const ima_adpcm_format *adpcmformat; + const nsavi::STRH *stream_header; +};
\ No newline at end of file diff --git a/Src/adpcm/flv_adpcm_decoder.cpp b/Src/adpcm/flv_adpcm_decoder.cpp new file mode 100644 index 00000000..69e02948 --- /dev/null +++ b/Src/adpcm/flv_adpcm_decoder.cpp @@ -0,0 +1,141 @@ +#include "flv_adpcm_decoder.h" +#include "../f263/BitReader.h" + +int FLVDecoderCreator::CreateAudioDecoder(int stereo, int bits, int sample_rate, int format_type, ifc_flvaudiodecoder **decoder) +{ + if (format_type == FLV::AUDIO_FORMAT_ADPCM) + { + *decoder = new FLVADPCM(stereo?2:1); + return CREATEDECODER_SUCCESS; + } + return CREATEDECODER_NOT_MINE; +} + +int FLVDecoderCreator::HandlesAudio(int format_type) +{ + if (format_type == FLV::AUDIO_FORMAT_ADPCM) + { + return CREATEDECODER_SUCCESS; + } + return CREATEDECODER_NOT_MINE; +} + +#define CBCLASS FLVDecoderCreator +START_DISPATCH; +CB(CREATE_AUDIO_DECODER, CreateAudioDecoder) +CB(HANDLES_AUDIO, HandlesAudio) +END_DISPATCH; +#undef CBCLASS + +/* --- */ +FLVADPCM::FLVADPCM(unsigned int channels) : channels(channels) +{ + +} + +int FLVADPCM::GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *bits) +{ + *channels = this->channels; + *bits = 16; + return FLV_AUDIO_SUCCESS; +} + +// padded to zero where table size is less then 16 +static const int swf_index_tables[4][16] = { + /*2*/ { -1, 2 }, + /*3*/ { -1, -1, 2, 4 }, + /*4*/ { -1, -1, -1, -1, 2, 4, 6, 8 }, + /*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 } +}; + +static const int step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +int FLVADPCM::DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *_samples, size_t *samples_size_bytes, double *bitrate) +{ + int predictors[2] = {0, 0}; + int16_t step_indices[2] = {0, 0}; + + int16_t *samples = (int16_t *)_samples; + const size_t max_samples = *samples_size_bytes / sizeof(int16_t); + + BitReader bit_reader; + bit_reader.data = (uint8_t *)input_buffer; + bit_reader.numBits = (uint32_t)input_buffer_bytes * 8; + + uint32_t bits = bit_reader.getbits(2); + const int *table = swf_index_tables[bits]; + int k0 = 1 << bits++; + int signmask = 1 << bits++; + + size_t sample_num=0; + while (bit_reader.size() >= 22*channels) + { + for (size_t i = 0; i != channels; i++) + { + samples[sample_num++] = predictors[i] = ((int32_t)bit_reader.getbits(16) << 16) >> 16; + step_indices[i] = bit_reader.getbits(6); + } + + while (bit_reader.size() > bits*channels && sample_num < max_samples) + { + for (size_t i = 0; i != channels; i++) + { + int delta = bit_reader.getbits(bits); + int step = step_table[step_indices[i]]; + long vpdiff = 0; + int k = k0; + + do { + if (delta & k) + vpdiff += step; + step >>= 1; + k >>= 1; + } while(k); + vpdiff += step; + + if (delta & signmask) + predictors[i] -= vpdiff; + else + predictors[i] += vpdiff; + + step_indices[i] += table[delta & (~signmask)]; + + if (step_indices[i] < 0) step_indices[i] = 0; + if (step_indices[i] > 88) step_indices[i] = 88; + + if (predictors[i] > 32767) predictors[i] = 32767; + if (predictors[i] < -32768) predictors[i] = -32768; + + samples[sample_num++] = predictors[i]; + } + } + } + + *samples_size_bytes = sample_num * sizeof(int16_t); + + return FLV_AUDIO_SUCCESS; +} + + +void FLVADPCM::Close() +{ + delete this; +} + +#define CBCLASS FLVADPCM +START_DISPATCH; +CB(FLV_AUDIO_GETOUTPUTFORMAT, GetOutputFormat) +CB(FLV_AUDIO_DECODE, DecodeSample) +VCB(FLV_AUDIO_CLOSE, Close) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/adpcm/flv_adpcm_decoder.h b/Src/adpcm/flv_adpcm_decoder.h new file mode 100644 index 00000000..68e75384 --- /dev/null +++ b/Src/adpcm/flv_adpcm_decoder.h @@ -0,0 +1,35 @@ +#pragma once +#include "../Plugins/Input/in_flv/svc_flvdecoder.h" +#include "../Plugins/Input/in_flv/FLVAudioHeader.h" +#include "../Plugins/Input/in_flv/ifc_flvaudiodecoder.h" + +// {A1249BA5-97F3-4820-9E3B-EB883AE7D19A} +static const GUID flv_adpcm_guid = +{ 0xa1249ba5, 0x97f3, 0x4820, { 0x9e, 0x3b, 0xeb, 0x88, 0x3a, 0xe7, 0xd1, 0x9a } }; + + +class FLVDecoderCreator : public svc_flvdecoder +{ +public: + static const char *getServiceName() { return "ADPCM FLV Decoder"; } + static GUID getServiceGuid() { return flv_adpcm_guid; } + int CreateAudioDecoder(int stereo, int bits, int sample_rate, int format, ifc_flvaudiodecoder **decoder); + int HandlesAudio(int format_type); +protected: + RECVS_DISPATCH; +}; + +class FLVADPCM : public ifc_flvaudiodecoder +{ +public: + FLVADPCM(unsigned int channels); + int GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *bits); + int DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate); + void Close(); +private: +/* data */ + unsigned int channels; + +protected: + RECVS_DISPATCH; +}; diff --git a/Src/adpcm/main.cpp b/Src/adpcm/main.cpp new file mode 100644 index 00000000..962bbba8 --- /dev/null +++ b/Src/adpcm/main.cpp @@ -0,0 +1,78 @@ +#include "api.h" +#include <bfc/platform/export.h> +#include "../Agave/Component/ifc_wa5component.h" +#include "flv_adpcm_decoder.h" +#include "../nu/Singleton.h" +#include "avi_adpcm_decoder.h" + +api_service *WASABI_API_SVC=0; + +class ADPCMComponent : public ifc_wa5component +{ +public: + void RegisterServices(api_service *service); + int RegisterServicesSafeModeOk(); + void DeregisterServices(api_service *service); +protected: + RECVS_DISPATCH; +}; + +template <class api_T> +void ServiceBuild(api_T *&api_t, GUID factoryGUID_t) +{ + if (WASABI_API_SVC) + { + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t); + if (factory) + api_t = reinterpret_cast<api_T *>( factory->getInterface() ); + } +} + +template <class api_T> +void ServiceRelease(api_T *api_t, GUID factoryGUID_t) +{ + if (WASABI_API_SVC && api_t) + { + waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t); + if (factory) + factory->releaseInterface(api_t); + } + api_t = NULL; +} + +static FLVDecoderCreator flvCreator; +static SingletonServiceFactory<svc_flvdecoder, FLVDecoderCreator> flvFactory; +static SingletonServiceFactory<svc_avidecoder, AVIDecoder> avi_factory; +static AVIDecoder avi_decoder; + +void ADPCMComponent::RegisterServices(api_service *service) +{ + WASABI_API_SVC = service; + flvFactory.Register(WASABI_API_SVC, &flvCreator); + avi_factory.Register(WASABI_API_SVC, &avi_decoder); +} + +int ADPCMComponent::RegisterServicesSafeModeOk() +{ + return 1; +} + +void ADPCMComponent::DeregisterServices(api_service *service) +{ + flvFactory.Deregister(WASABI_API_SVC); + avi_factory.Deregister(WASABI_API_SVC); +} + +static ADPCMComponent component; +extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent() +{ + return &component; +} + +#define CBCLASS ADPCMComponent +START_DISPATCH; +VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices) +CB(15, RegisterServicesSafeModeOk) +VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices) +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/adpcm/resource.h b/Src/adpcm/resource.h new file mode 100644 index 00000000..2d45563a --- /dev/null +++ b/Src/adpcm/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by adpcm.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Src/adpcm/version.rc2 b/Src/adpcm/version.rc2 new file mode 100644 index 00000000..6dfcb509 --- /dev/null +++ b/Src/adpcm/version.rc2 @@ -0,0 +1,39 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "../Winamp/buildType.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION WINAMP_PRODUCTVER + PRODUCTVERSION WINAMP_PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Winamp SA" + VALUE "FileDescription", "Winamp 5.x System Component" + VALUE "FileVersion", STR_WINAMP_PRODUCTVER + VALUE "InternalName", "adpcm.w5s" + VALUE "LegalCopyright", "Copyright © 2005-2019 Winamp SA" + VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA" + VALUE "OriginalFilename", "adpcm.w5s" + VALUE "ProductName", "Winamp ADPCM AVI Decoder Service" + VALUE "ProductVersion", STR_WINAMP_PRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END |