Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
#include "../Winamp/out.h"
#include "resource.h"
extern Out_Module mod;
#include "../Agave/Language/api_language.h"
#include <api/service/waServiceFactory.h>
#define PLUGIN_VERSION L"2.18"
inline void * z_malloc(UINT x)
{
void * p=malloc(x);
if (p) memset(p,0,x);
return p;
}
#if 0
#include "ssrc/ssrc.h"
#endif

View File

@ -0,0 +1,184 @@
// 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
/////////////////////////////////////////////////////////////////////////////
// Polish resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
#ifdef _WIN32
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
#pragma code_page(1250)
#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 // Polish resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOGEX 0, 0, 388, 170
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Output File Location",IDC_OUTPUT_STATIC,4,4,185,126
LTEXT "Directory:",IDC_OUTPUT_DIRECTORY_STATIC,11,20,31,8
PUSHBUTTON "",IDC_OUTPUT_DIRECTORY,45,18,137,13
CONTROL "Output to directory containing source files",IDC_OUTPUT_SRCDIR,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,39,151,10
CONTROL "Display ""save as"" dialog for every file",IDC_FILENAME_SAVEAS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,52,135,10
LTEXT "Playlist index at the beginning:",IDC_FILENAME_INDEX_STATIC,11,70,99,8
COMBOBOX IDC_FILENAME_INDEX,11,82,172,92,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Output Filename Format:",IDC_FILENAME_FORMAT_STATIC,11,101,81,8
COMBOBOX IDC_FILENAME_FORMAT,11,111,172,94,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Output File Type",IDC_OUTMODE_STATIC,4,134,185,32
COMBOBOX IDC_OUTMODE,11,147,172,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Single-File Mode",IDC_STATIC,194,4,188,61
CONTROL "Enabled",IDC_SINGLEFILE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,17,41,10
LTEXT "File:",IDC_SINGLEFILE_FILE_STATIC,211,32,14,8
PUSHBUTTON "",IDC_SINGLEFILE_FILE_BUTTON,227,29,148,13
LTEXT "Format:",IDC_SINGLEFILE_FORMAT_STATIC,201,48,24,8
PUSHBUTTON "",IDC_SINGLEFILE_FORMAT_BUTTON,227,46,148,13
GROUPBOX "Conversion",IDC_CONVERT_STATIC,194,69,188,67
CONTROL "Convert to format:",IDC_CONVERT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,81,77,10
PUSHBUTTON "",IDC_CONVERT_BUTTON,200,93,175,21,BS_MULTILINE
LTEXT "Note: some output formats will produce an error message",IDC_CONVERT_NOTE,199,115,178,17,SS_CENTERIMAGE | WS_DISABLED
CONTROL "Override thread priority (hack)",IDC_THREAD_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,140,114,10
DEFPUSHBUTTON "OK",IDOK,280,153,50,13
PUSHBUTTON "Cancel",IDCANCEL,334,153,50,13
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOG1, DIALOG
BEGIN
LEFTMARGIN, 4
RIGHTMARGIN, 384
TOPMARGIN, 4
BOTTOMMARGIN, 166
END
END
#endif // APSTUDIO_INVOKED
#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
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_DISK_WRITER "Nullsoft Disk Writer v%s"
65535 "{1A710E67-5180-49ac-8102-105856ED0A2F}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_DISK_WRITER_OLD "Nullsoft Disk Writer"
IDS_AUTO_RECOMMENDED "Auto (recommended)"
IDS_FORCE_WAV_FILE "Force WAV file"
IDS_FORCE_RAW_DATA "Force raw data"
IDS_DISABLED "disabled"
IDS_1_DIGIT "1 digit"
IDS_2_DIGITS "2 digits"
IDS_3_DIGITS "3 digits"
IDS_4_DIGITS "4 digits"
IDS_SELECT_OUTPUT_DIRECTORY "Select output directory"
IDS_CHOOSE_FILE_NAME "%s - Choose File Name"
IDS_X_FILES_DOT_X "%s files|*%s|"
IDS_FILE_ALREADY_EXISTS_OVERWRITE
"File: ""%hs"" already exists. Overwrite?"
IDS_CANNOT_CREATE_OUTPUT_FILE "Cannot create output file"
IDS_CANNOT_OPEN_FILE "Cannot open file"
END
STRINGTABLE
BEGIN
IDS_NOT_A_PCM_WAV_FILE "Not a PCM WAV file"
IDS_ERROR_INITIALIZING_OUTPUT "Error initializing output."
IDS_ABOUT_TEXT "%s\n<> 2005-2023 Winamp SA\n<> 2001-2002 Peter Pawlowski\nBuild date: %hs"
IDS_SETTINGS_TITLE "%s Settings"
END
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,30 @@
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}") = "out_disk", "out_disk.vcxproj", "{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}"
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
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|Win32.ActiveCfg = Debug|Win32
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|Win32.Build.0 = Debug|Win32
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|x64.ActiveCfg = Debug|x64
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|x64.Build.0 = Debug|x64
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|Win32.ActiveCfg = Release|Win32
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|Win32.Build.0 = Release|Win32
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|x64.ActiveCfg = Release|x64
{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {14A951ED-3F6F-4E8C-97C7-53A443DB461F}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,301 @@
<?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>{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}</ProjectGuid>
<RootNamespace>out_disk</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>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<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;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0415</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_DEBUG;WIN32;_WINDOWS</PreprocessorDefinitions>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NDEBUG;WIN32;_WINDOWS</PreprocessorDefinitions>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_DEBUG;WIN64;_WINDOWS</PreprocessorDefinitions>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MinSpace</Optimization>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NDEBUG;WIN64;_WINDOWS</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="out_disk.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_disk.rc" />
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</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>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="out_disk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{3d730b77-a765-46b3-80a4-893d8ed28bca}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{4e1c8c55-ef16-46e4-94a9-fbd4c5a74f0c}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{8b744104-8938-49fc-ad58-e58f93746183}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_disk.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,80 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by acm.rc
//
#define IDS_NULLSOFT_DISK_WRITER_OLD 0
#define IDS_AUTO_RECOMMENDED 1
#define IDS_FORCE_WAV_FILE 2
#define IDC_RTFM 3
#define IDS_FORCE_RAW_DATA 3
#define IDS_DISABLED 4
#define IDS_1_DIGIT 5
#define IDS_2_DIGITS 6
#define IDS_3_DIGITS 7
#define IDS_4_DIGITS 8
#define IDS_CONFIGURATION_TITLE 9
#define IDS_SELECT_OUTPUT_DIRECTORY 10
#define IDS_CHOOSE_FILE_NAME 11
#define IDS_X_FILES_DOT_X 12
#define IDS_FILE_ALREADY_EXISTS_OVERWRITE 13
#define IDS_CANNOT_CREATE_OUTPUT_FILE 14
#define IDS_CANNOT_OPEN_FILE 15
#define IDS_NOT_A_PCM_WAV_FILE 16
#define IDS_ERROR_INITIALIZING_OUTPUT 17
#define IDS_ABOUT 18
#define IDS_STRING19 19
#define IDS_ABOUT_STRING 20
#define IDS_ABOUT_TEXT 20
#define IDS_SETTINGS_TITLE 21
#define IDD_DIALOG1 101
#define IDR_README 103
#define IDD_RTFM 109
#define IDC_DIR 1000
#define IDC_OUTPUT_DIRECTORY 1000
#define IDC_CONVERT 1001
#define IDC_CONVERT_CHECK 1001
#define IDC_FORMAT 1002
#define IDC_CONVERT_BUTTON 1002
#define IDC_FMT_NAME 1005
#define IDC_WAV1 1010
#define IDC_SINGLEFILE_CHECK 1010
#define IDC_WAV1E 1011
#define IDC_WAV1B 1012
#define IDC_SINGLEFILE_FILE_BUTTON 1012
#define IDC_WAV1F 1013
#define IDC_SINGLEFILE_FORMAT_BUTTON 1013
#define IDC_STATIC1 1014
#define IDC_STATIC2 1015
#define IDC_SINGLEFILE_FILE_STATIC 1015
#define IDC_STATIC3 1016
#define IDC_SINGLEFILE_FORMAT_STATIC 1016
#define IDC_STATIC4 1018
#define IDC_MODE 1019
#define IDC_OUTMODE 1019
#define IDC_THREAD_HACK 1020
#define IDC_FMTBLAH 1021
#define IDC_CONVERT_NOTE 1021
#define IDC_STARTHACK 1022
#define IDC_OUTPUT_SRCDIR 1023
#define IDC_CONVERT_STATIC 1024
#define IDC_OUTPUT_STATIC 1025
#define IDC_OUTMODE_STATIC 1026
#define IDC_FILENAME_INDEX_STATIC 1028
#define IDC_FILENAME_INDEX 1031
#define IDC_FILENAME_SAVEAS 1033
#define IDC_OUTPUT_DIRECTORY_STATIC 1034
#define IDC_FILENAME_FORMAT_STATIC 1035
#define IDC_FILENAME_FORMAT 1036
#define IDC_EDIT1 1066
#define IDS_NULLSOFT_DISK_WRITER 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1037
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,18,0,0
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 Output Plug-in"
VALUE "FileVersion", "2,18,0,0"
VALUE "InternalName", "Nullsoft Disk Writer"
VALUE "LegalCopyright", "Copyright <20> 2005-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "out_disk.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,50 @@
#include "res_wa2/resource.h"
#include "Config.h"
#include "../Winamp/out.h"
#include <api.h>
DS2config::DS2config()
{
sr = 44100;
bps = 16;
nch = 2;
wnd = 0;
create_primary = 0;
error[0] = 0;
mixing = MIXING_DEFAULT;
volmode = 0;
logfades = 0;
//logvol_min=100;
chan_mask = 0;
ms = DEFAULT_BUFFER;
preb = DEFAULT_PREBUFFER;
memset(&guid, 0, sizeof(guid));
sil_db = 0;
delayed_shutdown = 1;
prim_override = 0;
_p_bps = _p_nch = _p_sr = 0;
use_cpu_management = 0;
refresh = 10;
coop = 1;
#ifdef DS2_HAVE_PITCH
have_pitch = 0;
#endif
}
extern HINSTANCE cfg_orig_dll;
void DS2config::SetErrorCodeMsgA(const TCHAR *msg, DWORD code)
{
if (code)
{
TCHAR boo[512] = {0}, buf[512] = {0};
#ifdef UNICODE
wsprintf(boo, WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_CODE_08X,buf,512),msg,code);
#else
wsprintf(boo,WASABI_API_LNGSTRING_BUF(/*cfg_orig_dll,*/IDS_ERROR_CODE_08X,buf,512),msg,code);
#endif
SetError(boo);
}
else SetError(msg);
}
void DS2config::SetError(LPCTSTR n_error) {lstrcpyn(error, n_error, 255);}

View File

@ -0,0 +1,70 @@
#ifndef NULLSOFT_OUT_DS_CONFIG_H
#define NULLSOFT_OUT_DS_CONFIG_H
#include <windows.h>
#include "ds_main.h"
class DS2config //config struct to pass to DS2::create(); if create messes up, this struct also returns error message
{
public:
enum
{
DEFAULT_BUFFER = 1500,
DEFAULT_PREBUFFER = 500,
};
private:
size_t sr, bps, nch;
HWND wnd;
bool create_primary;
DWORD chan_mask;
UINT ms;
UINT preb;
bool use_cpu_management;
int volmode;
int logvol_min;
bool logfades;
GUID guid;
bool delayed_shutdown, prim_override;
UINT _p_bps, _p_nch, _p_sr;
float sil_db;
UINT mixing;
UINT refresh;
UINT coop;
#ifdef DS2_HAVE_PITCH
bool have_pitch;
#endif
TCHAR error[256];
void SetError(LPCTSTR n_error);
void SetErrorCodeMsgA(const TCHAR *msg, DWORD code);
public:
enum {
MIXING_DEFAULT = 0,
MIXING_FORCE_HARDWARE = 1,
MIXING_FORCE_SOFTWARE = 2
};
DS2config();
inline const TCHAR *GetError() { return error[0] ? error : 0;}
void _inline SetPCM(UINT _sr, UINT _bps, UINT _nch) {sr = _sr;bps = _bps;nch = _nch;}
void _inline SetWindow(HWND w) {wnd = w;}
void _inline SetCreatePrimary(bool b) {create_primary = b;}
void _inline SetChanMask(DWORD c) {chan_mask = c;}
void _inline SetDeviceGUID(const GUID& g) {guid = g;}
void _inline ResetDevice() {memset(&guid, 0, sizeof(guid));}
void _inline SetBuffer(UINT _ms = DEFAULT_BUFFER, UINT _preb = DEFAULT_PREBUFFER) {ms = _ms;preb = _preb;}
void _inline SetSilence(float s) {sil_db = s;} // s is in negative dB
void _inline SetDelayedShutdown(bool d) {delayed_shutdown = d;} //disable for AC97 shit, NOTE: this is global, not per-DS2 instance
void _inline SetImmediateShutdown(bool d) {delayed_shutdown = !d;}
void _inline SetPrimaryOverride(bool b) {prim_override = b;}
void _inline SetPrimaryOverrideFormat(UINT _sr, UINT _bps, UINT _nch) {_p_bps = _bps;_p_nch = _nch;_p_sr = _sr;}
void _inline SetVolMode(int mode, int logmin = 100, bool _logfades = 0) {volmode = mode;logvol_min = logmin;logfades = _logfades;}
void _inline SetMixing(UINT m) {mixing = m;}
void _inline SetCpuManagement(bool b) {use_cpu_management = b;}
void _inline SetRefresh(UINT n) {refresh = n;}
void _inline SetCoop(UINT n) {coop = n;}
#ifdef DS2_HAVE_PITCH
void _inline SetHavePitch(bool b) {have_pitch = b;}
#endif
friend class DS2;
};
#endif

View File

@ -0,0 +1,132 @@
#include "DevEnum.h"
#include "ds2.h"
#include "strsafe.h"
static int device_count=0;
static const GUID NULL_GUID;
BOOL WINAPI DsDevEnum::DSEnumCallback(LPGUID guid,LPCTSTR desc,LPCTSTR,DS_DEV *** var)
{
DS_DEV * dev=new DS_DEV;
size_t length=lstrlen(desc);
length+=4; // "##: "
length+=1; // null terminator
dev->name = (TCHAR *)calloc(sizeof(TCHAR),length);
StringCchPrintf(dev->name,length, TEXT("%02d: %s"), device_count++, desc);
dev->guid=guid ? *guid : NULL_GUID;
**var = dev;
*var=&dev->next;
return 1;
}
DsDevEnum::DsDevEnum()
{
DS2::InitDLL();
ds_devs=0;
DS_DEV ** dev_ptr=&ds_devs;
device_count = 1;
if (DS2::pDirectSoundEnumerate)
DS2::pDirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumCallback,&dev_ptr);
*dev_ptr=0;
pDev=ds_devs;
}
DsDevEnum::~DsDevEnum()
{
DS_DEV* dev=ds_devs;
while(dev)
{
DS_DEV * next=dev->next;
free(dev->name);
delete dev;
dev=next;
}
// ds_devs=0;
}
bool DsDevEnum::FindGuid(const GUID & guid)
{
pDev=ds_devs;
while(pDev)
{
if (pDev->guid== guid) return true;
pDev=pDev->next;
}
return false;
}
bool DsDevEnum::FindDefault()
{
return FindGuid(NULL_GUID);
}
bool DsDevEnum::FindName(const TCHAR *deviceToFind)
{
pDev=ds_devs;
if (!deviceToFind) return true;
while(pDev)
{
if (!lstrcmpi(pDev->name,deviceToFind)) return true;
pDev=pDev->next;
}
return false;
}
/*
const GUID DsDevEnum::GuidFromName(const char* name)
{
return FindName(name) ? GetGuid() : NULL_GUID;
}
const char * DsDevEnum::NameFromGuid(const GUID & g, char * def)
{
return FindGuid(g) ? GetName() : def;
}
*/
const GUID DsDevEnum::GetGuid()
{
return pDev ? pDev->guid : NULL_GUID;
}
static bool _getcaps(IDirectSound * pDS,LPDSCAPS pCaps,DWORD * speakercfg)
{
bool rv = true;
if (pCaps)
{
memset(pCaps,0,sizeof(*pCaps));
pCaps->dwSize=sizeof(*pCaps);
if (FAILED(pDS->GetCaps(pCaps))) rv = false;
}
if (speakercfg)
{
if (FAILED(pDS->GetSpeakerConfig(speakercfg))) rv = false;
}
return rv;
}
bool DsDevEnum::GetCapsFromGuid(const GUID *dev,LPDSCAPS pCaps,DWORD * speakercfg)
{
bool rv=false;
if (!dev) dev=&NULL_GUID;
if (DS2::TryGetDevCaps(dev,pCaps,speakercfg)) rv=true;
else
{
IDirectSound * l_pDS=0;
if (SUCCEEDED(DS2::myDirectSoundCreate(dev,&l_pDS)) && l_pDS)
{
rv=_getcaps(l_pDS,pCaps,speakercfg);
l_pDS->Release();
}
}
return rv;
}

View File

@ -0,0 +1,67 @@
#ifndef NULLSOFT_OUT_DS_DEVENUM_H
#define NULLSOFT_OUT_DS_DEVENUM_H
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include "res_wa2/resource.h"
#include "api.h"
#include "../Winamp/out.h"
class DsDevEnum
{
private:
struct DS_DEV
{
DS_DEV *next;
TCHAR *name;
GUID guid;
} ;
DS_DEV *pDev;
DS_DEV *ds_devs;
static BOOL WINAPI DSEnumCallback(LPGUID guid, LPCTSTR desc, LPCTSTR, DS_DEV *** var);
public:
const GUID GetGuid();
inline const TCHAR *GetName(const TCHAR *def = TEXT("device not found")) {
static wchar_t defStr[64];
return pDev ? pDev->name : WASABI_API_LNGSTRINGW_BUF(IDS_DEVICE_NOT_FOUND,defStr,64);
}
inline bool operator++(int) {if (pDev) pDev = pDev->next; return pDev ? true : false;}
inline operator bool() {return pDev ? true : false;}
bool FindGuid(const GUID & g);
bool FindDefault();
bool FindName(LPCTSTR n);
DsDevEnum();
~DsDevEnum();
inline void Reset() {pDev = ds_devs;}
static bool GetCapsFromGuid(const GUID *dev, LPDSCAPS pCaps, DWORD * speakercfg = 0);
inline bool GetCaps(LPDSCAPS pCaps, DWORD * speakercfg = 0) { return GetCapsFromGuid(&pDev->guid, pCaps, speakercfg);}
};
//helpers
class DsDevEnumGuid : public DsDevEnum
{
public:
DsDevEnumGuid(const GUID & g) {FindGuid(g);}
};
class DsDevEnumName : public DsDevEnum
{
public:
DsDevEnumName(LPCTSTR n) {FindName(n);}
};
class DsDevEnumDefault : public DsDevEnum
{
public:
DsDevEnumDefault() {FindDefault();}
};
#endif

View File

@ -0,0 +1,70 @@
#include "SoundBlock.h"
#include <memory.h>
#include <malloc.h>
SoundBlock::SoundBlock()
{
data = 0;
size = 0;
next = 0;
prev = 0;
start = 0;
used = 0;
}
SoundBlock::~SoundBlock()
{
if (data) free(data);
}
void SoundBlock::SetData(void *new_data, size_t new_size)
{
if (!data) data = malloc(new_size);
else if (new_size > size)
{
data = realloc(data, new_size);
if (!data) data = malloc(new_size);
else size = new_size;
}
if (data)
{
memcpy(data, new_data, new_size);
used = new_size;
}
else
{
used = 0;
}
start = 0;
}
void SoundBlock::Advance(size_t d)
{
used -= d;
start += d;
}
const void *SoundBlock::GetData()
{
return (char*)data + start;
}
size_t SoundBlock::GetDataSize()
{
return used;
}
size_t SoundBlock::Dump(void * out, size_t out_size)
{
const void * src = GetData();
if (out_size > used) out_size = used;
memcpy(out, src, out_size);
Advance(out_size);
return out_size;
}
void SoundBlock::Clear()
{
used = 0;
}

View File

@ -0,0 +1,21 @@
#ifndef NULLSOFT_OUT_DS_SOUNDBLOCK_H
#define NULLSOFT_OUT_DS_SOUNDBLOCK_H
class SoundBlock
{
public:
SoundBlock *next, *prev;
SoundBlock();
~SoundBlock();
void SetData(void *new_data, size_t new_size);
void Advance(size_t d);
const void *GetData();
size_t GetDataSize();
size_t Dump(void * out, size_t out_size);
void Clear();
private:
void *data;
size_t size, used, start;
};
#endif

