mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 08:25:45 -04:00
Initial community commit
This commit is contained in:
1203
Src/Plugins/Output/out_disk/main.cpp
Normal file
1203
Src/Plugins/Output/out_disk/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
18
Src/Plugins/Output/out_disk/out_disk.h
Normal file
18
Src/Plugins/Output/out_disk/out_disk.h
Normal 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
|
184
Src/Plugins/Output/out_disk/out_disk.rc
Normal file
184
Src/Plugins/Output/out_disk/out_disk.rc
Normal 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
|
||||
|
30
Src/Plugins/Output/out_disk/out_disk.sln
Normal file
30
Src/Plugins/Output/out_disk/out_disk.sln
Normal 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
|
301
Src/Plugins/Output/out_disk/out_disk.vcxproj
Normal file
301
Src/Plugins/Output/out_disk/out_disk.vcxproj
Normal 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>
|
35
Src/Plugins/Output/out_disk/out_disk.vcxproj.filters
Normal file
35
Src/Plugins/Output/out_disk/out_disk.vcxproj.filters
Normal 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>
|
80
Src/Plugins/Output/out_disk/resource.h
Normal file
80
Src/Plugins/Output/out_disk/resource.h
Normal 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
|
39
Src/Plugins/Output/out_disk/version.rc2
Normal file
39
Src/Plugins/Output/out_disk/version.rc2
Normal 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
|
50
Src/Plugins/Output/out_ds/Config.cpp
Normal file
50
Src/Plugins/Output/out_ds/Config.cpp
Normal 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);}
|
70
Src/Plugins/Output/out_ds/Config.h
Normal file
70
Src/Plugins/Output/out_ds/Config.h
Normal 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
|
132
Src/Plugins/Output/out_ds/DevEnum.cpp
Normal file
132
Src/Plugins/Output/out_ds/DevEnum.cpp
Normal 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;
|
||||
}
|
67
Src/Plugins/Output/out_ds/DevEnum.h
Normal file
67
Src/Plugins/Output/out_ds/DevEnum.h
Normal 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
|
70
Src/Plugins/Output/out_ds/SoundBlock.cpp
Normal file
70
Src/Plugins/Output/out_ds/SoundBlock.cpp
Normal 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;
|
||||
}
|
21
Src/Plugins/Output/out_ds/SoundBlock.h
Normal file
21
Src/Plugins/Output/out_ds/SoundBlock.h
Normal 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
|
129
Src/Plugins/Output/out_ds/SoundBlockList.cpp
Normal file
129
Src/Plugins/Output/out_ds/SoundBlockList.cpp
Normal 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;
|
||||
}
|
32
Src/Plugins/Output/out_ds/SoundBlockList.h
Normal file
32
Src/Plugins/Output/out_ds/SoundBlockList.h
Normal 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
|
196
Src/Plugins/Output/out_ds/VolCtrl.cpp
Normal file
196
Src/Plugins/Output/out_ds/VolCtrl.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
44
Src/Plugins/Output/out_ds/VolCtrl.h
Normal file
44
Src/Plugins/Output/out_ds/VolCtrl.h
Normal 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
|
16
Src/Plugins/Output/out_ds/api.h
Normal file
16
Src/Plugins/Output/out_ds/api.h
Normal 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
|
798
Src/Plugins/Output/out_ds/cnv_ds2.cpp
Normal file
798
Src/Plugins/Output/out_ds/cnv_ds2.cpp
Normal 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;
|
||||
}
|
85
Src/Plugins/Output/out_ds/cnv_ds2.h
Normal file
85
Src/Plugins/Output/out_ds/cnv_ds2.h
Normal 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
|
1372
Src/Plugins/Output/out_ds/ds2.cpp
Normal file
1372
Src/Plugins/Output/out_ds/ds2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
237
Src/Plugins/Output/out_ds/ds2.h
Normal file
237
Src/Plugins/Output/out_ds/ds2.h
Normal 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
|
32
Src/Plugins/Output/out_ds/ds2_devenum.cpp
Normal file
32
Src/Plugins/Output/out_ds/ds2_devenum.cpp
Normal 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;
|
||||
}
|
4
Src/Plugins/Output/out_ds/ds2_misc.cpp
Normal file
4
Src/Plugins/Output/out_ds/ds2_misc.cpp
Normal 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));}
|
1
Src/Plugins/Output/out_ds/ds2_volctrl.cpp
Normal file
1
Src/Plugins/Output/out_ds/ds2_volctrl.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "ds2.h"
|
16
Src/Plugins/Output/out_ds/ds_ipc.h
Normal file
16
Src/Plugins/Output/out_ds/ds_ipc.h
Normal 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
|
14
Src/Plugins/Output/out_ds/ds_main.h
Normal file
14
Src/Plugins/Output/out_ds/ds_main.h
Normal 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
|
29
Src/Plugins/Output/out_ds/out_ds.h
Normal file
29
Src/Plugins/Output/out_ds/out_ds.h
Normal 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;
|
30
Src/Plugins/Output/out_ds/out_ds.sln
Normal file
30
Src/Plugins/Output/out_ds/out_ds.sln
Normal 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
|
304
Src/Plugins/Output/out_ds/out_ds.vcxproj
Normal file
304
Src/Plugins/Output/out_ds/out_ds.vcxproj
Normal 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>
|
89
Src/Plugins/Output/out_ds/out_ds.vcxproj.filters
Normal file
89
Src/Plugins/Output/out_ds/out_ds.vcxproj.filters
Normal 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>
|
101
Src/Plugins/Output/out_ds/out_ds_joy.cpp
Normal file
101
Src/Plugins/Output/out_ds/out_ds_joy.cpp
Normal 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;}
|
||||
}
|
||||
}
|
304
Src/Plugins/Output/out_ds/res_wa2/out_ds2.rc
Normal file
304
Src/Plugins/Output/out_ds/res_wa2/out_ds2.rc
Normal 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
|
||||
|
146
Src/Plugins/Output/out_ds/res_wa2/resource.h
Normal file
146
Src/Plugins/Output/out_ds/res_wa2/resource.h
Normal 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
|
39
Src/Plugins/Output/out_ds/res_wa2/version.rc2
Normal file
39
Src/Plugins/Output/out_ds/res_wa2/version.rc2
Normal 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
|
1005
Src/Plugins/Output/out_ds/wa2.cpp
Normal file
1005
Src/Plugins/Output/out_ds/wa2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1150
Src/Plugins/Output/out_ds/wa2_config.cpp
Normal file
1150
Src/Plugins/Output/out_ds/wa2_config.cpp
Normal file
File diff suppressed because it is too large
Load Diff
9
Src/Plugins/Output/out_wasapi/api.h
Normal file
9
Src/Plugins/Output/out_wasapi/api.h
Normal 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"
|
393
Src/Plugins/Output/out_wasapi/main.cpp
Normal file
393
Src/Plugins/Output/out_wasapi/main.cpp
Normal 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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
81
Src/Plugins/Output/out_wasapi/out_wasapi.rc
Normal file
81
Src/Plugins/Output/out_wasapi/out_wasapi.rc
Normal 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
|
||||
|
31
Src/Plugins/Output/out_wasapi/out_wasapi.sln
Normal file
31
Src/Plugins/Output/out_wasapi/out_wasapi.sln
Normal 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
|
250
Src/Plugins/Output/out_wasapi/out_wasapi.vcxproj
Normal file
250
Src/Plugins/Output/out_wasapi/out_wasapi.vcxproj
Normal 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>
|
32
Src/Plugins/Output/out_wasapi/out_wasapi.vcxproj.filters
Normal file
32
Src/Plugins/Output/out_wasapi/out_wasapi.vcxproj.filters
Normal 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>
|
18
Src/Plugins/Output/out_wasapi/resource.h
Normal file
18
Src/Plugins/Output/out_wasapi/resource.h
Normal 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
|
39
Src/Plugins/Output/out_wasapi/version.rc2
Normal file
39
Src/Plugins/Output/out_wasapi/version.rc2
Normal 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
|
69
Src/Plugins/Output/out_wasapi/waveformat.cpp
Normal file
69
Src/Plugins/Output/out_wasapi/waveformat.cpp
Normal 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;
|
||||
}
|
16
Src/Plugins/Output/out_wave/api.h
Normal file
16
Src/Plugins/Output/out_wave/api.h
Normal 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
|
248
Src/Plugins/Output/out_wave/cnv_pcmwaveout.cpp
Normal file
248
Src/Plugins/Output/out_wave/cnv_pcmwaveout.cpp
Normal 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);
|
||||
|
||||
|
||||
}
|
37
Src/Plugins/Output/out_wave/cnv_pcmwaveout.h
Normal file
37
Src/Plugins/Output/out_wave/cnv_pcmwaveout.h
Normal 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
|
576
Src/Plugins/Output/out_wave/out_wave.cpp
Normal file
576
Src/Plugins/Output/out_wave/out_wave.cpp
Normal 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;
|
||||
}
|
7
Src/Plugins/Output/out_wave/out_wave.h
Normal file
7
Src/Plugins/Output/out_wave/out_wave.h
Normal 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"
|
158
Src/Plugins/Output/out_wave/out_wave.rc
Normal file
158
Src/Plugins/Output/out_wave/out_wave.rc
Normal 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
|
||||
|
30
Src/Plugins/Output/out_wave/out_wave.sln
Normal file
30
Src/Plugins/Output/out_wave/out_wave.sln
Normal 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
|
284
Src/Plugins/Output/out_wave/out_wave.vcxproj
Normal file
284
Src/Plugins/Output/out_wave/out_wave.vcxproj
Normal 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>
|
44
Src/Plugins/Output/out_wave/out_wave.vcxproj.filters
Normal file
44
Src/Plugins/Output/out_wave/out_wave.vcxproj.filters
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<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>
|
60
Src/Plugins/Output/out_wave/resource.h
Normal file
60
Src/Plugins/Output/out_wave/resource.h
Normal 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
|
39
Src/Plugins/Output/out_wave/version.rc2
Normal file
39
Src/Plugins/Output/out_wave/version.rc2
Normal 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
|
267
Src/Plugins/Output/out_wave/wa2_config.cpp
Normal file
267
Src/Plugins/Output/out_wave/wa2_config.cpp
Normal 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);
|
||||
}
|
617
Src/Plugins/Output/out_wave/waveout.cpp
Normal file
617
Src/Plugins/Output/out_wave/waveout.cpp
Normal 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;
|
||||
}
|
125
Src/Plugins/Output/out_wave/waveout.h
Normal file
125
Src/Plugins/Output/out_wave/waveout.h
Normal 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);
|
||||
};
|
Reference in New Issue
Block a user