Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

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

View file

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

View file

@ -0,0 +1,81 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_NULLSOFT_WASAPI "Nullsoft WASAPI Output v%s"
65535 "{CA8AD152-9760-4AA3-AC54-7464279C5D63}"
END
STRINGTABLE
BEGIN
IDS_NULLSOFT_WASAPI_OLD "Nullsoft WASAPI Output"
IDS_ABOUT_TEXT "%s\nWritten by Ben Allison\n© 2015-2023 Ben Allison\nBuild date: %s"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29424.173
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "out_wasapi", "out_wasapi.vcxproj", "{389AB984-6C9E-40FF-9556-51B80200AE89}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|Win32.ActiveCfg = Debug|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|Win32.Build.0 = Debug|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|Win32.ActiveCfg = Release|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|Win32.Build.0 = Release|Win32
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|x64.ActiveCfg = Debug|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Debug|x64.Build.0 = Debug|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|x64.ActiveCfg = Release|x64
{389AB984-6C9E-40FF-9556-51B80200AE89}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FD99919C-E1E8-4534-BAF6-4C7E97120250}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{389AB984-6C9E-40FF-9556-51B80200AE89}</ProjectGuid>
<RootNamespace>out_wasapi</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;OUT_WASAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="waveformat.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="out_wasapi.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

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

View file

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

View file

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,03,0,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", ""
VALUE "FileDescription", "Winamp Output Plug-in"
VALUE "FileVersion", "0,03,0,0"
VALUE "InternalName", "Nullsoft WASAPI Output"
VALUE "LegalCopyright", "Copyright © 2015-2023 Ben Allison"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "out_wasapi.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

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