View File

@ -0,0 +1,129 @@
#include "SoundBlockList.h"
#include <memory.h>
void SoundBlockList::AddBlock(void * data, size_t size)
{
SoundBlock * b = remove(b_free);
if (!b) b=new SoundBlock;
b->SetData(data,size);
mount2(b_first,b,b_last);
data_buffered+=size;
#ifdef USE_LOG
char boo[256] = {0};
wsprintf(boo,"AddBlock: %u, +%u",data_buffered,size);
log_write(boo);
#endif
}
size_t SoundBlockList::DumpBlocks(void * out1, size_t size1)
{
char * p1=(char*)out1;
size_t rv=0;
while(b_last && size1)
{
if (size1)
{
size_t d=b_last->Dump(p1,size1);
p1+=d;
size1-=d;
rv+=d;
}
if (b_last->GetDataSize()==0)
{
mount(b_free,removelast(b_first,b_last));
}
}
if (size1) memset(p1,silence_filler,size1);
data_buffered-=rv;
return rv;
}
void SoundBlockList::Reset()
{
if (b_first)
{
connect(b_last,b_free);
b_free=b_first;
}
b_first=0;
b_last=0;
data_buffered=0;
}
SoundBlockList::~SoundBlockList()
{
SoundBlock * p;
while(b_first)
{
p=b_first;
b_first=b_first->next;
delete p;
}
while(b_free)
{
p=b_free;
b_free=b_free->next;
delete p;
}
}
size_t SoundBlockList::DataSize()
{
return data_buffered;
}
SoundBlockList::SoundBlockList(int sil)
{
b_first = 0;b_last = 0;b_free = 0;data_buffered = 0;silence_filler = sil;
}
void SoundBlockList::advance(SoundBlock * &b)
{
b = b->next;
}
void SoundBlockList::goback(SoundBlock * &b)
{
b = b->prev;
}
void SoundBlockList::mount(SoundBlock * &first, SoundBlock * add)
{
connect(0, add);
connect(add, first);
first = add;
}
void SoundBlockList::mount2(SoundBlock * &first, SoundBlock * add, SoundBlock * &last)
{
mount(first, add);
if (!last) last = add;
}
SoundBlock *SoundBlockList::remove(SoundBlock * &list)
{
SoundBlock * b = list;
if (b)
{
advance(list);
connect(0, list);
connect(b, 0);
}
return b;
}
SoundBlock *SoundBlockList::removelast(SoundBlock * &first, SoundBlock * &last)
{
SoundBlock * b = last;
if (b)
{
goback(last);
connect(last, 0);
connect(0, b);
if (!last) first = 0;
}
return b;
}

View File

@ -0,0 +1,32 @@
#ifndef NULLSOFT_OUT_DS_SOUNDBLOCKLIST_H
#define NULLSOFT_OUT_DS_SOUNDBLOCKLIST_H
#include "SoundBlock.h"
class SoundBlockList
{
public:
SoundBlockList(int sil);
~SoundBlockList();
void AddBlock(void * data, size_t size);
size_t DumpBlocks(void * out1, size_t size1);
void Reset();
size_t DataSize();
private:
void connect(SoundBlock * b1, SoundBlock * b2) {if (b1) b1->next = b2;if (b2) b2->prev = b1;}
void advance(SoundBlock * &b);
void goback(SoundBlock * &b);
void mount(SoundBlock * &first, SoundBlock * add);
void mount2(SoundBlock * &first, SoundBlock * add, SoundBlock * &last);
SoundBlock * remove(SoundBlock * &list);
SoundBlock * removelast(SoundBlock * &first, SoundBlock * &last);
size_t data_buffered;
SoundBlock *b_first, *b_last, *b_free;
int silence_filler;
};
#endif

View File

@ -0,0 +1,196 @@
#include "VolCtrl.h"
#include <cmath>
static double lin2log_vol(double v)
{
return v>0 ? 20.0*log10(v) : -100.0;
}
static double log2lin_vol(double v)
{
return v<=-100.0 ? 0 : pow(10.0,v/20.0);
}
static double lin2log_pan(double p)
{
if (p==0) return 0;
else return lin2log_vol(1.0-fabs(p)) * (p>0 ? -1 : 1);
}
static double log2lin_pan(double p)
{
if (p==0) return 0;
else return (1.0-log2lin_vol(-fabs(p))) * (p>0 ? 1 :-1);
}
void DsVolCtrl::MapVol(double Vol,double Pan,double &OutNewVol,double &OutNewPan)
{
DestVolHack=Vol;
DestPanHack=Pan;
double NewVol = 0.0;
double NewPan = 0.0;
switch(VolMode)
{
case 0:
NewVol=lin2log_vol(Vol);
NewPan=lin2log_pan(Pan);
NewVol=Vol>0 ? 20*log10(Vol) : -100.0;//in negative db
if (Pan==0) NewPan=0;
else
{
double d= 1.0 - fabs(Pan);
d = d>0 ? 20*log10(d) : -1000.0;
if (Pan>0) d=-d;
NewPan=d;
}
break;
case 1:
{
double left,right;
NewVol=left=right=(double)LogVolMin * (Vol-1.0);
left+=lin2log_vol(sqrt(0.5-0.5*Pan));
right+=lin2log_vol(sqrt(0.5+0.5*Pan));
//NewVol=left>right ? left : right;
NewPan=right-left;
}
break;
case 2:
{
double left,right;
NewVol=left=right=100.0 * (pow(Vol,0.25)-1.0);
left+=lin2log_vol(sqrt(0.5-0.5*Pan));
right+=lin2log_vol(sqrt(0.5+0.5*Pan));
//NewVol=left>right ? left : right;
NewPan=right-left;
}
break;
}
if (NewVol<-100.0) NewVol=-100.0;
else if (NewVol>0) NewVol=0;
if (NewPan<-100.0) NewPan=-100.0;
else if (NewPan>100.0) NewPan=100.0;
OutNewVol=NewVol;
OutNewPan=NewPan;
}
DsVolCtrl::DsVolCtrl(int _VolMode,double _LogVolMin,bool _LogFades)
{
IsFading=0;
LogFades=_LogFades;
VolMode=_VolMode;
LogVolMin=_LogVolMin;
FadeSrcTime=FadeDstTime=-1;
CurTime=0;
CurVol=1;
LastVol=0;
CurPan=0;
LastPan=0;
DestPanHack = 0;
DestVolHack = 0;
FadeDstPan = 0;
FadeDstVol = 0;
FadeSrcPan = 0;
FadeSrcVol = 0;
}
void DsVolCtrl::SetFade(__int64 duration,double destvol,double destpan)
{
FadeSrcTime=CurTime;
FadeDstTime=CurTime+duration;
FadeSrcVol=CurVol;
FadeSrcPan=CurPan;
IsFading=1;
MapVol(destvol,destpan,FadeDstVol,FadeDstPan);
}
void DsVolCtrl::SetTime(__int64 time)
{
CurTime=time;
}
void DsVolCtrl::SetVolume(double vol)
{
if (Fading()) SetFade(FadeDstTime-CurTime,vol,DestPanHack);
else MapVol(vol,DestPanHack,CurVol,CurPan);
}
void DsVolCtrl::SetPan(double pan)
{
if (Fading()) SetFade(FadeDstTime-CurTime,DestVolHack,pan);
else MapVol(DestVolHack,pan,CurVol,CurPan);
}
void DsVolCtrl::Apply(IDirectSoundBuffer * pDSB)
{
if (Fading())
{
if (LogFades)
{
CurVol= FadeSrcVol + (FadeDstVol-FadeSrcVol) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime);
CurPan= FadeSrcPan + (FadeDstPan-FadeSrcPan) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime);
}
else
{
double SrcVol=log2lin_vol(FadeSrcVol);
double DstVol=log2lin_vol(FadeDstVol);
double SrcPan=log2lin_pan(FadeSrcPan);
double DstPan=log2lin_pan(FadeDstPan);
CurVol=lin2log_vol( SrcVol + (DstVol-SrcVol) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime) );
CurPan=lin2log_pan( SrcPan + (DstPan-SrcPan) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime) );
}
}
else if (FadeDstTime>=0)
{
CurVol=FadeDstVol;
CurPan=FadeDstPan;
FadeDstTime=-1;
IsFading=0;
}
if (CurVol!=LastVol)
{
LastVol=CurVol;
pDSB->SetVolume((long)(CurVol*100.0));
}
if (CurPan!=LastPan)
{
LastPan=CurPan;
pDSB->SetPan((long)(CurPan*100.0));
}
}
bool DsVolCtrl::Fading()
{
return IsFading && CurTime<FadeDstTime;
}
__int64 DsVolCtrl::RelFade(__int64 max,double destvol)
{
return (__int64)(fabs(destvol-DestVolHack)*(double)max);
}
double DsVolCtrl::Stat_GetVolLeft()
{
return CurPan<0 ? CurVol : CurVol - CurPan;
}
double DsVolCtrl::Stat_GetVolRight()
{
return CurPan>0 ? CurVol : CurVol + CurPan;
}

View File

@ -0,0 +1,44 @@
#ifndef NULLSOFT_OUT_DS_VOLCTRL_H
#define NULLSOFT_OUT_DS_VOLCTRL_H
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
class DsVolCtrl
{
public:
DsVolCtrl(int VolMode, double LogVolMin, bool logfades);
void SetFade(__int64 duration, double destvol, double destpan);
inline void SetFadeVol(__int64 duration, double destvol) {SetFade(duration, destvol, DestPanHack);}
inline void SetFadePan(__int64 duration, double destpan) {SetFade(duration, DestVolHack, destpan);}
__int64 RelFade(__int64 max, double destvol);
void SetTime(__int64 time);
void SetVolume(double vol);
void SetPan(double pan);
void Apply(IDirectSoundBuffer * pDSB);
// inline double GetCurVol() {return CurVol;}
inline double GetDestVol() { return DestVolHack;}
inline void Reset() {CurTime = 0;FadeDstTime = -1;}
double Stat_GetVolLeft();
double Stat_GetVolRight();
bool Fading();
private:
bool IsFading;
int VolMode;
double LogVolMin;
double FadeSrcVol, FadeDstVol, FadeSrcPan, FadeDstPan;
__int64 FadeSrcTime, FadeDstTime;
__int64 CurTime;
double CurVol, CurPan, LastVol, LastPan;
double DestVolHack, DestPanHack;
bool LogFades;
void MapVol(double Vol, double Pan, double &NewVol, double &NewPan);
};
#endif

View File

@ -0,0 +1,16 @@
#ifndef NULLSOFT_API_H
#define NULLSOFT_API_H
#include <api/service/api_service.h>
extern api_service *serviceManager;
#define WASABI_API_SVC serviceManager
#include <api/service/waServiceFactory.h>
#include "../Agave/Language/api_language.h"
#include <api/application/api_application.h>
extern api_application *applicationApi;
#define WASABI_API_APP applicationApi
#endif

View File

@ -0,0 +1,798 @@
#include "cnv_ds2.h"
#include "ds2.h"
#include "../studio/services/svc_textfeed.h"
#include "../studio/services/svc_action.h"
#include "../common/nsguid.h"
#include "../bfc/timerclient.h"
#include "../bfc/textfeed.h"
static WACNAME wac;
WAComponentClient *the = &wac;
// {F6FE7F49-B017-4bcc-842C-2FFA842FB033}
static const GUID guid =
{ 0xf6fe7f49, 0xb017, 0x4bcc, { 0x84, 0x2c, 0x2f, 0xfa, 0x84, 0x2f, 0xb0, 0x33 } };
GUID WACNAME::getGUID() {
return guid;
}
class _int_limited : public _int
{
private:
int min,max;
public:
// void setMinMax(int _min,int _max) {min=_min;max=_max;}
_int_limited(const char * name,int defval,int _min,int _max) : _int(name,defval) {min=_min;max=_max;}
friend class fooViewer;
int operator =(int newval) { return setValueAsInt(newval) ? newval : getValueAsInt(); }
};
class fooViewer : public DependentViewerT<_int_limited>
{
protected:
//took me some time to notice when bas borked it last time
//virtual int viewer_onItemDataChange(_int_limited *item, int hint1, int hint2)
virtual int viewer_onEvent(_int_limited *item, int event, int param2, void *ptr, int ptrlen)
{
int i = (int)(*item);
if (i>item->max) (*item)=item->max;
else if (i<item->min) (*item)=item->min;
return 1;
}
};
static fooViewer fooviewer;
#define DEVICE_DEFAULT "(default device)"
_string cfg_device("Device",DEVICE_DEFAULT);
_int_limited cfg_buf_ms("Buffer length (ms)",DS2config::DEFAULT_BUFFER,100,20000);
_int_limited cfg_prebuf("Prebuffer (ms)",DS2config::DEFAULT_PREBUFFER,0,20000);
_int_limited cfg_fade("Default fade time (ms)",333,0,20000);
_bool cfg_dofades("Use fades",0);
_bool cfg_oldpausefade("Old-style fade on pause",0);
_bool cfg_killsil("Kill silence",0);
_int_limited cfg_sil_db("Cutoff (in -dB)",40,15,200);
_bool cfg_hw_mix("Allow hardware mixing",1);
_bool cfg_delayed("Delayed DirectSound shutdown",1);
_bool cfg_wait("Full fadeout when exiting Winamp",1);
_bool cfg_fade_volume("Smooth volume changes",1);
_bool cfg_create_primary("Create primary buffer",0);
_bool cfg_override_primary("Override primary buffer format",0);
_int_limited cfg_primary_sr("Primary buffer override sample rate",44100,8000,192000);
_int_limited cfg_primary_nch("Primary buffer override number of channels",2,1,6);
_int_limited cfg_primary_bps("Primary buffer override bits per sample",16,8,32);
_int cfg_logvol_min("Logarithmic volume control scale",100);
_bool cfg_logfades("Logarithmic fades",0);
_bool cfg_pitch_enabled("Use pitch control",0);
_int cfg_pitch("Pitch",100);
_string cfg_volume("Volume control mode","linear");
_int_limited cfg_refresh("Status display refresh",50,1,5000);
class FADE_CTRL
{
private:
_bool enabled,custom;
_int_limited time;
public:
FADE_CTRL(const char * name,int enab)
: enabled(StringPrintf("Fade on %s enabled",name),enab), custom(StringPrintf("Fade on %s use custom time",name),0), time(StringPrintf("Fade on %s custom time",name),333,0,20000)
{
}
void registerme(CfgItemI * diz)
{
diz->registerAttribute(&enabled);
diz->registerAttribute(&custom);
diz->registerAttribute(&time);
fooviewer.viewer_addViewItem(&time);
}
operator int()
{
if (!enabled || !cfg_dofades) return 0;
else if (custom) return (UINT)time;
else return (UINT)cfg_fade;
}
};
static FADE_CTRL
fade_start("start",0),
fade_firststart("first start",0),
fade_endoftrack("end of track",0),
fade_pause("stop/pause",1),
fade_seek("seek",1);
class myCfgItemI : public CfgItemI
{
public:
myCfgItemI(const char * n,GUID _guid=INVALID_GUID) : CfgItemI(n,_guid) {setParentGuid(guid);}
};
class fadeShiz : public myCfgItemI
{
public:
void registerStuff()
{
registerAttribute(&cfg_dofades);
registerAttribute(&cfg_fade);
registerAttribute(&cfg_oldpausefade);
registerAttribute(&cfg_wait);
registerAttribute(&cfg_fade_volume);
fade_start.registerme(this);
fade_firststart.registerme(this);
fade_endoftrack.registerme(this);
fade_pause.registerme(this);
fade_seek.registerme(this);
}
fadeShiz(const char *n, GUID guid) : myCfgItemI(n,guid) {}
};
static fadeShiz fadeshiz("Fading",nsGUID::fromChar("{4D981DA3-F75D-431a-B617-46F3E45D2A1F}"));
static myCfgItemI cmpt("Compatibility",nsGUID::fromChar("{CBDF55F4-6EB6-45c1-B1DF-7A9F95C33758}"));
#define FEEDID_DEVICELIST "DirectSound:DEVICES"
#define FEEDID_VERSION "DirectSound:VERSION"
#define FEEDID_VOLCTRL "DirectSound:VOLCTRL"
#define FEEDID_STATUS "DirectSound:STATUS"
#if 0
class MyTextFeed : public TextFeed
{
public:
MyTextFeed() {
registerFeed(FEEDID_VOLCTRL, "linear;logarithmic;hybrid;disabled");
}
//CUT virtual int hasFeed(const char * name)
//CUT {
//CUT return !_stricmp(name,FEEDID_DEVICELIST) || !_stricmp(name,FEEDID_VERSION) || !_stricmp(name,FEEDID_VOLCTRL);
//CUT }
//CUT virtual void registerCallback(const char *feedid, TextFeedCallback *cb)
//CUT {
if (!_stricmp(feedid,FEEDID_DEVICELIST))
{
String devlist="";
DsDevEnum e;
while(e)
{
if (!devlist.isempty()) devlist += ";";
devlist+=e.GetName();
e++;
}
cb->textfeed_onReceiveText(devlist);
if (!strcmp(cfg_device,DEVICE_DEFAULT)) cfg_device=DsDevEnumDefault().GetName();
}
else if (!_stricmp(feedid,FEEDID_VERSION))
{
cb->textfeed_onReceiveText(DS2_ENGINE_VER);
}
else if (!_stricmp(feedid,FEEDID_VOLCTRL))
{
cb->textfeed_onReceiveText("linear;logarithmic;hybrid;disabled");
}
}
virtual void unregisterCallback(const char *feedid, TextFeedCallback *cb) {}
};
#endif
class StatusTextFeed : public TextFeed, private TimerClientDI
{
public:
StatusTextFeed() {
cc = 0;
registerFeed(FEEDID_STATUS);
}
int cc;
virtual void onRegClient() {
cc++;
if (cc == 1) timerclient_setTimer(666,cfg_refresh);
}
virtual void onDeregClient() {
cc--;
if (cc == 0) timerclient_killTimer(666);
}
private:
void UpdateStatus();
//CUT PtrList<TextFeedCallback> list;
virtual void timerclient_timerCallback(int id) {UpdateStatus();}
static char display[1024];
public:
static const char * getDisplay() {return display;}
static const char *getServiceName() { return "DirectSound Status Display"; }
//CUT virtual int hasFeed(const char * name) {return !_stricmp(name,FEEDID_STATUS);}
#if 0//CUT
virtual void registerCallback(const char *feedid, TextFeedCallback *cb)
{
if (!_stricmp(feedid,FEEDID_STATUS))
{
int n=list.getNumItems();
list.addItem(cb);
if (n==0)
{
timerclient_setTimer(666,cfg_refresh);
}
UpdateStatus();
}
}
virtual void unregisterCallback(const char *feedid, TextFeedCallback *cb)
{
list.removeItem(cb);
if (list.getNumItems()==0)
{
timerclient_killTimer(666);
}
}
#endif
};
char StatusTextFeed::display[1024];
#define ACTIONID_COPY "DirectSound:COPY"
class DsoundActions : public svc_actionI {
public:
DsoundActions() {
registerAction(ACTIONID_COPY, 0);
}
virtual ~DsoundActions() { }
virtual int onActionId(int id, const char *action, const char *param,int,int,void*,int,RootWnd*) {
switch (id) {
case 0:
if (!_stricmp(action,ACTIONID_COPY))
{
const char * display = StatusTextFeed::getDisplay();
if (OpenClipboard(0))
{
HANDLE hMem=GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,strlen(display)+1);
strcpy((char*)GlobalLock(hMem),display);
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
}
return 1;
}
return 0;
}
static const char *getServiceName() { return "DirectSound Actions Service"; }
};
static void FormatProgress(UINT pos,UINT max,UINT len,char * out)
{
UINT pos1=MulDiv(pos,len,max);
UINT n;
*(out++)='[';
for(n=0;n<len;n++)
{
*(out++)= (n==pos1) ? '#' : '=';
}
*(out++)=']';
*(out++)=0;
}
static void FormatTime(__int64 t,char * out)
{
int w,d,h,m,s,ms;
w=(int)(t/(1000*60*60*24*7));
d=(int)(t/(1000*60*60*24))%7;
h=(int)(t/(1000*60*60))%24;
m=(int)(t/(1000*60))%60;
s=(int)(t/(1000))%60;
ms=(int)(t)%1000;
if (w)
{
wsprintf(out,"%iw ",w);
while(*out) out++;
}
if (d)
{
wsprintf(out,"%id ",d);
while(*out) out++;
}
if (h)
{
wsprintf(out,"%i:",h);
while(*out) out++;
}
wsprintf(out,h ? "%02i:":"%i:",m);
while(*out) out++;
wsprintf(out,"%02i.%03i",s,ms);
}
void StatusTextFeed::UpdateStatus()
{
DS2_REALTIME_STAT stat;
char total[32];
__int64 time_total=DS2::GetTotalTime();
FormatTime(time_total,total);
if (DS2::GetRealtimeStatStatic(&stat))
{
char bigint1[32],bigint2[32];
_i64toa(stat.bytes_written,bigint1,10);
_i64toa(stat.bytes_played,bigint2,10);
char time1[32],time2[32];
FormatTime(stat.bytes_written/(stat.bps/8*stat.nch)*1000/stat.sr,time1);
__int64 time_played=stat.bytes_played/(stat.bps/8*stat.nch)*1000/stat.sr;
FormatTime(time_played,time2);
char prog1[56],prog2[56];
FormatProgress(stat.pos_play,stat.buf_size_bytes,48,prog1);
FormatProgress(stat.pos_write,stat.buf_size_bytes,48,prog2);
#define EOL "\x0d\x0a"
sprintf(display,
"Output format: %u Hz, %u bits per sample, %u channel%s" EOL
"Active buffer size: %u ms (%u bytes)" EOL
"Device: \"%s\"" EOL
"Mixing: %s, primary buffer: %s%s" EOL EOL
"Buffer playback cursor: %u bytes%s" EOL "%s" EOL
"Buffer write cursor: %u bytes" EOL "%s" EOL
EOL
"Data buffered:"EOL
"Total: %u ms (%u bytes)" EOL
"Async buffer: %u ms (%u bytes)"EOL
EOL
"Buffer locks done: %u" EOL
"Underruns: %u" EOL
"Time played: %s (%s bytes)" EOL
"Time written: %s (%s bytes)" EOL
"Total time played: %s" EOL
"Volume: %f dB / %f dB" EOL
,
stat.sr,stat.bps,stat.nch,stat.nch>1 ? "s":"",
stat.buf_size_ms,stat.buf_size_bytes,
DsDevEnumGuid(stat.current_device).GetName(),
(stat.dscaps_flags&DSBCAPS_LOCHARDWARE) ? "hardware" : (stat.dscaps_flags&DSBCAPS_LOCSOFTWARE) ? "software" : "unknown",
stat.have_primary_buffer ? "active" : "inactive",
(stat.dscaps_flags_primary&DSBCAPS_LOCHARDWARE) ? " (hardware)" : (stat.dscaps_flags_primary&DSBCAPS_LOCSOFTWARE) ? " (software)" : "",
stat.pos_play,stat.paused?" (paused)":"",prog1,stat.pos_write,prog2,
stat.latency_ms,stat.latency,
MulDiv(stat.bytes_async,1000,stat.sr*stat.nch*(stat.bps>>3)),stat.bytes_async,
stat.lock_count,stat.underruns,
time2,bigint2,
time1,bigint1,
total,
stat.vol_left,stat.vol_right
);
}
else
{
wsprintf(display,"Not active." EOL EOL "Total time played: %s",total);
#undef EOL
}
#if 0//CUT
foreach(list)
list.getfor()->textfeed_onReceiveText(display);
endfor;
#endif
sendFeed(FEEDID_STATUS, display);
}
//static waServiceTSingle<svc_textFeed, TextFeed> g_feed;
static waServiceTSingle<svc_textFeed, StatusTextFeed> g_statusfeed;
static waServiceTSingle<svc_action, DsoundActions> g_actions;
WACNAME::WACNAME() {
#ifdef FORTIFY
FortifySetName("cnv_pcmdsound.wac");
FortifyEnterScope();
#endif
addChildItem(&fadeshiz);
addChildItem(&cmpt);
registerService(new waServiceFactoryT<svc_mediaConverter, cnvDS2>);
registerService(&g_statusfeed);
registerService(&g_actions);
// registerService(&g_feed);
}
WACNAME::~WACNAME() {
#ifdef FORTIFY
FortifyLeaveScope();
#endif
}
void WACNAME::onCreate()
{
{
char temp[128];
api->getStringPrivate("Total time", temp,127, "0");
temp[127]=0;
DS2::SetTotalTime(_atoi64(temp));
}
// {EDAA0599-3E43-4eb5-A65D-C0A0484240E7}
static const GUID cfg_audio_guid =
{ 0xedaa0599, 0x3e43, 0x4eb5, { 0xa6, 0x5d, 0xc0, 0xa0, 0x48, 0x42, 0x40, 0xe7 } };
// {689D3A8E-3DDF-4d56-8BA4-8E068CF86F2D}
static const GUID cfg_fade_guid =
{ 0x689d3a8e, 0x3ddf, 0x4d56, { 0x8b, 0xa4, 0x8e, 0x6, 0x8c, 0xf8, 0x6f, 0x2d } };
// {27D1BBF0-6F65-4149-BE77-6FB2A2F59AA8}
static const GUID cfg_status_guid =
{ 0x27d1bbf0, 0x6f65, 0x4149, { 0xbe, 0x77, 0x6f, 0xb2, 0xa2, 0xf5, 0x9a, 0xa8 } };
// {9F60BF8B-1F3F-4c11-9BCD-AA15C9EAD1C4}
static const GUID cfg_misc_guid =
{ 0x9f60bf8b, 0x1f3f, 0x4c11, { 0x9b, 0xcd, 0xaa, 0x15, 0xc9, 0xea, 0xd1, 0xc4 } };
registerSkinFile("xml/directsound-prefs.xml");
registerSkinFile("xml/directsound-status.xml");
registerSkinFile("xml/directsound-fading.xml");
registerSkinFile("xml/directsound-misc.xml");
api->preferences_registerGroup("directsound", "DirectSound", guid, cfg_audio_guid);
api->preferences_registerGroup("directsound.fading", "Fading", cfg_fade_guid, guid);
api->preferences_registerGroup("directsound.status", "Status display", cfg_status_guid, guid);
api->preferences_registerGroup("directsound.misc", "Other settings", cfg_misc_guid, guid);
fadeshiz.registerStuff();
registerAttribute(&cfg_device);
registerAttribute(&cfg_buf_ms);
registerAttribute(&cfg_prebuf);
registerAttribute(&cfg_killsil);
registerAttribute(&cfg_sil_db);
registerAttribute(&cfg_pitch_enabled);
registerAttribute(&cfg_pitch);
registerAttribute(&cfg_volume);
registerAttribute(&cfg_logvol_min);
registerAttribute(&cfg_logfades);
registerAttribute(&cfg_refresh);
fooviewer.viewer_addViewItem(&cfg_buf_ms);
fooviewer.viewer_addViewItem(&cfg_prebuf);
fooviewer.viewer_addViewItem(&cfg_fade);
fooviewer.viewer_addViewItem(&cfg_sil_db);
fooviewer.viewer_addViewItem(&cfg_refresh);
cmpt.registerAttribute(&cfg_delayed);
cmpt.registerAttribute(&cfg_hw_mix);
cmpt.registerAttribute(&cfg_create_primary);
cmpt.registerAttribute(&cfg_override_primary);
cmpt.registerAttribute(&cfg_primary_sr);
cmpt.registerAttribute(&cfg_primary_nch);
cmpt.registerAttribute(&cfg_primary_bps);
}
void WACNAME::onDestroy() {
WAComponentClient::onDestroy();
if (cfg_wait)
{
while(DS2::InstanceCount()>0) Sleep(1);
}
DS2::Quit();
{
char temp[128];
_i64toa(DS2::GetTotalTime(),temp,10);
api->setStringPrivate("Total time",temp);
}
}
cnvDS2::cnvDS2() {
m_ds2=0;
ds2_paused=0;
fadenow=DS2::InstanceCount()>0 ? fade_start : fade_firststart;
pitch_set=1;
sr=nch=bps=chan=0;
}
cnvDS2::~cnvDS2() {
if (m_ds2)
{
m_ds2->FadeAndForget(fade_pause);
}
}
int cnvDS2::getInfos(MediaInfo *infos)
{
return 0;
}
unsigned long tea_key[4]={0xef542687,0x4d5c68ac,0x54274ef9,0x844dfc52};
unsigned long tea_sum=0xC6EF3720;
unsigned long tea_delta=0x9E3779B9;
static int strings_decrypt=0;
static char crypted_bps[]={'b'^0x25,'p'^0x25,'s'^0x25,0};
static char crypted_srate[]={(char)('s'+0x41),(char)('r'+0x41),(char)('a'+0x41),(char)('t'+0x41),(char)('e'+0x41),0};
static char crypted_nch[]={'n'-0x18,'c'-0x18,'h'-0x18,0};
int cnvDS2::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)
{
/* if (ds2_paused && m_ds2)
{
m_ds2->Pause(0);
ds2_paused=0;
}*/
// strings "encrypted" for WMA pcm "secure" stuff
int old_canwrite=m_ds2 ? m_ds2->CanWrite() : 0;
char pcmstr[5]={(char)('p'+23),'c'^12,'M'-64,0};
pcmstr[4]=0;
pcmstr[1]^=12;
pcmstr[0]-=23;
pcmstr[2]+=64;
Chunk *chunk1=chunk_list->getChunk(pcmstr/*"PCM"*/);
pcmstr[3]=(char)('x'+85);
pcmstr[3]-=85;
Chunk *chunk=chunk_list->getChunk(pcmstr/*"PCMx"*/);
if(chunk) {
// decrypt using TEA (128-bit)
int i=chunk->getSize()/8;
unsigned long *v=(unsigned long *)chunk->getData();
const unsigned long *k=tea_key;
while(i) {
register unsigned long y=v[0],z=v[1],sum=tea_sum, delta=tea_delta,n=32;
/* sum = delta<<5, in general sum = delta * n */
while(n-->0) {
z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];
sum -= delta;
y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3];
}
v[0]=y; v[1]=z; v+=2; i--;
}
} else {
chunk=chunk1;
if(!chunk) return 0;
}
Chunk * c=chunk;//chunk_list->getChunk("PCM");
if (!c) return 0;
int size=c->getSize();
if (size<=0 || !c->getData()) {
if(infos->getData("audio_need_canwrite")) {
int cw;
if(m_ds2)
{
cw=old_canwrite;//can be negative
if (cw<0) cw=0;
}
else cw=65536;
infos->setDataInt("audio_canwrite",cw,MediaInfo::INFO_NOSENDCB);
}
return 1;
}
UINT _sr=c->getInfo("srate"),_nch=c->getInfo("nch"),_bps=c->getInfo("bps");
DWORD _chan=0;
{
Chunk *cc=chunk_list->getChunk("SPEAKER_SETUP");
if (cc)
{
if (cc->getSize()==4)
{
chan = *(DWORD*)cc->getData();
}
}
}
UINT _fade=fadenow;
fadenow=0;
DS2 * wait=0;
UINT waitfade=0;
if (_sr!=sr || _nch!=nch || _bps!=bps || _chan!=chan || _fade)
{
if (m_ds2)
{
wait=m_ds2;
if (_fade)
{
waitfade=_fade;
}
else
{
waitfade=cfg_dofades ? 50 : 0;//let's pretend that we're gapless hehe
wait=m_ds2;
}
m_ds2=0;
if (*killswitch) return 0;
}
sr=_sr;
bps=_bps;
nch=_nch;
chan=_chan;
}
if (!m_ds2)
{
DS2config cfg;
if (_stricmp(cfg_device,DEVICE_DEFAULT)) cfg.SetDeviceGUID(DsDevEnumName(cfg_device).GetGuid());
cfg.SetPCM(sr,bps,nch);
cfg.SetCreatePrimary(cfg_create_primary);
cfg.SetPrimaryOverride(cfg_override_primary);
cfg.SetPrimaryOverrideFormat(cfg_primary_sr,cfg_primary_bps,cfg_primary_nch);
if (chan) cfg.SetChanMask(chan);
cfg.SetWindow(api->main_getRootWnd()->gethWnd());
cfg.SetMixing(cfg_hw_mix ? 0 : 2);
use_pitch=cfg_pitch_enabled;
if (!_stricmp(cfg_volume,"disabled")) use_vol=0;
else
{
use_vol=1;
int volmode;
if (!_stricmp(cfg_volume,"logarithmic")) volmode=1;
else if (!_stricmp(cfg_volume,"hybrid")) volmode=2;
else volmode=0;
cfg.SetVolMode(volmode,cfg_logvol_min,cfg_logfades);
}
{//automagic idiotproof buffer size config (no more "too short fading" lamers)
UINT bs=(UINT)cfg_buf_ms;
UINT bs1=bs;
UINT v=fade_endoftrack;
if (bs<v) bs=v;
v=fade_pause;
if (bs<v) bs=v;
v=fade_seek;
if (bs<v) bs=v;
UINT pb=cfg_prebuf;
cfg.SetBuffer(bs,pb>bs ? bs : pb);
}
cfg.SetSilence(cfg_killsil ? (float)cfg_sil_db : 0);
cfg.SetImmediateShutdown(cfg_delayed);
cfg.SetHavePitch(use_pitch);
m_ds2=DS2::Create(&cfg);
if (!m_ds2)
{
const char *moo=cfg.GetError();
if (moo) infos->error(moo);
return 0;
}
if (use_vol) m_ds2->SetPan_Int(api->core_getPan(m_coretoken));
if (_fade)
{
m_ds2->SetVolume_Int(0);
m_ds2->Fade_Int(_fade,use_vol ? api->core_getVolume(m_coretoken) : 255);
}
else
m_ds2->SetVolume_Int(use_vol ? api->core_getVolume(m_coretoken) : 255);
if (wait) m_ds2->WaitFor(wait,waitfade);
pitch_set=1.0;
}
int ret=0;
if (m_ds2->ForceWriteData(c->getData(),(UINT)size))
{
ret=1;
if (old_canwrite<0) while(!*killswitch && m_ds2->CanWrite()<0) Sleep(1);
}
if(infos->getData("audio_need_canwrite")) infos->setDataInt("audio_canwrite",m_ds2->CanWrite(),MediaInfo::INFO_NOSENDCB);
if (use_pitch)
{
double foo=(double)cfg_pitch / 100.0;
if (foo<0.25) foo=0.25;
else if (foo>4.0) foo=4.0;
if (pitch_set!=foo)
{
m_ds2->SetPitch(foo);
pitch_set=foo;
}
}
return ret;
}
int cnvDS2::corecb_onSeeked(int newpos)
{
if (m_ds2)
{
fadenow=fade_seek;
m_ds2->FadeAndForget(fadenow);
m_ds2=0;
}
return 0;
}
int cnvDS2::getLatency(void)
{
return m_ds2 ? m_ds2->GetLatency() : 0;
}
int cnvDS2::corecb_onAbortCurrentSong()
{
if (m_ds2)
{
m_ds2->FadeAndForget(fade_pause);
m_ds2=0;
fadenow=fade_start;
}
return 0;
}
int cnvDS2::corecb_onVolumeChange(int v)
{
if (m_ds2 && use_vol)
{
if (cfg_fade_volume) m_ds2->FadeX_Int(100,v);
else m_ds2->SetVolume_Int(v);
}
return 0;
}
int cnvDS2::corecb_onPanChange(int v)
{
if (m_ds2 && use_vol)
{
m_ds2->SetPan_Int(v);
}
return 0;
}
int cnvDS2::corecb_onPaused()
{
if (m_ds2)
{
UINT v=fade_pause;
if (!v)
{
m_ds2->Pause(1);
}
else if (cfg_oldpausefade)
{
m_ds2->FadeAndForget(v);
m_ds2=0;
fadenow=v;
}
else
{
m_ds2->FadePause(v);
}
ds2_paused=1;
}
return 0;
}
int cnvDS2::corecb_onUnpaused()
{
if (ds2_paused && m_ds2) {m_ds2->Pause(0);}
ds2_paused=0;
return 0;
}
int cnvDS2::corecb_onEndOfDecode()
{
if (m_ds2)
{
m_ds2->KillEndGap();
m_ds2->ForcePlay();
fadenow=fade_endoftrack;
}
return 0;
}
int cnvDS2::sortPlacement(const char *oc)
{
// if (!_stricmp(oc,"crossfader")) {return -1;}
return 0;
}

View File

@ -0,0 +1,85 @@
#ifndef _CNV_DS2_H
#define _CNV_DS2_H
#include "../studio/wac.h"
#include "../common/rootcomp.h"
#include "../attribs/cfgitemi.h"
#include "../attribs/attrint.h"
#include "../attribs/attrbool.h"
#include "../attribs/attrfloat.h"
#include "../attribs/attrstr.h"
#include "../studio/services/svc_mediaconverter.h"
#include "../studio/services/servicei.h"
#include "../studio/corecb.h"
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include "ds2.h"
#define WACNAME WACcnv_ds2
class WACNAME : public WAComponentClient {
public:
WACNAME();
virtual ~WACNAME();
virtual const char *getName() { return "DirectSound Output"; };
virtual GUID getGUID();
virtual void onCreate();
virtual void onDestroy();
virtual int getDisplayComponent() { return FALSE; };
virtual CfgItem *getCfgInterface(int n) { return this; }
};
class cnvDS2 : public svc_mediaConverterI {
public:
cnvDS2();
virtual ~cnvDS2();
// service
static const char *getServiceName() { return "DirectSound Output"; }
virtual int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype) {
if(chunktype && !STRICMP(chunktype,"pcm")) return 1;
return 0;
}
virtual const char *getConverterTo() { return "OUTPUT:DirectSound"; }
virtual int getInfos(MediaInfo *infos);
virtual int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch);
virtual int getLatency(void);
virtual int isSelectableOutput(void) { return 1; }
// callbacks
virtual int corecb_onSeeked(int newpos);
virtual int sortPlacement(const char *oc);
virtual int corecb_onVolumeChange(int v);
virtual int corecb_onPanChange(int v);
virtual int corecb_onAbortCurrentSong();
virtual int corecb_onPaused();
virtual int corecb_onUnpaused();
virtual int corecb_onEndOfDecode();
private:
DS2 * m_ds2;
UINT sr,nch,bps,chan;
bool ds2_paused;
UINT fadenow;
bool use_vol;
bool use_pitch;
double pitch_set;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,237 @@
#ifndef _DS2_H
#define _DS2_H
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include "ds_main.h"
#include "Config.h"
#include "SoundBlockList.h"
#include "DevEnum.h"
#include "VolCtrl.h"
class CriticalSection : public CRITICAL_SECTION
{
public:
inline void Enter() {EnterCriticalSection(this);}
inline void Leave() {LeaveCriticalSection(this);}
CriticalSection() {InitializeCriticalSection(this);}
~CriticalSection() {DeleteCriticalSection(this);}
//BOOL TryEnter() {return TryEnterCriticalSection(this);}
};
typedef struct
{
UINT sr,bps,nch;
UINT buf_size_bytes,buf_size_ms;
UINT pos_play,pos_write,latency,latency_ms;
UINT lock_count;
UINT underruns;
size_t bytes_async;
__int64 bytes_written,bytes_played;
double vol_left,vol_right;
GUID current_device;
bool have_primary_buffer;
bool paused;
DWORD dscaps_flags;
DWORD dscaps_flags_primary;
} DS2_REALTIME_STAT;
class DS2
{
private:
DS2(DS2config * cfg);
SoundBlockList BlockList;
UINT LockCount;
UINT Underruns;
bool DoLock();
public:
~DS2();
int WriteData(void * data,UINT size,bool *killswitch);//returns 1 on success and 0 on failure
int WriteDataNow(void * data,UINT size);//sleep-less version, writes CanWrite() of bytes immediately, returns amount of data written
int ForceWriteData(void * data,UINT size);//sleep-less force-write all the data w/o sleep/canwrite (async buffer has no size limit), use with caution
/*
how to use writedata shit
a) just WriteData(), will sleep until its done
b) WriteDataNow() until we're done (writes as much data as possible at the moment, without sleep)
c) ForceWriteData() (evil!), then sleep while CanWrite()<0
*/
void StartNewStream();
UINT GetLatency();
void _inline Release() {delete this;}//obsolete
void Pause(int new_state);
void SetVolume(double);
inline void SetVolume_Int(int i) {SetVolume((double)i/255.0);}
void SetPan(double);
inline void SetPan_Int(int i) {SetPan((double)i/128.0);}
void Flush();//causes problems with some um.. drivers
int CanWrite();//can be negative !!!!!!! (eg. after ForceWriteData)
inline UINT BufferStatusPercent() {return MulDiv(data_buffered+(UINT)BlockList.DataSize(),buf_size,100);}
void ForcePlay();
void KillEndGap();
#ifdef DS2_HAVE_FADES
void FadePause(UINT time);
void FadeAndForget(UINT time);
void Fade(UINT time,double destvol);
inline void Fade_Int(UINT time,int destvol) {Fade(time,(double)destvol/255.0);}
void FadeX(UINT time,double destvol);//actual fade time depends on volume difference
inline void FadeX_Int(UINT time,int destvol) {FadeX(time,(double)destvol/255.0);}
#endif
void WaitFor(DS2 * prev,UINT fadeout=0);
//gapless mode stuff
void SetCloseOnStop(bool b);
bool IsClosed();
private:
#ifdef _DEBUG
DWORD serial;
UINT sync_n;
#endif
int Open(DS2config * cfg);
DS2 * next;
DS2 * wait;
UINT prebuf;
DWORD flags;
enum
{
FLAG_UPDATED=1,
FLAG_WAITED=1<<1,
FLAG_NEED_PLAY_NOW=1<<2,
FLAG_DIE_ON_STOP=1<<3,
FLAG_CLOSE_ON_STOP=1<<4,
FLAG_PAUSED=1<<5,
FLAG_PLAYING=1<<6,
// FLAG_UNDERRUNNING=1<<7,
FLAG_USE_CPU_MNGMNT=1<<8,
FLAG_FADEPAUSE=1<<9,
FLAG_FADEPAUSING=1<<10,
FLAG_STARTSIL=1<<11,
FLAG_SWMIXED=1<<12,
};
IDirectSoundBuffer * pDSB;
IDirectSound * myDS;
UINT fmt_nch,fmt_bps,fmt_sr,fmt_mul;
UINT buf_size,clear_size;
__int64 last_nonsil,pos_delta,pos_delta2;
inline __int64 GetCurPos() {return data_written-data_buffered;}
__int64 GetSafeWrite();
__int64 data_written;
UINT data_buffered;
UINT silence_buffered;
UINT bytes2ms(UINT bytes);
UINT ms2bytes(UINT ms);
#ifdef DS2_HAVE_FADES
DsVolCtrl VolCtrl;
double fadepause_orgvol;
UINT fadepause_time;
UINT waitfade;
#else
class DsVolCtrl
{
private:
double CurVol,CurPan;
public:
DsVolCtrl() {CurVol=1;CurPan=0;}
inline void SetTime(__int64) {}
inline void SetFade(__int64,double) {}
inline void SetFadeVol(__int64,double,double) {}
inline void SetFadePan(__int64,double,double) {}
inline void SetVolume(double v) {CurVol=v;}
inline void SetPan(double p) {CurPan=p;}
// inline __int64 RelFade(__int64 max,double destvol) {return 0;}
void Apply(IDirectSoundBuffer * pDSB);
inline bool Fading() {return 0;}
// inline double GetCurVol() {return CurVol;}
// inline double GetDestVol() {return CurVol;}
inline void Reset() {}
};
DsVolCtrl VolCtrl;
#endif
void SetVolumeI(double);
void SetPanI(int _pan);
void _setvol();
void _setpan();
void update_pos();
void ds_stop();
void ds_kill();
bool Update();
void reset_vars();
void do_reset_vars();
int silence_delta;
void test_silence(char * buf,int len,int * first,int* last);
static DWORD WINAPI ThreadFunc(void*);
UINT _inline _align() {return (fmt_bps>>3)*fmt_nch;}
UINT _inline _align_var(UINT var) {return var-(var%_align());}
static void SYNC_IN();
static void SYNC_OUT();
typedef HRESULT (WINAPI *tDirectSoundCreate)( const GUID * lpGuid, LPDIRECTSOUND * ppDS, IUnknown FAR * pUnkOuter );
static tDirectSoundCreate pDirectSoundCreate;
static IDirectSound * pDS;
public:
static void Init();//init is OBSOLETE
static void Quit(bool wait=0);//must be called on exit, NOT from DllMain, its ok to call it if init never happened
static DS2 * Create(DS2config * cfg);
static bool InitDLL();//used internally
static HRESULT myDirectSoundCreate(const GUID * g,IDirectSound ** out);
static void SetTotalTime(__int64);
static __int64 GetTotalTime();
static UINT InstanceCount();
void GetRealtimeStat(DS2_REALTIME_STAT * stat);
static bool GetRealtimeStatStatic(DS2_REALTIME_STAT * stat);
__int64 GetOutputTime();
#ifdef DS2_HAVE_DEVICES
static bool TryGetDevCaps(const GUID *g,LPDSCAPS pCaps,DWORD * speakercfg=0);//for current device
typedef HRESULT (WINAPI *tDirectSoundEnumerate)(LPDSENUMCALLBACK lpDSEnumCallback,LPVOID lpContext);
static tDirectSoundEnumerate pDirectSoundEnumerate;
static GUID GetCurDev();
#endif
#ifdef DS2_HAVE_PITCH
void SetPitch(double p);
#endif
};
#endif

View File

@ -0,0 +1,32 @@
#include "ds2.h"
#include "strsafe.h"
static const GUID NULL_GUID;
static bool _getcaps(IDirectSound * pDS,LPDSCAPS pCaps,DWORD * speakercfg)
{
bool rv=1;
if (pCaps)
{
memset(pCaps,0,sizeof(*pCaps));
pCaps->dwSize=sizeof(*pCaps);
if (FAILED(pDS->GetCaps(pCaps))) rv=0;
}
if (speakercfg)
{
if (FAILED(pDS->GetSpeakerConfig(speakercfg))) rv=0;
}
return rv;
}
bool DS2::TryGetDevCaps(const GUID *g,LPDSCAPS pCaps,DWORD * speakercfg)
{
bool rv=0;
SYNC_IN();
if (!g) g=&NULL_GUID;
if (pDS && GetCurDev()==*g)
{
rv=_getcaps(pDS,pCaps,speakercfg);
}
SYNC_OUT();
return rv;
}

View File

@ -0,0 +1,4 @@
#include "ds2.h"
UINT DS2::bytes2ms(UINT bytes) {return MulDiv(bytes,1000,fmt_mul);}
UINT DS2::ms2bytes(UINT ms) {return _align_var(MulDiv(ms,fmt_mul,1000));}

View File

@ -0,0 +1 @@
#include "ds2.h"

View File

@ -0,0 +1,16 @@
#ifndef DS_IPC_H
#define DS_IPC_H
#define DS_IPC_CLASSNAME "DSound_IPC"
#define WM_DS_IPC WM_USER
#define DS_IPC_CB_CFGREFRESH 0 // trap this to detect when apply/ok was pressed in config
#define DS_IPC_CB_ONSHUTDOWN 1 // trap this to detect when out_ds is going away (ie: another output plugin was selected, or winamp is exiting)
#define DS_IPC_SET_CROSSFADE 100 // send this with wParam = 0/1 to change fade on end setting
#define DS_IPC_GET_CROSSFADE 101 // returns fade on end on/off
#define DS_IPC_SET_CROSSFADE_TIME 102 // send this with wParam = fade on end time in ms
#define DS_IPC_GET_CROSSFADE_TIME 103 // returns fade on end time in ms
#endif

View File

@ -0,0 +1,14 @@
#ifndef NULLSOFT_OUT_DS_MAIN_H
#define NULLSOFT_OUT_DS_MAIN_H
#define DS2_ENGINE_VER L"2.82"
#ifndef DS2_NO_DEVICES
#define DS2_HAVE_DEVICES
#endif
#ifndef DS2_NO_FADES
#define DS2_HAVE_FADES
#endif
#endif

View File

@ -0,0 +1,29 @@
#define STRICT
#include <windows.h>
#include "../Winamp/out.h"
#include "ds2.h"
#include "../pfc/pfc.h"
#define NAME "DirectSound output "DS2_ENGINE_VER
extern cfg_int cfg_def_fade;
class FadeCfg
{
public:
const wchar_t * name;
cfg_int time;
cfg_int on,usedef;
inline UINT get_time() {return on ? (usedef ? cfg_def_fade : time) : 0;}
inline operator int() {return get_time();}
FadeCfg(const wchar_t* name,const wchar_t* vname,int vtime,bool von,bool vusedef);
};
#ifdef HAVE_SSRC
typedef struct
{
UINT src_freq,src_bps,dst_freq,dst_bps;
} RESAMPLING_STATUS;
#endif
extern FadeCfg cfg_fade_start,cfg_fade_firststart,cfg_fade_stop,cfg_fade_pause,cfg_fade_seek;

View File

@ -0,0 +1,30 @@
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}") = "out_ds", "out_ds.vcxproj", "{224E9634-ED82-4762-B1C4-33FC20CD0DD3}"
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
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Debug|Win32.ActiveCfg = Debug|Win32
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Debug|Win32.Build.0 = Debug|Win32
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Release|Win32.ActiveCfg = Release|Win32
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Release|Win32.Build.0 = Release|Win32
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Debug|x64.ActiveCfg = Debug|x64
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Debug|x64.Build.0 = Debug|x64
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Release|x64.ActiveCfg = Release|x64
{224E9634-ED82-4762-B1C4-33FC20CD0DD3}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9F1A238-FD11-4202-9F24-119183616B81}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,304 @@
<?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>{224E9634-ED82-4762-B1C4-33FC20CD0DD3}</ProjectGuid>
<RootNamespace>out_ds</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" 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>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|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>
<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>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<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;_MBCS;_USRDLL;OUT_DS_EXPORTS;_CRT_SECURE_NO_WARNINGS;PFC_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_MBCS;_USRDLL;OUT_DS_EXPORTS;_CRT_SECURE_NO_WARNINGS;PFC_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;OUT_DS_EXPORTS;_CRT_SECURE_NO_WARNINGS;PFC_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_MBCS;_USRDLL;OUT_DS_EXPORTS;_CRT_SECURE_NO_WARNINGS;PFC_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\pfc\cfg_var.cpp" />
<ClCompile Include="..\..\..\pfc\string.cpp" />
<ClCompile Include="..\..\..\pfc\string_unicode.cpp" />
<ClCompile Include="Config.cpp" />
<ClCompile Include="DevEnum.cpp" />
<ClCompile Include="ds2.cpp" />
<ClCompile Include="ds2_devenum.cpp" />
<ClCompile Include="ds2_misc.cpp" />
<ClCompile Include="SoundBlock.cpp" />
<ClCompile Include="SoundBlockList.cpp" />
<ClCompile Include="VolCtrl.cpp" />
<ClCompile Include="wa2.cpp" />
<ClCompile Include="wa2_config.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Config.h" />
<ClInclude Include="DevEnum.h" />
<ClInclude Include="ds2.h" />
<ClInclude Include="ds_main.h" />
<ClInclude Include="out_ds.h" />
<ClInclude Include="res_wa2\resource.h" />
<ClInclude Include="SoundBlock.h" />
<ClInclude Include="SoundBlockList.h" />
<ClInclude Include="VolCtrl.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res_wa2\out_ds2.rc">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">res_wa2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">res_wa2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">res_wa2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">res_wa2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</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>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="Config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DevEnum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ds2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ds2_devenum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ds2_misc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundBlock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundBlockList.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="VolCtrl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wa2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wa2_config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\pfc\cfg_var.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\pfc\string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\pfc\string_unicode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="VolCtrl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundBlockList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SoundBlock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="res_wa2\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="out_ds.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ds2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ds_main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DevEnum.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Config.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{a9054c6f-fcbf-4f1b-98c3-47fb0b552dc6}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{76daf3b6-09e4-496b-8254-80d6afffba08}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{da81f6bf-ee4d-440e-bcd5-457809fb2c36}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="res_wa2\out_ds2.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,101 @@
#include "out_ds.h"
#include <dinput.h>
#include <math.h>
static IDirectInput8 * pDI;
static IDirectInputDevice8 * pDev;
#ifndef HAVE_JOY
#error nein!
#endif
static BOOL CALLBACK eCallback(LPCDIDEVICEINSTANCE dev,void * foop)
{
*(GUID*)foop=dev->guidInstance;
return DIENUM_STOP;
}
static bool captured;
#define joy_id JOYSTICKID1
#define POLL 5
void wa2_hack_setpitch(double d);
static double joy_read()
{
DIJOYSTATE2 stat;
if (SUCCEEDED(pDev->GetDeviceState(sizeof(stat),&stat)))
{
return pow(2,(double)stat.lX/(double)0x8000)/2.0;
}
else return 1;
}
void wa2_hack_joy_update()
{
wa2_hack_setpitch(joy_read());
}
static HANDLE hThread;
static bool die;
static DWORD _stdcall joy_thread(void*)
{
while(!die)
{
wa2_hack_setpitch(joy_read());
Sleep(10);
}
return 0;
}
void wa2_hack_joy_init()
{
if (!hThread)
{
DirectInput8Create(mod.hDllInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDI,0);
if (pDI)
{
GUID foop;
pDI->EnumDevices(DI8DEVCLASS_GAMECTRL,eCallback,&foop,DIEDFL_ATTACHEDONLY);
pDI->CreateDevice(foop,&pDev,0);
if (pDev)
{
pDev->SetDataFormat(&c_dfDIJoystick2);
DIPROPDWORD dw;
dw.dwData=1000;
dw.diph.dwSize=sizeof(DIPROPDWORD);
dw.diph.dwHeaderSize=sizeof(DIPROPHEADER);
dw.diph.dwObj=0;
dw.diph.dwHow=DIPH_DEVICE;
pDev->SetProperty(DIPROP_DEADZONE,&dw.diph);
pDev->SetCooperativeLevel(mod.hMainWindow,DISCL_BACKGROUND);
pDev->Acquire();
die=0;
DWORD id;
hThread=CreateThread(0,0,joy_thread,0,0,&id);
SetThreadPriority(hThread,THREAD_PRIORITY_TIME_CRITICAL);
}
else {pDI->Release();pDI=0;}
}
}
}
void wa2_hack_joy_deinit()
{
if (hThread)
{
die=1;
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
hThread=0;
if (pDev) {pDev->Unacquire();pDev->Release();pDev=0;}
if (pDI) {pDI->Release();pDI=0;}
}
}

View File

@ -0,0 +1,304 @@
// 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
#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
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DS_CONFIG DIALOGEX 0, 0, 247, 221
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "DirectSound output settings"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Note: Most settings take full effect after restarting playback",IDC_STATIC,2,194,194,8,WS_DISABLED
PUSHBUTTON "Apply",IDABORT,212,192,32,12
LTEXT "",IDC_VER,1,211,40,8
PUSHBUTTON "Reset all",IDC_RESET,136,206,36,12
DEFPUSHBUTTON "OK",IDOK,176,206,32,12
PUSHBUTTON "Cancel",IDCANCEL,212,206,32,12
CONTROL "Tab1",IDC_TAB,"SysTabControl32",WS_TABSTOP,0,0,244,188
END
IDD_CONFIG_TAB1 DIALOGEX 0, 0, 242, 170
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
COMBOBOX IDC_DEVICE,4,5,196,66,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Refresh",IDC_REFRESH,202,5,36,13
CONTROL "Allow hardware acceleration\n(may cause problems with broken drivers)",IDC_HW_MIX,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,8,24,228,17
CONTROL "Create primary buffer\n(for old soundcards, fixes sound quality problems)",IDC_CREATE_PRIMARY,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,8,45,228,18
GROUPBOX "Device Info",-1,4,68,234,56
LTEXT "",IDC_DEVICE_INFO,8,78,226,42
LTEXT "Note that info above is what your soundcard driver reports; it might not match actual hardware specs in certain cases.",IDC_STATIC_BLEH,4,128,234,17
LTEXT "",IDC_PDS_FAQ,4,148,234,18
END
IDD_CONFIG_TAB2 DIALOGEX 0, 0, 238, 170
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Buffer length:",-1,8,4,46,8
PUSHBUTTON "Reset to default values",IDC_BUF_RESET,147,0,90,12
CONTROL "Slider1",IDC_BUFFER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,4,14,232,12
CTEXT "",IDC_BUF_DISP,8,26,224,8
LTEXT "Prebuffer on start / seek / underrun:",-1,8,39,119,8
CONTROL "Slider1",IDC_PREBUFFER_1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,4,49,232,12
CTEXT "",IDC_PREBUF_DISP_1,8,61,224,8
LTEXT "Buffer-ahead on track change:",-1,8,74,100,8
CONTROL "Slider1",IDC_PREBUFFER_2,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,4,84,232,12
CTEXT "",IDC_PREBUF_DISP_2,8,96,224,8
LTEXT "Longer buffer gives better skipping (underrun) protection at cost of higher CPU usage when starting (Winamp decodes as fast as possible until buffer is full). Big buffer also causes EQ/DSP setting changes to lag.",-1,2,104,236,25
LTEXT "Prebuffer determines how much data to eat before starting to output; recommended values are 500-1000ms, higher values can cause problems.",-1,2,131,236,16
CONTROL "Enable CPU usage control (experimental, keeps CPU usage fluid when starting/seeking, even with very big buffers)",IDC_PREBUF_AUTO,
"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,2,151,220,16
END
IDD_CONFIG_TAB3 DIALOGEX 0, 0, 242, 170
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Default fade length:",-1,10,9,66,8
EDITTEXT IDC_FADE,78,7,38,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_FADE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,104,7,11,14
LTEXT "ms",-1,118,9,10,8
CONTROL "Old-style fade on pause",IDC_PAUSEFADE2,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,8,24,116,10
CONTROL "Don't abort fadeout when Winamp is shutting down",IDC_WAITx,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,36,177,10
LISTBOX IDC_LIST,8,50,224,45,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "",IDC_FADE_GROUP,8,95,224,39,WS_DISABLED
CONTROL "Enabled",IDC_FADE_ENABLED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,18,106,42,10
CONTROL "Use custom fade time:",IDC_USE_CUSTOM_FADE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,18,118,84,10
EDITTEXT IDC_CUSTOM_FADE,106,117,34,12,ES_AUTOHSCROLL | WS_DISABLED
CONTROL "Spin1",IDC_CUSTOM_FADE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | WS_DISABLED,128,118,11,14
LTEXT "ms",IDC_STATIC_MS,142,119,10,8,WS_DISABLED
LTEXT "Note: all fadeouts are limited to buffer length. You may need to set longer buffer in order to get what you want.",-1,4,137,232,16
LTEXT "FAQ: fades on end of song and on start will disable gapless playback.",-1,4,157,226,8
END
IDD_CONFIG_TAB4 DIALOGEX 0, 0, 242, 170
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
GROUPBOX "Silence remover",-1,4,4,234,76
CONTROL "Remove silence at the beginning / end of track",IDC_KILLSIL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,17,165,10
LTEXT "Cutoff:",-1,16,30,24,8
CONTROL "Slider1",IDC_DB,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,10,38,220,12
CTEXT "",IDC_DB_DISPLAY,14,50,212,8
LTEXT "Note: amount of removed silence at the end of track\nis limited to buffer length (see buffering tab)",-1,12,58,168,16
GROUPBOX "Volume control",-1,4,88,234,76
CONTROL "Enable volume control",IDC_VOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,106,86,10
CONTROL "Smooth volume changes",IDC_FADEVOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,108,106,93,10
LTEXT "Volume control:",-1,12,127,50,8
COMBOBOX IDC_VOLMODE,62,124,138,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Map 0% to -",IDC_LOGVOL_STATIC,24,144,38,8
EDITTEXT IDC_LOGVOL_MIN,62,142,28,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_LOGVOL_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,88,150,11,14
LTEXT "dB",IDC_LOGVOL_STATIC2,92,144,10,8
CONTROL "Logarithmic fades",IDC_LOGFADES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,128,144,71,10
END
IDD_CONFIG_TAB6 DIALOGEX 0, 0, 242, 174
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
PUSHBUTTON "Copy",IDC_STAT_COPY,4,157,28,14
LTEXT "Refresh every",-1,147,159,47,8
EDITTEXT IDC_REFRESH,196,157,32,12,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Spin1",IDC_REFRESH_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,212,159,11,14
LTEXT "ms",-1,230,159,10,8
END
IDD_CONFIG_STATUS DIALOGEX 0, 0, 290, 170
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
EXSTYLE WS_EX_CONTROLPARENT
FONT 7, "MS Shell Dlg", 0, 0, 0x1
BEGIN
LTEXT "",IDC_STATUS,0,0,289,170,0,WS_EX_CLIENTEDGE
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_DS_CONFIG, DIALOG
BEGIN
RIGHTMARGIN, 244
BOTTOMMARGIN, 219
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_DS_OUTPUT "Nullsoft DirectSound Output v%s"
65535 "{A812F3D3-633B-4af6-8749-3BA75290BAC0}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_DS_OUTPUT_OLD "Nullsoft DirectSound Output"
IDS_ERROR_CODE_08X "%s\nError code: %08X"
IDS_DEVICE_NOT_FOUND "device not found"
IDS_BAD_DS_DRIVER "Bad DirectSound driver. Please install proper drivers or select another device in configuration."
IDS_DEVICE_NOT_FOUND_SELECT_ANOTHER
"Device not found. Please select another device in configuration."
IDS_ERROR_SETTING_DS_COOPERATIVE_LEVEL
"Error setting DirectSound cooperative level; please shutdown other programs using your soundcard."
IDS_ERROR_CREATING_DS_BUFFER "Error creating DirectSound buffer."
IDS_ERROR "%s Error"
IDS_FAQ_PREFERRED_DEVICE
"FAQ: ""%s"" refers to preferred sound device selected in Windows control panel."
IDS_NO_DS_DEVICES_PRESENT
"No DirectSound devices present. Please install soundcard drivers first."
IDS_DS_DOES_NOT_APPEAR_TO_BE_INSTALLED
"DirectSound does not appear to be installed on this system. Please install DirectX first."
IDS_NO_DEVICES_FOUND "no devices found"
IDS_ERROR_GETTING_DEVICE_INFO
"error getting device info\n(device in use?)"
IDS_UNSUPPORTED "unsupported"
END
STRINGTABLE
BEGIN
IDS_SUPPORTED_X_FREE_STREAMS "supported, %u free streams (%u max)"
IDS_X_BYTES "%u bytes (%u bytes free)"
IDS_NA "N/A"
IDS_FADE_ON_X_SETTINGS "Fade on%s settings"
IDS_LINEAR "Linear"
IDS_LOGARITHMIC "Logarithmic"
IDS_HYBRID "Hybrid"
IDS_NOT_ACTIVE_TOTAL_PLAYED "Not active.\n\nTotal time played: %s"
IDS_RESET_ALL_SETTINGS_TO_DEFAULTS
"This will reset all settings to their default values. Continue?"
IDS_WARNING "Warning"
IDS_SOME_FADE_TIMES_ARE_BIGGER_THAN_BUFFER
"Some fade times are bigger than buffer length; in order to get what you want, please increase buffer size to %u ms.\nWould you like your settings to be automatically corrected?"
IDS_5_1 "5.1"
IDS_HEADPHONES "Headphones"
IDS_MONO "Mono"
IDS_QUAD "Quad"
IDS_STEREO "Stereo"
END
STRINGTABLE
BEGIN
IDS_SURROUND "Surround"
IDS_UNKNOWN "Unknown"
IDS_DS_INFO "Certified: %s, emulated: %s\nSupports sample rates from %u Hz to %u Hz%s\nHardware memory: %s\nHardware mixing: %s\nSpeaker setup: %s"
IDS_YES "Yes"
IDS_NO "No"
IDS_CONTINUOUS " (continuous)"
IDS_STATUS_TEXT "Output format: %u Hz, %u bits per sample, %u %s\nActive buffer size: %u ms (%u bytes)\nDevice: ""%s""\nMixing: %s, primary buffer: %s%s\n\nBuffer playback cursor: %u bytes%s\n%s\nBuffer write cursor: %u bytes\n%s\n\nData buffered:\nTotal: %u ms (%u bytes)\nAsync buffer: %u ms (%u bytes)\n\nBuffer locks done: %u\nUnderruns: %u\nTime played: %s (%s bytes)\nTime written: %s (%s bytes)\nTotal time played: %s\nVolume: %f dB / %f dB"
IDS_HARDWARE "hardware"
IDS_SOFTWARE "software"
IDS_ACTIVE "active"
IDS_INACTIVE "inactive"
IDS_HARDWARE_BRACKETED " (hardware)"
IDS_SOFTWARE_BRACKETED " (software)"
IDS_PAUSED_BRACKETED " (paused)"
IDS_EMPTY " "
END
STRINGTABLE
BEGIN
IDS_DEVICE "Device"
IDS_BUFFERING "Buffering"
IDS_FADING "Fading"
IDS_OTHER "Other"
IDS_STATUS "Status"
IDS_PREFS_TITLE "%s Settings"
IDS_DISABLED " (disabled)"
IDS_ON "on"
IDS_FADE_START " start"
IDS_FADE_FIRSTSTART " first start"
IDS_FADE_STOP " end of song"
IDS_FADE_PAUSE " pause/stop"
IDS_FADE_SEEK " seek"
IDS_CHANNEL "channel"
IDS_CHANNELS "channels"
IDS_DS_U_MS "%u ms"
END
STRINGTABLE
BEGIN
IDS_DS_DB "dB"
IDS_ABOUT_TEXT "%s\n<> 2005-2023 Winamp SA\n<> 2001-2002 Peter Pawlowski\t\nBuild date: %hs"
IDS_7_1 "7.1"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,146 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by out_ds2.rc
//
#define IDS_NULLSOFT_DS_OUTPUT_OLD 0
#define IDS_ERROR_CODE_08X 1
#define IDS_DEVICE_NOT_FOUND 2
#define IDC_APPLY 3
#define IDS_BAD_DS_DRIVER 3
#define IDS_DEVICE_NOT_FOUND_SELECT_ANOTHER 4
#define IDS_ERROR_SETTING_DS_COOPERATIVE_LEVEL 5
#define IDS_ERROR_CREATING_DS_BUFFER 6
#define IDS_ABOUT 7
#define IDS_ERROR 9
#define IDS_FAQ_PREFERRED_DEVICE 10
#define IDS_NO_DS_DEVICES_PRESENT 11
#define IDS_DS_DOES_NOT_APPEAR_TO_BE_INSTALLED 12
#define IDS_NO_DEVICES_FOUND 13
#define IDS_ERROR_GETTING_DEVICE_INFO 14
#define IDS_UNSUPPORTED 15
#define IDS_SUPPORTED_X_FREE_STREAMS 16
#define IDS_X_BYTES 17
#define IDS_NA 18
#define IDS_FADE_ON_X_SETTINGS 19
#define IDS_LINEAR 20
#define IDS_LOGARITHMIC 21
#define IDS_HYBRID 22
#define IDS_NOT_ACTIVE_TOTAL_PLAYED 23
#define IDS_RESET_ALL_SETTINGS_TO_DEFAULTS 24
#define IDS_WARNING 25
#define IDS_SOME_FADE_TIMES_ARE_BIGGER_THAN_BUFFER 26
#define IDS_5_1 27
#define IDS_HEADPHONES 28
#define IDS_MONO 29
#define IDS_QUAD 30
#define IDS_STEREO 31
#define IDS_SURROUND 32
#define IDS_UNKNOWN 33
#define IDS_DS_INFO 34
#define IDS_YES 35
#define IDS_NO 36
#define IDS_CONTINUOUS 37
#define IDS_STATUS_TEXT 38
#define IDS_HARDWARE 40
#define IDS_SOFTWARE 41
#define IDS_ACTIVE 42
#define IDS_INACTIVE 43
#define IDS_HARDWARE_BRACKETED 44
#define IDS_SOFTWARE_BRACKETED 45
#define IDS_PAUSED_BRACKETED 46
#define IDS_EMPTY 47
#define IDS_DEVICE 48
#define IDS_BUFFERING 49
#define IDS_FADING 50
#define IDS_OTHER 51
#define IDS_STATUS 52
#define IDS_STRING53 53
#define IDS_PREFS_TITLE 53
#define IDS_DISABLED 54
#define IDS_ON 55
#define IDS_FADE_START 56
#define IDS_FADE_FIRSTSTART 57
#define IDS_FADE_STOP 58
#define IDS_FADE_PAUSE 59
#define IDS_STRING60 60
#define IDS_FADE_SEEK 60
#define IDS_CHANNEL 61
#define IDS_STRING62 62
#define IDS_CHANNELS 62
#define IDS_DS_U_MS 63
#define IDS_STRING64 64
#define IDS_DS_DB 64
#define IDS_ABOUT_STRING 65
#define IDS_ABOUT_TEXT 65
#define IDS_STRING209 66
#define IDS_7_1 66
#define IDD_DS_CONFIG 200
#define IDD_CONFIG_TAB1 201
#define IDD_CONFIG_TAB2 202
#define IDD_CONFIG_TAB3 203
#define IDD_CONFIG_TAB4 204
#define IDD_CONFIG_TAB6 205
#define IDD_CONFIG_STATUS 206
#define IDC_RESET 1000
#define IDC_GLOBAL_FADES 1001
#define IDC_CUSTOM_FADE_SPIN 1002
#define IDC_LOGVOL_SPIN 1002
#define IDC_REFRESH_SPIN 1002
#define IDC_FADE 1003
#define IDC_FADE_SPIN 1004
#define IDC_CREATE_PRIMARY 1005
#define IDC_PAUSEFADE2 1011
#define IDC_DEVICE 1013
#define IDC_WAITx 1014
#define IDC_PREBUFFER_2 1015
#define IDC_KILLSIL 1017
#define IDC_DB 1018
#define IDC_DB_DISPLAY 1019
#define IDC_PREBUFFER_1 1020
#define IDC_LIST 1021
#define IDC_PREBUF_DISP_1 1022
#define IDC_CUSTOM_FADE 1022
#define IDC_PREBUF_DISP_2 1023
#define IDC_USE_CUSTOM_FADE 1023
#define IDC_BUFFER 1024
#define IDC_BUF_DISP 1025
#define IDC_STATIC_MS 1025
#define IDC_BUF_RESET 1031
#define IDC_VOLUME 1032
#define IDC_TAB1 1033
#define IDC_TAB 1033
#define IDC_DEVICE_INFO 1035
#define IDC_PDS_FAQ 1036
#define IDC_FADE_GROUP 1037
#define IDC_FADE_ENABLED 1038
#define IDC_STATUS 1039
#define IDC_REFRESH 1041
#define IDC_STAT_COPY 1043
#define IDC_LOGVOL_MIN 1045
#define IDC_LOGVOL_STATIC 1046
#define IDC_LOGVOL_STATIC2 1047
#define IDC_FADEVOL 1059
#define IDC_PREBUF_AUTO 1061
#define IDC_STATIC_BLEH 1062
#define IDC_VOLMODE 1066
#define IDC_LOGFADES 1067
#define IDC_TEXT1 1078
#define IDC_HW_MIX 1078
#define IDC_VER 1078
#define IDC_CONFIG_TAB1 10000
#define IDC_CONFIG_TAB2 10001
#define IDC_CONFIG_TAB3 10002
#define IDC_CONFIG_TAB4 10003
#define IDC_CONFIG_TAB6 10005
#define IDS_NULLSOFT_DS_OUTPUT 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 210
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1002
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,82,0,0
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 Output Plug-in"
VALUE "FileVersion", "2,82,0,0"
VALUE "InternalName", "Nullsoft DirectSound Output"
VALUE "LegalCopyright", "Copyright <20> 2005-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "out_ds.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
#pragma once
#include "../Agave/Config/api_config.h"
extern api_config *AGAVE_API_CONFIG;
#include <api/application/api_application.h>
#define WASABI_API_APP applicationApi
#include "../Agave/Language/api_language.h"

View File

@ -0,0 +1,393 @@
#include "../Winamp/OUT.H"
#include "api.h"
#include "resource.h"
#include <Mmdeviceapi.h>
#include <Audioclient.h>
#include <Audiosessiontypes.h>
#include "../winamp/wa_ipc.h"
#include <api/service/waServiceFactory.h>
#include <strsafe.h>
#define WASAPI_PLUGIN_VERSION L"0.3"
constexpr auto VolumeLevelMultiplier = 255;
static wchar_t plugin_name[256];
// wasabi based services for localisation support
api_service *WASABI_API_SVC = 0;
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
static const UINT32 REFTIMES_PER_SEC = 10000000;
static const UINT32 REFTIMES_PER_MILLISEC = 10000;
// TODO(benski) is there some library that has this
static const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
static const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
static const IID IID_IAudioClient = __uuidof(IAudioClient);
static const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
static const IID IID_IAudioClock = __uuidof(IAudioClock);
static bool InitializedCOM;
extern Out_Module plugin;
static IAudioClient *client=0;
static IAudioRenderClient *render_client=0;
static IAudioClock *clock=0;
static ISimpleAudioVolume *audio_volume = 0;
static IChannelAudioVolume *channel_volume = 0;
static UINT32 bufferFrameCount;
static WORD bytes_per_frame;
static UINT64 frequency=0;
static UINT32 sample_rate;
static double start_time_ms = 0;
static bool paused=false;
static float start_volume = 1.0;
static float start_pan = 0;
WAVEFORMATEXTENSIBLE WaveFormatForParameters(int samplerate, int numchannels, int bitspersamp);
static void SetVolume(int volume);
static void SetPan(int pan);
static CRITICAL_SECTION ThreadSync;
static void Config(HWND hwndParent)
{
}
static int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
{
MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMSW),0};
msgbx.lpszText = message;
msgbx.lpszCaption = title;
msgbx.lpszIcon = MAKEINTRESOURCEW(102);
msgbx.hInstance = GetModuleHandle(0);
msgbx.dwStyle = MB_USERICON;
msgbx.hwndOwner = parent;
return MessageBoxIndirectW(&msgbx);
}
static void About(HWND hwndParent)
{
wchar_t message[1024], text[1024] =L"";
WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_WASAPI_OLD,text,1024);
StringCchPrintfW(message, 1024, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
plugin.description, TEXT(__DATE__));
DoAboutMessageBox(hwndParent,text,message);
}
static void Init()
{
/*
HRESULT hr;
hr=CoInitializeEx(0, COINIT_MULTITHREADED);
if (SUCCEEDED(hr)) {
InitializedCOM = true;
} else {
InitializedCOM = false;
}
*/
// loader so that we can get the localisation service api for use
WASABI_API_SVC = (api_service*)SendMessage(plugin.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(plugin.hDllInstance,OutWasapiLangGUID);
StringCbPrintfW(plugin_name,sizeof(plugin_name),WASABI_API_LNGSTRINGW(IDS_NULLSOFT_WASAPI), WASAPI_PLUGIN_VERSION);
plugin.description = (char *)plugin_name;
}
static void Quit()
{
/*
if (InitializedCOM) {
CoUninitialize();
}*/
}
static int Open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
{
CoInitialize(0);
IMMDeviceEnumerator *enumerator=0;
IMMDevice *device=0;
sample_rate = samplerate;
HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator);
hr = enumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &device);
hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&client);
if (FAILED(hr)) {
wchar_t temp[1234];
wsprintf(temp, L"device->Activate: %x", hr);
::MessageBox(NULL, temp, L"error", MB_OK);
return -1;
}
WAVEFORMATEXTENSIBLE wave_format = WaveFormatForParameters(samplerate, numchannels, bitspersamp);
bytes_per_frame = wave_format.Format.nBlockAlign;
hr = client->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0x80000000,
1 * REFTIMES_PER_SEC,
0,
(WAVEFORMATEX *)&wave_format,
NULL);
if (FAILED(hr)) {
wchar_t temp[1234];
wsprintf(temp, L"client->Initialize: %x", hr);
::MessageBox(NULL, temp, L"error", MB_OK);
return -1;
}
// Get the actual size of the allocated buffer.
hr = client->GetBufferSize(&bufferFrameCount);
if (FAILED(hr)) {
wchar_t temp[1234];
wsprintf(temp, L"client->GetBufferSize: %x", hr);
::MessageBox(NULL, temp, L"error", MB_OK);
return -1;
}
hr = client->GetService(
IID_IAudioRenderClient,
(void**)&render_client);
if (FAILED(hr)) {
wchar_t temp[1234];
wsprintf(temp, L"client->GetService(IID_IAudioRenderClient): %x", hr);
::MessageBox(NULL, temp, L"error", MB_OK);
return -1;
}
hr = client->GetService(
IID_IAudioClock,
(void**)&clock);
if (FAILED(hr)) {
wchar_t temp[1234];
wsprintf(temp, L"client->GetService(IID_IAudioClock): %x", hr);
::MessageBox(NULL, temp, L"error", MB_OK);
return -1;
}
hr = clock->GetFrequency(&frequency);
hr = client->GetService(__uuidof(ISimpleAudioVolume), reinterpret_cast<void **>( & audio_volume));
hr = client->GetService(__uuidof(IChannelAudioVolume), (void **)&channel_volume);
start_time_ms = 0;
paused=false;
client->Start();
// Start volume is in range 0.0 to 1.0, should be converted
SetVolume((int)(start_volume * VolumeLevelMultiplier));
SetPan((int)start_pan);
return 1000;
}
static void Close()
{
if (client) {
client->Stop();
client->Release();
client=0;
}
if (render_client) {
render_client->Release();
render_client=0;
}
if (clock) {
clock->Release();
clock=0;
}
if (audio_volume) {
audio_volume->Release();
audio_volume=0;
}
if (channel_volume) {
channel_volume->Release();
channel_volume=0;
}
}
static int CanWrite()
{
if (client) {
UINT32 numFramesPadding;
HRESULT hr = client->GetCurrentPadding(&numFramesPadding);
return (bufferFrameCount - numFramesPadding) * bytes_per_frame;
}
else {
return 0;
}
}
static int Write(char* buf, int len)
{
if (!render_client)
{
return -1;
}
else
{
int LenghtToWrite = CanWrite();
if (LenghtToWrite > 0 && LenghtToWrite >= len)
{
BYTE* data;
render_client->GetBuffer(len / bytes_per_frame, &data);
memcpy(data, buf, len);
render_client->ReleaseBuffer(len / bytes_per_frame, 0);
}
}
return 0;
}
static int IsPlaying()
{
return CanWrite() == 0;
}
static int Pause(int pause)
{
int old_paused = paused?1:0;
if (client) {
if (pause) {
client->Stop();
paused=true;
} else {
client->Start();
paused=false;
}
}
return old_paused;
}
static void SetVolume(int volume)
{
float fVolume = (float)volume / (float)VolumeLevelMultiplier;
if (volume >= 0) {
start_volume = fVolume;
if (audio_volume) {
audio_volume->SetMasterVolume(fVolume, 0);
}
}
}
static void SetPan(int pan)
{
float fPan = (float)pan/128.0f;
if (channel_volume) {
start_pan = fPan;
if (fPan < 0) {
channel_volume->SetChannelVolume(0, 1.0f, NULL);
channel_volume->SetChannelVolume(1, 1.0f-fPan, NULL);
} else if (fPan > 0) {
channel_volume->SetChannelVolume(1, 1.0f, NULL);
channel_volume->SetChannelVolume(0, 1.0f-fPan, NULL);
}
}
}
static void Flush(int t)
{
if (client) {
client->Stop();
client->Reset();
start_time_ms = t;
client->Start();
}
}
static double GetOutputTimeAsDouble()
{
if (clock) {
UINT64 position;
HRESULT hr = clock->GetPosition(&position, NULL);
double output_time = (double)position * 1000.0 / (double)frequency;
return output_time + start_time_ms;
} else {
return 0;
}
}
static int GetOutputTime()
{
return (int)GetOutputTimeAsDouble();
}
static int GetWrittenTime()
{
double time_in_buffer = (1000.0 * (double)CanWrite()) / ((double)bytes_per_frame * (double)sample_rate);
return (int)(GetOutputTimeAsDouble() + time_in_buffer);
}
Out_Module plugin = {
OUT_VER_U,
0,
70,
NULL,
NULL,
Config,
About,
Init,
Quit,
Open,
Close,
Write,
CanWrite,
IsPlaying,
Pause,
SetVolume,
SetPan,
Flush,
GetOutputTime,
GetWrittenTime,
};
extern "C" {
__declspec(dllexport) int __cdecl winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param)
{
return OUT_PLUGIN_UNINSTALL_REBOOT;
}
__declspec(dllexport) Out_Module * __cdecl winampGetOutModule(){ return &plugin; }
__declspec(dllexport) void __cdecl winampGetOutModeChange(int mode)
{
}
}

View File

@ -0,0 +1,81 @@
// 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
#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
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_WASAPI "Nullsoft WASAPI Output v%s"
65535 "{CA8AD152-9760-4AA3-AC54-7464279C5D63}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_WASAPI_OLD "Nullsoft WASAPI Output"
IDS_ABOUT_TEXT "%s\nWritten by Ben Allison\n<> 2015-2023 Ben Allison\nBuild date: %s"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -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}") = "out_wasapi", "out_wasapi.vcxproj", "{389AB984-6C9E-40FF-9556-51B80200AE89}"
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
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|Win32.ActiveCfg = Debug|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|Win32.Build.0 = Debug|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|Win32.ActiveCfg = Release|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|Win32.Build.0 = Release|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|x64.ActiveCfg = Debug|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|x64.Build.0 = Debug|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|x64.ActiveCfg = Release|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FD99919C-E1E8-4534-BAF6-4C7E97120250}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,250 @@
<?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>{389AB984-6C9E-40FF-9556-51B80200AE89}</ProjectGuid>
<RootNamespace>out_wasapi</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>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<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;OUT_WASAPI_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>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_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>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<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>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<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>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="waveformat.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_wasapi.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</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>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="waveformat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{f03738fe-bfa7-4223-9730-d5fd6da53b8e}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{87e33b04-0bd1-46f2-8b54-2f02d76834e9}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{50096f2a-3c40-4451-aa4d-b82937277d9d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_wasapi.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,18 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by out_wasapi.rc
//
#define IDS_NULLSOFT_WASAPI_OLD 0
#define IDS_ABOUT_TEXT 2
#define IDS_NULLSOFT_WASAPI 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 3
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,03,0,0
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", ""
VALUE "FileDescription", "Winamp Output Plug-in"
VALUE "FileVersion", "0,03,0,0"
VALUE "InternalName", "Nullsoft WASAPI Output"
VALUE "LegalCopyright", "Copyright <20> 2015-2023 Ben Allison"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "out_wasapi.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,69 @@
#define INITGUID
#include <mmdeviceapi.h>
#undef INITGUID
#include <mmreg.h>
static WAVEFORMATEXTENSIBLE format_24_stereo =
{
{
WAVE_FORMAT_EXTENSIBLE,
2,
88200,
705600,
8,
32,
22,
},
24,
SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT,
KSDATAFORMAT_SUBTYPE_PCM
};
static WORD BitsPerSampleContainer(int bitspersamp)
{
if (bitspersamp <= 8) {
return 8;
} else if (bitspersamp <= 16) {
return 16;
} else if (bitspersamp <= 24) {
return 24;
} else {
return 32;
}
}
static WORD ChannelMask(int numchannels)
{
switch(numchannels) {
case 1:
return SPEAKER_FRONT_CENTER;
case 2:
return SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT;
case 4: // quadraphonic
return SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT;
case 6: // 5.1
return SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY;
default:
return 0;
}
}
WAVEFORMATEXTENSIBLE WaveFormatForParameters(int samplerate, int numchannels, int bitspersamp)
{
WAVEFORMATEXTENSIBLE wave_format;
wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; /* format type */
wave_format.Format.nChannels = numchannels; /* number of channels (i.e. mono, stereo...) */
wave_format.Format.nSamplesPerSec = samplerate; /* sample rate */
wave_format.Format.nAvgBytesPerSec = BitsPerSampleContainer(bitspersamp) * numchannels * samplerate / 8; /* for buffer estimation */
wave_format.Format.nBlockAlign = BitsPerSampleContainer(bitspersamp) * numchannels / 8; /* block size of data */
wave_format.Format.wBitsPerSample = BitsPerSampleContainer(bitspersamp);
wave_format.Format.cbSize = 22; /* the count in bytes of the size of */
/* extra information (after cbSize) */
wave_format.Samples.wValidBitsPerSample = bitspersamp;
wave_format.dwChannelMask = ChannelMask(numchannels);
wave_format.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
return wave_format;
}

View File

@ -0,0 +1,16 @@
#ifndef NULLSOFT_API_H
#define NULLSOFT_API_H
#include <api/service/api_service.h>
extern api_service *serviceManager;
#define WASABI_API_SVC serviceManager
#include <api/service/waServiceFactory.h>
#include "../Agave/Language/api_language.h"
#include <api/application/api_application.h>
extern api_application *applicationApi;
#define WASABI_API_APP applicationApi
#endif

View File

@ -0,0 +1,248 @@
#include "cnv_pcmwaveout.h"
#include <mmsystem.h>
#include "waveout.h"
#include "../studio/services/svc_textfeed.h"
#define FEEDID_DEVICELIST "waveOut:DEVICES"
static String * devlist;
static UINT n_devs;
#define DEVICE_DEFAULT "(default device)" //trick: use this string for default wave mapper, without querying device names and shit
_string cfg_dev("Device",DEVICE_DEFAULT);
static void devlist_init()
{
if (devlist) return;
n_devs=waveOutGetNumDevs()+1;
UINT n;
WAVEOUTCAPS caps;
devlist=new String[n_devs];
for(n=0;n<n_devs;n++)
{
if (waveOutGetDevCaps(n-1,&caps,sizeof(caps))==MMSYSERR_NOERROR)
{
devlist[n]=caps.szPname;
}
}
}
class TextFeed : public svc_textFeedI {
public:
TextFeed() {
registerFeed(FEEDID_DEVICELIST); // we output shit in <List> objects whose feed param is "DirectSound::DEVICES"
}
static const char *getServiceName() { return "waveOut TextFeed Service"; }
protected:
virtual void registerCallback(const char *feedid, TextFeedCallback *cb)
{
if (!STRICMP(feedid,FEEDID_DEVICELIST))
{//HACK: nice delayed init - don't query device list before we really need to, for really short loading time
static bool inited;
if (!inited)
{
inited=1;
devlist_init();
String feed_devlist="";
UINT n;
for(n=0;n<n_devs;n++)
{
if (!feed_devlist.isempty()) feed_devlist += ";";
feed_devlist+=devlist[n];
}
sendFeed(FEEDID_DEVICELIST, feed_devlist);
if (!strcmp(cfg_dev,DEVICE_DEFAULT)) cfg_dev=devlist[0];
}
}
svc_textFeedI::registerCallback(feedid,cb);
}
};
static waServiceTSingle<svc_textFeed, TextFeed> g_feed;
_int cfg_buf_ms("Buffer length (ms)",2000);
_int cfg_prebuf("Prebuffer (ms)",0);
_bool cfg_vol_enabled("Volume control enabled",1);
_bool cfg_vol_alt("Alt volume control method",0);
_bool cfg_vol_reset("Reset volume on stop",0);
class cnv_pcmwaveout: public svc_mediaConverterI {
private:
WaveOut * pWO;
int fmt_sr,fmt_bps,fmt_nch;
public:
cnv_pcmwaveout()
{
pWO = 0;
fmt_sr = 0;
fmt_bps = 0;
fmt_nch = 0;
}
~cnv_pcmwaveout()
{
if (pWO) delete pWO;
}
static const char *getServiceName() { return "WaveOut Output"; }
virtual int canConvertFrom(svc_fileReader *reader, const char *name, const char *chunktype) {
if(chunktype && !STRICMP(chunktype,"pcm")) return 1;
return 0;
}
virtual const char *getConverterTo() { return "OUTPUT:waveOut"; }
virtual int getInfos(MediaInfo *infos) {return 0;}
virtual int processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch)
{
Chunk * c=chunk_list->getChunk("PCM");
if (!c) return 0;
char * data=(char*)c->getData();
int size=c->getSize();
if (size<=0) {
if (pWO && infos->getData("audio_need_canwrite")) infos->setDataInt("audio_canwrite",pWO->CanWrite(),FALSE);
return 1;
}
int sr,bps,nch;
sr=c->getInfo("srate");
bps=c->getInfo("bps");
nch=c->getInfo("nch");
if (pWO && (fmt_sr!=sr || fmt_bps!=bps || fmt_nch!=nch))
{
while(!*killswitch && pWO->GetLatency()>0) Sleep(1);
delete pWO;
pWO=0;
}
if (*killswitch) return 0;
if (!pWO)
{
fmt_sr=sr;
fmt_bps=bps;
fmt_nch=nch;
WaveOutConfig cfg;
cfg.SetPCM(sr,nch,bps);
cfg.SetBuffer(cfg_buf_ms,cfg_prebuf);
const char * devname=cfg_dev;
if (_stricmp(devname,DEVICE_DEFAULT))
{
devlist_init();
for(UINT n=0;n<n_devs;n++)
{
if (!_stricmp(devname,devlist[n]))
{
cfg.SetDevice(n);
break;
}
}
}
cfg.SetVolumeSetup(cfg_vol_enabled,cfg_vol_alt,cfg_vol_reset);
pWO=WaveOut::Create(&cfg);
if (!pWO)
{
//todo: cfg.GetError() yadda yadda
return 0;
}
pWO->SetVolume(api->core_getVolume(m_coretoken));
pWO->SetPan(api->core_getPan(m_coretoken));
}
while(!*killswitch)
{
int d=pWO->WriteData(data,size);
if (d>0)
{
size-=d;
if (size<=0) break;
data+=d;
}
Sleep(1);
}
return 1;
}
virtual int getLatency(void) {return pWO ? pWO->GetLatency() : 0;}
virtual int corecb_onSeeked(int newpos) {if (pWO) pWO->Flush();return 0;}
virtual int corecb_onVolumeChange(int v) {pWO->SetVolume(v);return 0;}
virtual int corecb_onPanChange(int v) {pWO->SetPan(v);return 0;}
virtual int corecb_onAbortCurrentSong() {if (pWO) pWO->Flush();return 0;}
virtual int corecb_onPaused() {if (pWO) pWO->Pause(1);return 0;}
virtual int corecb_onUnpaused() {if (pWO) pWO->Pause(0);return 0;}
};
static WACNAME wac;
WAComponentClient *the = &wac;
#include "../studio/services/servicei.h"
static waServiceT<svc_mediaConverter, cnv_pcmwaveout> waveout;
// {E91551F2-E1CE-4484-B331-B3BE2B754B52}
static const GUID guid =
{ 0xe91551f2, 0xe1ce, 0x4484, { 0xb3, 0x31, 0xb3, 0xbe, 0x2b, 0x75, 0x4b, 0x52 } };
WACNAME::WACNAME() {
#ifdef FORTIFY
FortifySetName("cnv_pcmwaveout.wac");
FortifyEnterScope();
#endif
registerService(&g_feed);//autoderegistered on shutdown
registerService(&waveout);
registerSkinFile("Wacs/xml/waveout/waveout-prefs.xml");
}
WACNAME::~WACNAME() {
#ifdef FORTIFY
FortifyLeaveScope();
#endif
if (devlist)
{
delete[] devlist;
devlist=0;
}
n_devs=0;
}
GUID WACNAME::getGUID() {
return guid;
}
void WACNAME::onDestroy() {
}
void WACNAME::onCreate()
{
// {EDAA0599-3E43-4eb5-A65D-C0A0484240E7}
static const GUID cfg_audio_guid =
{ 0xedaa0599, 0x3e43, 0x4eb5, { 0xa6, 0x5d, 0xc0, 0xa0, 0x48, 0x42, 0x40, 0xe7 } };
api->preferences_registerGroup("waveout", "waveOut", guid, cfg_audio_guid);
registerAttribute(&cfg_dev);
registerAttribute(&cfg_buf_ms);
registerAttribute(&cfg_prebuf);
registerAttribute(&cfg_vol_enabled);
registerAttribute(&cfg_vol_alt);
registerAttribute(&cfg_vol_reset);
}

View File

@ -0,0 +1,37 @@
#ifndef _CNV_DS2_H
#define _CNV_DS2_H
#include "../studio/wac.h"
#include "../common/rootcomp.h"
#include "../attribs/cfgitemi.h"
#include "../attribs/attrint.h"
#include "../attribs/attrbool.h"
#include "../attribs/attrstr.h"
#include "../studio/services/svc_mediaconverter.h"
#include "../studio/services/servicei.h"
#include "../studio/corecb.h"
#include "../studio/wac.h"
#define WACNAME WACcnv_waveout
class WACNAME : public WAComponentClient {
public:
WACNAME();
virtual ~WACNAME();
virtual const char *getName() { return "WaveOut Output"; };
virtual GUID getGUID();
virtual void onDestroy();
virtual void onCreate();
virtual int getDisplayComponent() { return FALSE; };
virtual CfgItem *getCfgInterface(int n) { return this; }
};
#endif

View File

@ -0,0 +1,576 @@
#include "out_wave.h"
#include "api.h"
#include "resource.h"
#include "waveout.h"
#include "../winamp/wa_ipc.h"
#include "../nu/AutoWide.h"
#ifdef HAVE_SSRC
#include "ssrc\ssrc.h"
static Resampler_base * pSSRC;
#endif
static bool gapless_stop;
static WaveOut * pWO;
static __int64 total_written;
static int pos_delta;
static UINT canwrite_hack;
// wasabi based services for localisation support
api_service *WASABI_API_SVC = 0;
api_language *WASABI_API_LNG = 0;
api_application *WASABI_API_APP = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
void _init();
//cfg_prebuf now in ms !
UINT cfg_dev = 0, cfg_buf_ms = 2000, cfg_prebuf = 200, cfg_trackhack = 200;
bool cfg_volume = 1, cfg_altvol = 0, cfg_resetvol = 0;
static int fmt_sr, fmt_bps, fmt_nch;
static int volume = 255, pan = 0;
#ifdef HAVE_SSRC
UINT cfg_dither = 1, cfg_resample_freq = 48000, cfg_resample_bps = 1;
bool cfg_fast = 1;
UINT cfg_pdf = 1;
UINT bps_tab[3] = {8, 16, 24};
static bool finished, use_finish;
static UINT resample_freq;
static UINT resample_bps;
static void do_ssrc_create()
{
pSSRC = SSRC_create(fmt_sr, resample_freq, fmt_bps, resample_bps, fmt_nch, cfg_dither, cfg_pdf, cfg_fast, 0);
finished = 0;
use_finish = cfg_trackhack == 0 ? 1 : 0;
}
#endif
void do_cfg(bool s);
static CRITICAL_SECTION sync; //various funky time consuming stuff going on, better protect ourselves with a critical section here, resampler doesnt have its own one
#define SYNC_IN EnterCriticalSection(&sync);
#define SYNC_OUT LeaveCriticalSection(&sync);
void Config(HWND);
int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
{
MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMSW),0};
msgbx.lpszText = message;
msgbx.lpszCaption = title;
msgbx.lpszIcon = MAKEINTRESOURCEW(102);
msgbx.hInstance = GetModuleHandle(0);
msgbx.dwStyle = MB_USERICON;
msgbx.hwndOwner = parent;
return MessageBoxIndirectW(&msgbx);
}
void About(HWND hwndParent)
{
wchar_t message[1024] = {0}, text[1024] = {0};
WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_WAVEOUT_OLD,text,1024);
wsprintfW(message, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
mod.description, __DATE__);
DoAboutMessageBox(hwndParent,text,message);
}
static void Init()
{
if (!IsWindow(mod.hMainWindow))
return;
// loader so that we can get the localisation service api for use
WASABI_API_SVC = (api_service*)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
if (!WASABI_API_SVC || WASABI_API_SVC == (api_service *)1)
return;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG(mod.hDllInstance,OutWaveLangGUID);
static wchar_t szDescription[256];
swprintf(szDescription,256,WASABI_API_LNGSTRINGW(IDS_NULLSOFT_WAVEOUT),OUT_WAVE_VER);
mod.description = (char*)szDescription;
}
static int inited;
static void Quit()
{
if (inited)
{
if (pWO)
{
delete pWO;
pWO = 0;
}
#ifdef HAVE_SSRC
if (pSSRC)
{
delete pSSRC;
pSSRC = 0;
}
#endif
do_cfg(1);
inited = 0;
}
}
static void reset_stuff()
{
canwrite_hack = 0;
pos_delta = 0;
total_written = 0;
gapless_stop = 0;
}
void _init()
{
if (!inited)
{
inited = 1;
do_cfg(0);
if (cfg_dev > waveOutGetNumDevs()) cfg_dev = 0;
}
}
static void _write(char * data, int size);
int Open(int sr, int nch, int bps, int bufferlenms, int prebufferms)
{
_init();
SYNC_IN;
if (pWO) //"gapless" track change (or someone forgot to close output)
{
pWO->SetCloseOnStop(0); //turn off self-destruct on out-of-PCM-data
if (!pWO->IsClosed()) //has it run out of PCM data or not ? if yes, we can only delete and create new one
{
if (sr != fmt_sr || nch != fmt_nch || bps != fmt_bps) //tough shit, new pcm format
{ //wait-then-close, dont cut previous track
#ifdef HAVE_SSRC
if (!pSSRC && !finished)
{
use_finish = 1;
_write(0, 0);
}
#endif
while (pWO->GetLatency() > 0) Sleep(1);
}
else
{ //successful gapless track change. yay.
reset_stuff();
#ifdef HAVE_SSRC
if (pSSRC)
{
if (finished)
{
delete pSSRC;
do_ssrc_create();
}
else use_finish = cfg_trackhack == 0 ? 1 : 0;
}
#endif
int r = pWO->GetMaxLatency();
SYNC_OUT;
return r;
}
}
#ifdef HAVE_SSRC
if (pSSRC)
{
delete pSSRC;
pSSRC = 0;
}
#endif
delete pWO;
}
WaveOutConfig * cfg = new WaveOutConfig; //avoid crazy crt references with creating cfg on stack, keep TINY_DLL config happy
cfg->SetBuffer(cfg_buf_ms, cfg_prebuf);
cfg->SetDevice(cfg_dev);
cfg->SetVolumeSetup(cfg_volume, cfg_altvol, cfg_resetvol);
fmt_sr = sr;
fmt_nch = nch;
fmt_bps = bps;
#ifdef HAVE_SSRC
resample_freq = cfg_resample_freq;
if (resample_freq < 6000) resample_freq = 6000;
else if (resample_freq > 192000) resample_freq = 192000;
resample_bps = bps_tab[cfg_resample_bps];
if (fmt_sr == (int)resample_freq && fmt_bps == (int)resample_bps)
{
cfg->SetPCM(fmt_sr, fmt_nch, fmt_bps);
}
else
{
do_ssrc_create();
}
if (!pSSRC) cfg->SetPCM(sr, nch, bps);
else cfg->SetPCM(resample_freq, nch, resample_bps);
#else//!HAVE_SSRC
cfg->SetPCM(sr, nch, bps);
#endif
pWO = WaveOut::Create(cfg);
if (!pWO)
{
const WCHAR *error = cfg->GetError();
if (error)
{
WCHAR err[128] = {0}, temp[128] = {0};
swprintf(err,128,WASABI_API_LNGSTRINGW(IDS_ERROR),WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_WAVEOUT_OLD,temp,128));
MessageBoxW(mod.hMainWindow, error, err, MB_ICONERROR);
}
}
else
{
reset_stuff();
}
delete cfg;
if (pWO)
{
int r = pWO->GetMaxLatency();
SYNC_OUT;
return r;
}
else
{
#ifdef HAVE_SSRC
if (pSSRC)
{
delete pSSRC;
pSSRC = 0;
}
#endif
SYNC_OUT;
return -1;
}
}
#ifdef HAVE_SSRC
static UINT ssrc_extra_latency;
static void _write(char * data, int size)
{
if (pWO)
{
if (pSSRC)
{
if (!finished)
{
UINT nsiz;
if (data > 0) pSSRC->Write(data, (UINT)size);
else if (use_finish)
{
finished = 1;
pSSRC->Finish();
}
data = (char*)pSSRC->GetBuffer(&nsiz);
UINT nsiz1 = nsiz;
while (nsiz) //ugly
{
int wr = pWO->WriteData(data, nsiz);
if (wr > 0)
{
data += wr;
nsiz -= wr;
if (!nsiz) break;
}
ssrc_extra_latency = MulDiv(nsiz, 1000, resample_freq * fmt_nch * (resample_bps >> 3));
SYNC_OUT;
Sleep(1); //shouldnt happen anymore since canwrite works correctly
SYNC_IN;
}
pSSRC->Read(nsiz1);
ssrc_extra_latency = 0;
}
}
else
{
pWO->WriteData(data, size);
}
total_written += size / ((fmt_bps >> 3) * fmt_nch);
}
}
#endif
int Write(char *data, int size)
{
SYNC_IN;
gapless_stop = 0;
canwrite_hack = 0;
// decrypt, if necessary
#ifdef HAVE_SSRC
_write(data, size);
#else
if (pWO)
{
pWO->WriteData(data, size);
total_written += size / ((fmt_bps >> 3) * fmt_nch);
}
#endif
SYNC_OUT;
return 0;
}
void Close()
{
SYNC_IN;
if (pWO)
{
if (gapless_stop) //end-of-song stop, dont close yet, use gapless hacks
{
pWO->SetCloseOnStop(1); //will self-destruct when out of PCM data to play, has no more than 200ms in buffer
}
else //regular stop (user action)
{
delete pWO;
pWO = 0;
#ifdef HAVE_SSRC
if (pSSRC)
{
delete pSSRC;
pSSRC = 0;
}
#endif
}
}
SYNC_OUT;
}
int CanWrite()
{
int r;
SYNC_IN;
if (pWO)
{
#ifdef HAVE_SSRC
if (pSSRC)
{
r = MulDiv(pWO->CanWrite() - (resample_bps >> 3) * fmt_nch, fmt_bps * fmt_sr, resample_freq * resample_bps) - pSSRC->GetDataInInbuf();
if (r < 0) r = 0;
}
else
#endif
r = pWO->CanWrite();
if (++canwrite_hack > 2) pWO->ForcePlay(); //avoid constant-small-canwrite-while-still-prebuffering snafu
}
else r = 0;
SYNC_OUT;
return r;
}
int IsPlaying()
{ //this is called only when decoding is done unless some input plugin dev is really nuts about making useless calls
SYNC_IN;
if (pWO)
{
#ifdef HAVE_SSRC
_write(0, 0);
#endif
pWO->ForcePlay(); //evil short files: make sure that output has started
if ((UINT)pWO->GetLatency() > cfg_trackhack) //cfg_trackhack used to be 200ms constant
{ //just for the case some input plugin dev is actually nuts about making useless calls or user presses stop/prev/next when decoding is finished, we don't activate gapless_stop here
gapless_stop = 0;
SYNC_OUT;
return 1;
}
else
{ //ok so looks like we're really near the end-of-track, time to do gapless track switch mumbo-jumbo
gapless_stop = 1;
SYNC_OUT;
return 0; //hack: make the input plugin think that we're done with current track
}
}
else
{
SYNC_OUT;
return 0;
}
}
int Pause(int new_state)
{
int rv;
SYNC_IN;
if (pWO)
{
rv = pWO->IsPaused();
pWO->Pause(new_state);
}
else rv = 0;
SYNC_OUT;
return rv;
}
void Flush(int pos)
{
SYNC_IN;
if (pWO) pWO->Flush();
#ifdef HAVE_SSRC
if (pSSRC)
{
delete pSSRC;
do_ssrc_create();
}
#endif
reset_stuff();
pos_delta = pos;
SYNC_OUT;
}
void SetVolume(int v)
{
SYNC_IN;
if (v != -666)
{
volume = v;
}
if (pWO) pWO->SetVolume(volume);
SYNC_OUT;
}
void SetPan(int p)
{
SYNC_IN;
pan = p;
if (pWO) pWO->SetPan(pan);
SYNC_OUT;
}
int get_written_time() //this ignores high 32bits of total_written
{
return MulDiv((int)total_written, 1000, fmt_sr);
}
int GetWrittenTime()
{
int r;
SYNC_IN;
r = pWO ? pos_delta + get_written_time() : 0;
SYNC_OUT;
return r;
}
int GetOutputTime()
{
int r;
SYNC_IN;
r = pWO ? (pos_delta + get_written_time()) - pWO->GetLatency() : 0;
#ifdef HAVE_SSRC
if (pSSRC)
r -= ssrc_extra_latency ? ssrc_extra_latency : pSSRC->GetLatency();
#endif
SYNC_OUT;
return r;
}
static int Validate(int dummy1, int dummy2, short key, char dummy4);
static int NewWrite(int len, char *buf);
Out_Module mod =
{
OUT_VER_U,
#ifdef HAVE_SSRC
NAME" SSRC",
#else
0,
#endif
1471482036, //could put different one for SSRC config but i'm too lazy and this shit doesnt seem used anymore anyway
0, 0,
Config,
About,
Init,
Quit,
Open,
Close,
Write,
CanWrite,
IsPlaying,
Pause,
SetVolume,
SetPan,
Flush,
GetOutputTime,
GetWrittenTime,
};
HMODULE thisMod=0;
Out_Module *(*waveGetter)(HINSTANCE) = 0;
HMODULE inWMDLL = 0;
BOOL APIENTRY DllMain(HANDLE hMod, DWORD r, void*)
{
if (r == DLL_PROCESS_ATTACH)
{
thisMod=(HMODULE)hMod;
DisableThreadLibraryCalls((HMODULE)hMod);
InitializeCriticalSection(&sync);
}
else if (r == DLL_PROCESS_DETACH)
{
DeleteCriticalSection(&sync);
if (inWMDLL)
{
FreeLibrary(inWMDLL); // potentially unsafe, we'll see ...
inWMDLL = 0;
}
}
return TRUE;
}
extern "C"
{
__declspec( dllexport ) Out_Module * winampGetOutModule()
{
inWMDLL = GetModuleHandleW(L"in_wm.dll");
if (inWMDLL)
{
waveGetter = (Out_Module * (*)(HINSTANCE))GetProcAddress(inWMDLL, "GetWave");
if (waveGetter)
return waveGetter(thisMod);
}
return &mod;
}
}
bool get_waveout_state(char * z)
{
if (pWO) return pWO->PrintState(z);
else return 0;
}

View File

@ -0,0 +1,7 @@
#define STRICT
#include <windows.h>
#include "../Winamp/out.h"
extern Out_Module mod;
#define OUT_WAVE_VER L"2.22"

View File

@ -0,0 +1,158 @@
// 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
#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
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_WAVE_CONFIG DIALOGEX 0, 0, 311, 169
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
LTEXT "Device:",IDC_STATIC,4,8,26,8
COMBOBOX IDC_DEV,34,6,160,82,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Buffering",IDC_STATIC,4,24,190,76
LTEXT "Buffer length:",IDC_STATIC,20,34,46,8
CONTROL "Slider1",IDC_BUFFER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,66,33,120,12
CTEXT "z",IDC_BUF_DISP,70,44,112,8
LTEXT "Prebuffer:",IDC_STATIC,34,56,32,8
CONTROL "Slider1",IDC_PREBUFFER_1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,66,55,120,12
CTEXT "z",IDC_PREBUF_DISP_1,70,66,112,8
LTEXT "Buffer-ahead\non track change:",IDC_STATIC,12,76,56,18
CONTROL "Slider1",IDC_PREBUFFER_2,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,66,78,120,12
CTEXT "z",IDC_PREBUF_DISP_2,70,88,112,8
GROUPBOX "Volume Control",IDC_STATIC,4,104,190,46
CONTROL "Enable",IDC_VOL_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,118,38,10
CONTROL "Alt. setting method (slow)",IDC_ALT_VOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,92,118,94,10
CONTROL "Reset to original value on stop",IDC_VOL_RESET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,134,111,10
GROUPBOX "Status Display",IDC_STATIC,198,4,108,121
LTEXT "",IDC_STATE,204,15,96,105
LTEXT "Note: Most settings take full effect after restarting playback",IDC_BLAH,4,155,194,8,WS_DISABLED
PUSHBUTTON "Reset to defaults",IDC_RESET,199,131,108,13
DEFPUSHBUTTON "OK",IDOK,199,150,52,13
PUSHBUTTON "Cancel",IDCANCEL,255,150,52,13
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_WAVE_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 307
TOPMARGIN, 7
BOTTOMMARGIN, 163
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_WAVEOUT "Nullsoft WaveOut Output v%s"
65535 "{004A91D9-CCD6-44e5-973A-4B7045C4662B}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_WAVEOUT_OLD "Nullsoft WaveOut Output"
IDS_NOT_ACTIVE "not active"
IDS_UNKNOWN_MMSYSTEM_ERROR "Unknown MMSYSTEM error."
IDS_UNSUPPORTED_PCM_FORMAT
"Unsupported PCM format (%u Hz, %u bits per sample, %u channels). Please change format settings in input plug-in configuration or change output device in waveOut plug-in configuration."
IDS_ANOTHER_PROGRAM_IS_USING_THE_SOUNDCARD
"Another program is using your soundcard. Please change output device (in waveOut plug-in configuration), switch to DirectSound output (in Winamp preferences / plug-ins / output) or get a soundcard which can play multiple streams."
IDS_NO_SOUND_DEVICES_FOUND
"No sound devices found. Please buy a soundcard first (or install proper drivers if you think that you have one)."
IDS_INTERNAL_DRIVER_ERROR
"Internal driver error; please reboot your computer."
IDS_REINSTALL_SOUNDCARD_DRIVERS "Please reinstall soundcard drivers."
IDS_ERROR_CODE_WINDOWS_ERROR_MESSAGE
"%s\n\nError code: %u\nWindows error message: \n""%s"""
IDS_ERROR_CODE "%s\nError code: %u"
IDS_DATA_FORMAT "Data format: \n %u Hz\n %u bits per sample\n %u channel(s)\n"
IDS_BUFFER_STATUS "Buffer status:\n %u bytes allocated\n %u blocks queued\n"
IDS_LATENCY "Latency: %u ms\n"
IDS_PREFS_TITLE "%s Settings"
END
STRINGTABLE
BEGIN
IDS_ERROR "%s Error"
IDS_WAVE_U_MS "%u ms"
IDS_ABOUT_TEXT "%s\n<> 2005-2023 Winamp SA\n<> 2001-2002 Peter Pawlowski\t\nBuild date: %hs"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,30 @@
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}") = "out_wave", "out_wave.vcxproj", "{D63584C4-6233-4469-AD94-4B9E0BDD15B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Debug|Win32.ActiveCfg = Debug|Win32
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Debug|Win32.Build.0 = Debug|Win32
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Release|Win32.ActiveCfg = Release|Win32
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Release|Win32.Build.0 = Release|Win32
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Debug|x64.ActiveCfg = Debug|x64
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Debug|x64.Build.0 = Debug|x64
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Release|x64.ActiveCfg = Release|x64
{D63584C4-6233-4469-AD94-4B9E0BDD15B7}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E2F57101-9F64-4677-A8F2-3F76DCA10FD4}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,284 @@
<?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>{D63584C4-6233-4469-AD94-4B9E0BDD15B7}</ProjectGuid>
<RootNamespace>out_wave</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" 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>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</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)'=='Release|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)'=='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)'=='Debug|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>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<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;OUT_wave_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>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;dsound.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;OUT_wave_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>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;dsound.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OUT_wave_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;dsound.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<DelayLoadDLLs>winmm.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;OUT_wave_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;dsound.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<DelayLoadDLLs>winmm.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="api.h" />
<ClInclude Include="out_wave.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="waveout.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="out_wave.cpp" />
<ClCompile Include="wa2_config.cpp" />
<ClCompile Include="waveout.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_wave.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>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="out_wave.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wa2_config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="waveout.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="waveout.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="out_wave.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{864917ef-d719-4565-9427-bd2c884cedff}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{784d9708-92ec-4f11-b552-29c92528bf31}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{c5280fb1-feed-44f9-8a38-2ba42a13bb94}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_wave.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,60 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by out_wave.rc
//
#define IDS_NULLSOFT_WAVEOUT_OLD 0
#define IDS_NOT_ACTIVE 1
#define IDS_UNKNOWN_MMSYSTEM_ERROR 2
#define IDC_RESET 3
#define IDS_UNSUPPORTED_PCM_FORMAT 3
#define IDS_ANOTHER_PROGRAM_IS_USING_THE_SOUNDCARD 4
#define IDS_NO_SOUND_DEVICES_FOUND 5
#define IDS_INTERNAL_DRIVER_ERROR 6
#define IDS_REINSTALL_SOUNDCARD_DRIVERS 7
#define IDS_ERROR_CODE_WINDOWS_ERROR_MESSAGE 8
#define IDS_ERROR_CODE 9
#define IDS_DATA_FORMAT 10
#define IDS_BUFFER_STATUS 11
#define IDS_LATENCY 12
#define IDS_ABOUT 13
#define IDS_PREFS_TITLE 15
#define IDS_ERROR 16
#define IDS_WAVE_U_MS 17
#define IDS_ABOUT_STRING 18
#define IDS_ABOUT_TEXT 18
#define IDD_CONFIG 300
#define IDD_WAVE_CONFIG 300
#define IDC_GAPLESS 1000
#define IDC_BUF_SIZE 1001
#define IDC_SPIN1 1002
#define IDC_PRIMARY 1003
#define IDC_PREBUF_SIZE 1003
#define IDC_DEV 1004
#define IDC_HACK 1005
#define IDC_EXCLUSIVE 1006
#define IDC_PREBUFFER 1007
#define IDC_SPIN2 1008
#define IDC_VOL_ENABLE 1009
#define IDC_ALT_VOL 1010
#define IDC_VOL_RESET 1011
#define IDC_PREB_TEXT 1012
#define IDC_STATE 1013
#define IDC_PREBUFFER_1 1014
#define IDC_PREBUFFER_2 1015
#define IDC_PREBUF_DISP_1 1016
#define IDC_PREBUF_DISP_2 1017
#define IDC_BLAH 1018
#define IDC_BUFFER 1020
#define IDC_BUF_DISP 1021
#define IDS_NULLSOFT_WAVEOUT 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 301
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1019
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,22,0,0
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 Output Plug-in"
VALUE "FileVersion", "2,22,0,0"
VALUE "InternalName", "Nullsoft Wave Output"
VALUE "LegalCopyright", "Copyright <20> 2005-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "out_wave.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,267 @@
#include "out_wave.h"
#include "api.h"
#include <commctrl.h>
#include "resource.h"
#include <math.h>
#include "../winamp/wa_ipc.h"
#pragma intrinsic(log)
#ifndef _WIN64
//__inline long int lrint (double flt)
//{
// int intgr;
//
// _asm
// {
// fld flt
// fistp intgr
// }
//
// return intgr;
//}
#else
//__inline long int lrint (double flt)
//{
// return (int)flt;
//}
#endif
#pragma warning(disable:4800)
extern Out_Module mod;
extern UINT cfg_buf_ms,cfg_dev,cfg_prebuf;
extern bool cfg_volume,cfg_altvol,cfg_resetvol;
extern UINT cfg_trackhack;
bool get_waveout_state(char * z) throw();
void _init();
#define BUFFER_SCALE 4000.0
static UINT cur_buffer;
static UINT get_buffer(HWND wnd)
{
if (cur_buffer) return cur_buffer;
//0-BUFFER_SCALE => 200-20000
LRESULT z=SendDlgItemMessage(wnd,IDC_BUFFER,TBM_GETPOS,0,0);
//return cur_buffer=lrint( 0.5 + 200.0*pow(100.0,((double)z)/BUFFER_SCALE) );
}
#define LOG100 4.6051701859880913680359829093687
static void set_buffer(HWND wnd,UINT b)
{
cur_buffer=b;
SendDlgItemMessage(wnd,IDC_BUFFER,TBM_SETPOS,1,lrint( 0.5 + BUFFER_SCALE * log( (double)b/200.0 ) / LOG100 /* / log( 100.0 )*/ ));
}
static void update_prebuf_1(HWND wnd)
{
WCHAR zz[128] = { 0 };
wsprintf(zz, WASABI_API_LNGSTRINGW(IDS_WAVE_U_MS), SendDlgItemMessage(wnd, IDC_PREBUFFER_1, TBM_GETPOS, 0, 0));
SetDlgItemText(wnd,IDC_PREBUF_DISP_1,zz);
}
static void update_prebuf_2(HWND wnd)
{
WCHAR zz[128] = { 0 };
wsprintf(zz, WASABI_API_LNGSTRINGW(IDS_WAVE_U_MS), SendDlgItemMessage(wnd, IDC_PREBUFFER_2, TBM_GETPOS, 0, 0));
SetDlgItemText(wnd,IDC_PREBUF_DISP_2,zz);
}
static void update_prebuf_range(HWND wnd)
{
UINT max=get_buffer(wnd);
if (max>0x7FFF) max=0x7FFF;
SendDlgItemMessage(wnd,IDC_PREBUFFER_1,TBM_SETRANGE,1,MAKELONG(0,max));
SendDlgItemMessage(wnd,IDC_PREBUFFER_2,TBM_SETRANGE,1,MAKELONG(0,max));
}
static void update_buf(HWND wnd)
{
WCHAR zz[128] = { 0 };
wsprintf(zz, WASABI_API_LNGSTRINGW(IDS_WAVE_U_MS), get_buffer(wnd));
SetDlgItemText(wnd,IDC_BUF_DISP,zz);
}
static INT_PTR WINAPI CfgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_INITDIALOG:
{
wchar_t title[128] = {0}, temp[128] = {0};
swprintf(title,128,WASABI_API_LNGSTRINGW(IDS_PREFS_TITLE),WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_WAVEOUT_OLD,temp,128));
SetWindowTextW(wnd,title);
SendDlgItemMessage(wnd,IDC_VOL_ENABLE,BM_SETCHECK,(long)cfg_volume,0);
SendDlgItemMessage(wnd,IDC_ALT_VOL,BM_SETCHECK,(long)cfg_altvol,0);
SendDlgItemMessage(wnd,IDC_VOL_RESET,BM_SETCHECK,(long)cfg_resetvol,0);
{
int dev;
HWND w=GetDlgItem(wnd,IDC_DEV);
UINT max=waveOutGetNumDevs();
WAVEOUTCAPS caps;
for(dev=-1;dev<(int)max;dev++)
{
if (waveOutGetDevCaps((UINT)dev,&caps,sizeof(caps)) == MMSYSERR_NOERROR)
SendMessage(w,CB_ADDSTRING,0,(LPARAM)caps.szPname);
}
SendMessage(w,CB_SETCURSEL,cfg_dev,0);
}
SendDlgItemMessage(wnd,IDC_BUFFER,TBM_SETRANGE,0,MAKELONG(0,(int)BUFFER_SCALE));
set_buffer(wnd,cfg_buf_ms);
update_prebuf_range(wnd);
SendDlgItemMessage(wnd,IDC_PREBUFFER_1,TBM_SETPOS,1,cfg_prebuf);
SendDlgItemMessage(wnd,IDC_PREBUFFER_2,TBM_SETPOS,1,cfg_trackhack);
update_prebuf_1(wnd);
update_prebuf_2(wnd);
update_buf(wnd);
SetTimer(wnd,1,500,0);
CfgProc(wnd,WM_TIMER,0,0);
}
return 1;
case WM_COMMAND:
switch(wp)
{
case IDC_RESET:
SendDlgItemMessage(wnd,IDC_VOL_ENABLE,BM_SETCHECK,1,0);
SendDlgItemMessage(wnd,IDC_ALT_VOL,BM_SETCHECK,0,0);
SendDlgItemMessage(wnd,IDC_VOL_RESET,BM_SETCHECK,0,0);
SendDlgItemMessage(wnd,IDC_DEV,CB_SETCURSEL,0,0);
set_buffer(wnd,2000);
update_prebuf_range(wnd);
SendDlgItemMessage(wnd,IDC_PREBUFFER_1,TBM_SETPOS,1,200);
SendDlgItemMessage(wnd,IDC_PREBUFFER_2,TBM_SETPOS,1,200);
update_prebuf_1(wnd);
update_prebuf_2(wnd);
update_buf(wnd);
break;
case IDOK:
KillTimer(wnd,1);
cfg_dev=(UINT)SendDlgItemMessage(wnd,IDC_DEV,CB_GETCURSEL,0,0);
cfg_buf_ms=get_buffer(wnd);
cfg_prebuf= (UINT)SendDlgItemMessage(wnd,IDC_PREBUFFER_1,TBM_GETPOS,0,0);
cfg_trackhack=(UINT)SendDlgItemMessage(wnd,IDC_PREBUFFER_2,TBM_GETPOS,0,0);
cfg_volume=(bool)SendDlgItemMessage(wnd,IDC_VOL_ENABLE,BM_GETCHECK,0,0);
cfg_altvol=(bool)SendDlgItemMessage(wnd,IDC_ALT_VOL,BM_GETCHECK,0,0);
cfg_resetvol=(bool)SendDlgItemMessage(wnd,IDC_VOL_RESET,BM_GETCHECK,0,0);
EndDialog(wnd,1);
break;
case IDCANCEL:
KillTimer(wnd,1);
EndDialog(wnd,0);
break;
}
break;
case WM_HSCROLL:
switch(GetWindowLong((HWND)lp,GWL_ID))
{
case IDC_BUFFER:
cur_buffer=0;
update_buf(wnd);
update_prebuf_range(wnd);
update_prebuf_1(wnd);
update_prebuf_2(wnd);
break;
case IDC_PREBUFFER_1:
update_prebuf_1(wnd);
break;
case IDC_PREBUFFER_2:
update_prebuf_2(wnd);
break;
}
break;
case WM_TIMER:
{
char poo[512] = {0};
bool z=get_waveout_state(poo);
SetDlgItemTextA(wnd,IDC_STATE,z ? poo : WASABI_API_LNGSTRING(IDS_NOT_ACTIVE));
EnableWindow(GetDlgItem(wnd,IDC_BLAH),z);
}
break;
}
const int controls[] =
{
IDC_BUFFER,
IDC_PREBUFFER_1,
IDC_PREBUFFER_2,
};
if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(wnd, msg, wp, lp, controls, ARRAYSIZE(controls)))
{
return TRUE;
}
return 0;
}
void Config(HWND w)
{
_init();
WASABI_API_DIALOGBOXW(IDD_CONFIG,w,CfgProc);
}
static char _dllfile[MAX_PATH];
static char * dllfile;
char *inifile=0;
static UINT atoui(char* s)
{
int ret=0;
while(s && *s>='0' && *s<='9') {ret=10*ret+(*s-'0');s++;}
return ret;
}
static int _do_var(unsigned int v,char* n,bool s)
{
if (s)
{
char tmp[2*sizeof(unsigned int) + 1] = {0}; // max 32 bit unsigned int == 4 294 967 296 == 10 digits, 11 if signed
wsprintfA(tmp,"%u",v);
WritePrivateProfileStringA(dllfile,n,tmp,inifile);
return v;
}
else
{
char tmp[64],tmp_s[2*sizeof(unsigned int) + 1] = {0};
wsprintfA(tmp_s,"%u",v);
GetPrivateProfileStringA(dllfile,n,tmp_s,tmp,64,inifile);
return atoui(tmp);
}
}
#define do_var(V) {V=_do_var(V,#V,s);}
void do_cfg(bool s)
{
if (!inifile)
inifile =(char *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILE);
if (!dllfile)
{
GetModuleFileNameA(mod.hDllInstance,_dllfile,sizeof(_dllfile));
dllfile=strrchr(_dllfile,'\\');
if (!dllfile) dllfile=_dllfile;
else dllfile++;
char * p=strchr(dllfile,'.');
if (p) *p=0;
}
do_var(cfg_buf_ms);
do_var(cfg_dev);
do_var(cfg_volume);
do_var(cfg_altvol);
do_var(cfg_resetvol);
do_var(cfg_prebuf);
do_var(cfg_trackhack);
}

View File

@ -0,0 +1,617 @@
#define STRICT
#include <windows.h>
#include "out_wave.h"
#include "api.h"
#include "waveout.h"
#include "resource.h"
#include <mmreg.h>
#pragma intrinsic(memset, memcpy)
#define SYNC_IN EnterCriticalSection(&sync);
#define SYNC_OUT LeaveCriticalSection(&sync);
#define GET_TIME timeGetTime()
static const int kMaxChannelsToMask = 8;
static const unsigned int kChannelsToMask[kMaxChannelsToMask + 1] = {
0,
// 1 = Mono
SPEAKER_FRONT_CENTER,
// 2 = Stereo
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,
// 3 = Stereo + Center
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER,
// 4 = Quad
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
// 5 = 5.0
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
// 6 = 5.1
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT,
// 7 = 6.1
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |
SPEAKER_BACK_CENTER,
// 8 = 7.1
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT |
SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT
// TODO(fbarchard): Add additional masks for 7.2 and beyond.
};
WaveOut::~WaveOut()
{
if (hThread)
{
SYNC_IN
die=1;
SYNC_OUT;
SetEvent(hEvent);
WaitForSingleObject(hThread,INFINITE);
}
if (hEvent) CloseHandle(hEvent);
DeleteCriticalSection(&sync);
killwaveout();
if (buffer) LocalFree(buffer);
hdr_free_list(hdrs);
hdr_free_list(hdrs_free);
}
DWORD WINAPI WaveOut::ThreadProc(WaveOut * p)
{
p->thread();
return 0;
}
void WaveOut::thread()
{
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
while(hWo)
{
WaitForSingleObject(hEvent,INFINITE);
SYNC_IN;
if (die) {SYNC_OUT; break;}
for(HEADER * h=hdrs;h;)
{
if (h->hdr.dwFlags&WHDR_DONE)
{
n_playing--;
buf_size_used-=h->hdr.dwBufferLength;
last_time=GET_TIME;
waveOutUnprepareHeader(hWo,&h->hdr,sizeof(WAVEHDR));
HEADER* f=h;
h=h->next;
hdr_free(f);
}
else h=h->next;
}
/* if (needflush)
{
flush();
if (!paused) waveOutRestart(hWo);
needflush=0;
}*/
if (!paused && newpause)
{
paused=1;
if (hWo) waveOutPause(hWo);
p_time=GET_TIME-last_time;
}
if (paused && !newpause)
{
paused=0;
if (hWo) waveOutRestart(hWo);
last_time = GET_TIME-p_time;
}
UINT limit;
if (needplay) limit=0;
else if (!n_playing)
{
limit=prebuf;
if (limit<avgblock) limit=avgblock;
}
else if (buf_size_used<(buf_size>>1) || n_playing<3) limit=minblock;//skipping warning, blow whatever we have
else limit=avgblock;//just a block
while(data_written>limit)
{
UINT d=(data_written > maxblock) ? maxblock : data_written;
d-=d%fmt_align;
if (!d) break;
data_written-=d;
buf_size_used+=d;
HEADER * h=hdr_alloc();
h->hdr.dwBytesRecorded=h->hdr.dwBufferLength=d;
h->hdr.lpData=buffer+write_ptr;
write_ptr+=d;
if (write_ptr>buf_size)
{
write_ptr-=buf_size;
memcpy(buffer+buf_size,buffer,write_ptr);
}
n_playing++;
if (use_altvol) do_altvol(h->hdr.lpData,d);
waveOutPrepareHeader(hWo,&h->hdr,sizeof(WAVEHDR));
waveOutWrite(hWo,&h->hdr,sizeof(WAVEHDR));//important: make all waveOutWrite calls from *our* thread to keep win2k/xp happy
if (n_playing==1) last_time=GET_TIME;
#if 0
{
char t[128] = {0};
wsprintf(t,"block size: %u, limit used %u\n", d,limit);
OutputDebugString(t);
}
#endif
}
needplay=0;
if (!data_written && !n_playing && closeonstop) killwaveout();
SYNC_OUT;
}
killwaveout();
}
int WaveOut::WriteData(const void * _data,UINT size)
{
SYNC_IN;
if (paused) //$!#@!
{
SYNC_OUT;
return 0;
}
const char * data=(const char*)_data;
{
UINT cw=CanWrite();
if (size>cw)
{
size=cw;
}
}
UINT written=0;
while(size>0)
{
UINT ptr=(data_written + write_ptr)%buf_size;
UINT delta=size;
if (ptr+delta>buf_size) delta=buf_size-ptr;
memcpy(buffer+ptr,data,delta);
data+=delta;
size-=delta;
written+=delta;
data_written+=delta;
}
SYNC_OUT; // sync out first to prevent a ping-pong condition
if (written) SetEvent(hEvent);//new shit, time to update
return (int)written;
}
void WaveOut::flush()//in sync
{
waveOutReset(hWo);
while(hdrs)
{
if (hdrs->hdr.dwFlags & WHDR_PREPARED)
{
waveOutUnprepareHeader(hWo,&hdrs->hdr,sizeof(WAVEHDR));
}
hdr_free(hdrs);
}
reset_shit();
}
void WaveOut::Flush()
{
/* SYNC_IN;
needflush=1;
SetEvent(hEvent);
SYNC_OUT;
while(needflush) Sleep(1);*/
SYNC_IN;//no need to sync this to our thread
flush();
if (!paused) waveOutRestart(hWo);
SYNC_OUT;
}
void WaveOut::ForcePlay()
{
SYNC_IN;//needs to be done in our thread
if (!paused) {needplay=1;SetEvent(hEvent);}
SYNC_OUT;
// while(needplay) Sleep(1);
}
WaveOut::WaveOut()
{
#ifndef TINY_DLL //TINY_DLL has its own new operator with zeroinit
memset(&hWo,0,sizeof(*this)-((char*)&hWo-(char*)this));
#endif
myvol=-666;
mypan=-666;
InitializeCriticalSection(&sync);
}
int WaveOut::open(WaveOutConfig * cfg)
{
fmt_sr = cfg->sr;
fmt_bps = cfg->bps;
fmt_nch = cfg->nch;
fmt_align = ( fmt_bps >> 3 ) * fmt_nch;
fmt_mul = fmt_align * fmt_sr;
use_volume=cfg->use_volume;
use_altvol=cfg->use_altvol;
use_resetvol=cfg->resetvol;
if (!use_volume)
use_altvol=use_resetvol=0;
else if (use_altvol)
{
use_resetvol=0;
use_volume=0;
}
WAVEFORMATEX wfx=
{
WAVE_FORMAT_PCM,
(WORD)fmt_nch,
fmt_sr,
fmt_mul,
(WORD)fmt_align,
(WORD)fmt_bps,
0
};
if (!hEvent) hEvent=CreateEvent(0,0,0,0);
WAVEFORMATEXTENSIBLE wfxe = { 0 };
wfxe.Format = wfx;
wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfxe.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
wfxe.Format.nChannels = fmt_nch;
wfxe.Format.nBlockAlign = (wfxe.Format.nChannels *
wfxe.Format.wBitsPerSample) / 8;
wfxe.Format.nAvgBytesPerSec = wfxe.Format.nBlockAlign *
wfxe.Format.nSamplesPerSec;
wfxe.Samples.wReserved = 0;
if (fmt_nch > kMaxChannelsToMask) {
wfxe.dwChannelMask = kChannelsToMask[kMaxChannelsToMask];
}
else {
wfxe.dwChannelMask = kChannelsToMask[fmt_nch];
}
wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;
MMRESULT mr = waveOutOpen(&hWo, (UINT)(cfg->dev-1), reinterpret_cast<LPCWAVEFORMATEX>(&wfxe), (DWORD_PTR)hEvent, 0, CALLBACK_EVENT);
if (mr)
{
WCHAR full_error[1024], * _fe = full_error;
WCHAR poo[MAXERRORLENGTH] = { 0 };
WCHAR* e = poo;
if (waveOutGetErrorTextW(mr,poo,MAXERRORLENGTH)!=MMSYSERR_NOERROR)
{
WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN_MMSYSTEM_ERROR, poo, MAXERRORLENGTH);
}
char * e2=0, e2Buf[1024] = {0};
switch(mr)
{
case 32:
wsprintfW(_fe, WASABI_API_LNGSTRINGW(IDS_UNSUPPORTED_PCM_FORMAT), fmt_sr, fmt_bps, fmt_nch);
//fixme: some broken drivers blow mmsystem032 for no reason, with "standard" 44khz/16bps/stereo, need better error message when pcm format isnt weird
while(_fe && *_fe) _fe++;
e2="";
break;
case 4:
e2=WASABI_API_LNGSTRING_BUF(IDS_ANOTHER_PROGRAM_IS_USING_THE_SOUNDCARD,e2Buf,1024);
break;
case 2:
e2=WASABI_API_LNGSTRING_BUF(IDS_NO_SOUND_DEVICES_FOUND,e2Buf,1024);
break;
case 20:
e2=WASABI_API_LNGSTRING_BUF(IDS_INTERNAL_DRIVER_ERROR,e2Buf,1024);
break;
case 7:
e2=WASABI_API_LNGSTRING_BUF(IDS_REINSTALL_SOUNDCARD_DRIVERS,e2Buf,1024);
break;
//case 8: fixme
}
if (e2)
{
wsprintfW(_fe, WASABI_API_LNGSTRINGW(IDS_ERROR_CODE_WINDOWS_ERROR_MESSAGE), e2, mr, e);
}
else
{
wsprintfW(_fe, WASABI_API_LNGSTRINGW(IDS_ERROR_CODE), e, mr);
}
cfg->SetError(full_error);
return 0;
}
buf_size=MulDiv(cfg->buf_ms,fmt_mul,1000);
maxblock = 0x10000;
minblock = 0x100;
avgblock = buf_size>>4;
if (maxblock>buf_size>>2) maxblock=buf_size>>2;
if (avgblock>maxblock) avgblock=maxblock;
if (maxblock<minblock) maxblock=minblock;
if (avgblock<minblock) avgblock=minblock;
buffer = (char*)LocalAlloc(LPTR,buf_size+maxblock);//extra space at the end of the buffer
prebuf = MulDiv(cfg->prebuf,fmt_mul,1000);
if (prebuf>buf_size) prebuf=buf_size;
n_playing=0;
waveOutRestart(hWo);
reset_shit();
if (use_resetvol) waveOutGetVolume(hWo,&orgvol);
if (myvol!=-666 || mypan!=-666) update_vol();
{
DWORD dw;
hThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc,this,0,&dw);
}
return 1;
}
int WaveOut::GetLatency(void)
{
SYNC_IN;
int r=0;
if (hWo)
{
r=MulDiv(buf_size_used+data_written,1000,(fmt_bps>>3)*fmt_nch*fmt_sr);
if (paused) r-=p_time;
else if (n_playing) r-=GET_TIME-last_time;
if (r<0) r=0;
}
SYNC_OUT;
return r;
}
void WaveOut::SetVolume(int v)
{
SYNC_IN;
myvol=v;
update_vol();
SYNC_OUT;
}
void WaveOut::SetPan(int p)
{
SYNC_IN;
mypan=p;
update_vol();
SYNC_OUT;
}
void WaveOut::update_vol()
{
if (hWo && use_volume)
{
if (myvol==-666) myvol=255;
if (mypan==-666) mypan=0;
DWORD left,right;
left=right=myvol|(myvol<<8);
if (mypan<0) right=(right*(128+mypan))>>7;
else if (mypan>0) left=(left*(128-mypan))>>7;
waveOutSetVolume(hWo,left|(right<<16));
}
}
void WaveOut::reset_shit()
{
n_playing=0;
data_written=0;
buf_size_used=0;
last_time=0;
//last_time=GET_TIME;
}
void WaveOut::Pause(int s)
{
SYNC_IN;
newpause=s?1:0;//needs to be done in our thread to keep stupid win2k/xp happy
SYNC_OUT;
SetEvent(hEvent);
while(paused!=newpause) Sleep(1);
}
void WaveOut::killwaveout()
{
if (hWo)
{
flush();
if (use_resetvol) waveOutSetVolume(hWo,orgvol);
waveOutClose(hWo);
hWo=0;
}
}
int WaveOut::CanWrite()
{
SYNC_IN;
int rv=paused ? 0 : buf_size-buf_size_used-data_written;
SYNC_OUT;
return rv;
}
WaveOut * WaveOut::Create(WaveOutConfig * cfg)
{
WaveOut * w=new WaveOut;
if (w->open(cfg)<=0)
{
delete w;
w=0;
}
return w;
}
WaveOut::HEADER * WaveOut::hdr_alloc()
{
HEADER * r;
if (hdrs_free)
{
r=hdrs_free;
hdrs_free=hdrs_free->next;
}
else
{
r=new HEADER;
}
r->next=hdrs;
hdrs=r;
memset(&r->hdr,0,sizeof(WAVEHDR));
return r;
}
void WaveOut::hdr_free(HEADER * h)
{
HEADER ** p=&hdrs;
while(p && *p)
{
if (*p==h)
{
*p = (*p)->next;
break;
}
else p=&(*p)->next;
}
h->next=hdrs_free;
hdrs_free=h;
}
void WaveOut::hdr_free_list(HEADER * h)
{
while(h)
{
HEADER * t=h->next;
delete h;
h=t;
}
}
bool WaveOut::PrintState(char * z)
{
bool rv;
SYNC_IN;
if (!hWo) rv=0;
else
{
rv=1;
wsprintfA(z,WASABI_API_LNGSTRING(IDS_DATA_FORMAT),fmt_sr,fmt_bps,fmt_nch);
while(z && *z) z++;
wsprintfA(z,WASABI_API_LNGSTRING(IDS_BUFFER_STATUS),buf_size,n_playing);
while(z && *z) z++;
wsprintfA(z,WASABI_API_LNGSTRING(IDS_LATENCY),GetLatency());
// while(z && *z) z++;
// wsprintf(z,"Data written: %u KB",MulDiv((int)total_written,(fmt_bps>>3)*fmt_nch,1024));
}
SYNC_OUT;
return rv;
}
void WaveOutConfig::SetError(const WCHAR * x)
{
error=(WCHAR*)LocalAlloc(LPTR,lstrlenW(x+1));
lstrcpyW(error,x);
}
void WaveOut::do_altvol_i(char * ptr,UINT max,UINT start,UINT d,int vol)
{
UINT p=start*(fmt_bps>>3);
while(p<max)
{
void * z=ptr+p;
switch(fmt_bps)
{
case 8:
*(BYTE*)z=0x80^(BYTE)MulDiv(0x80^*(BYTE*)z,vol,255);
break;
case 16:
*(short*)z=(short)MulDiv(*(short*)z,vol,255);
break;
case 24:
{
long l=0;
memcpy(&l,z,3);
if (l&0x800000) l|=0xFF000000;
l=MulDiv(l,vol,255);
memcpy(z,&l,3);
}
break;
case 32:
*(long*)z=MulDiv(*(long*)z,vol,255);
break;
}
p+=d*(fmt_bps>>3);
}
}
void WaveOut::do_altvol(char * ptr,UINT s)
{
int mixvol=(myvol==-666) ? 255 : myvol;
int mixpan=(mypan==-666) ? 0 : mypan;
if (mixvol==255 && (fmt_nch!=2 || mixpan==0)) return;
if (fmt_nch==2)
{
int rv=mixvol,lv=mixvol;
if (mixpan<0)
{//-128..0
rv=MulDiv(rv,mixpan+128,128);
}
else if (mixpan>0)
{
lv=MulDiv(rv,128-mixpan,128);
}
do_altvol_i(ptr,s,0,2,lv);
do_altvol_i(ptr,s,1,2,rv);
}
else
{
do_altvol_i(ptr,s,0,1,mixvol);
}
}
bool WaveOut::IsClosed()
{
SYNC_IN;
bool rv=hWo ? 0 : 1;
SYNC_OUT;
return rv;
}

View File

@ -0,0 +1,125 @@
/*
simple waveout class.
usage:
create the object
write PCM data using WriteData(); WriteData() returns number of bytes successfully written; CanWrite() returns amout of bytes you can write at given point of time
ForcePlay after writing last data block to ensure that all your PCM data gets queued to waveout
wait for GetLatency() to become 0 to ensure that playback is finished
delete the object
*/
class WaveOutConfig
{
friend class WaveOut;
private:
UINT sr,nch,bps,buf_ms,dev,prebuf;
WCHAR* error;
void SetError(const WCHAR* x);
bool use_volume,use_altvol,resetvol;
public:
WaveOutConfig()
{
error=0;
sr=44100;
nch=2;
bps=16;
buf_ms=2000;
dev=0;
prebuf=200;
use_volume=1;
use_altvol=0;
resetvol=0;
}
void SetPCM(UINT _sr,UINT _nch,UINT _bps) {sr=_sr;nch=_nch;bps=_bps;}
void SetBuffer(UINT _buf,UINT _prebuf) {buf_ms=_buf;prebuf=_prebuf;}
void SetDevice(UINT d) {dev=d;}
void SetVolumeSetup(bool enabled,bool alt,bool _reset) {use_volume = enabled;use_altvol=alt;resetvol=_reset;}
~WaveOutConfig()
{
if (error) LocalFree(error);
}
//call these after attempting to create WaveOut
const WCHAR* GetError() {return error;}
};
class WaveOut{
public:
static WaveOut * Create(WaveOutConfig * cfg);
~WaveOut();
int WriteData(const void * ptr,UINT siz);
int GetLatency(void);
void Flush();
void SetVolume(int v);
void SetPan(int p);
void Pause(int s);
void ForcePlay();
int CanWrite();
int IsPaused() {return paused?1:0;}
UINT GetMaxLatency() {return MulDiv(buf_size,1000,fmt_mul);}
bool PrintState(char * z);
//for gapless mode
void SetCloseOnStop(bool b) {closeonstop=b;}
bool IsClosed();
private:
WaveOut();
typedef struct tagHEADER
{
tagHEADER * next;
WAVEHDR hdr;
} HEADER;
HEADER * hdr_alloc();
void hdr_free(HEADER * h);
static void hdr_free_list(HEADER * h);
HWAVEOUT hWo;
HANDLE hThread;
HANDLE hEvent;
CRITICAL_SECTION sync;
HEADER *hdrs,*hdrs_free;
UINT fmt_bps,fmt_nch,fmt_sr,fmt_mul,fmt_align;//,fmt_chan;
char * buffer;
UINT buf_size,buf_size_used;
UINT data_written,write_ptr;
UINT minblock,maxblock,avgblock;
DWORD last_time;
DWORD p_time;
UINT prebuf;
UINT n_playing;
UINT cur_block;
bool paused,needplay;
bool die;
bool use_volume,use_altvol,use_resetvol;
bool newpause;//,needflush;
bool closeonstop;
int myvol,mypan;
DWORD orgvol;
void killwaveout();
void flush();
void update_vol();
void advance_block();
void reset_shit();
void thread();
void init();
int open(WaveOutConfig * cfg);
void do_altvol(char * ptr,UINT s);
void do_altvol_i(char * ptr,UINT max,UINT start,UINT d,int vol);
static DWORD WINAPI ThreadProc(WaveOut * p);
};