Initial commit

This commit is contained in:
Benjamin Moir
2025-11-15 18:19:52 +10:00
commit 627c3c3a1e
15 changed files with 1461 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{cpp,hpp,c,h,inl}]
indent_style = space
indent_size = 4
cpp_indent_case_contents = true
cpp_indent_case_labels = false
cpp_indent_case_contents_when_block = true
cpp_indent_goto_labels = one_left
cpp_indent_preprocessor = one_left
cpp_space_pointer_reference_alignment = right
cpp_indent_lambda_braces_when_parameter = false
+1
View File
@@ -0,0 +1 @@
* text eol=lf
+3
View File
@@ -0,0 +1,3 @@
.cmake/
.vs/
artifacts/
+14
View File
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.20)
project(XboxAudio2 LANGUAGES CXX ASM_MASM)
file(GLOB_RECURSE XAUDIO_SOURCES CONFIGURE_DEPENDS "include/*.h" "source/*.cpp" "source/*.h" "source/*.asm")
add_library(XAudio2_9 SHARED ${XAUDIO_SOURCES})
target_include_directories(XAudio2_9 PRIVATE include)
find_package(FFMPEG REQUIRED)
target_include_directories(XAudio2_9 PRIVATE ${FFMPEG_INCLUDE_DIRS})
target_link_directories(XAudio2_9 PRIVATE ${FFMPEG_LIBRARY_DIRS})
target_link_libraries(XAudio2_9 PRIVATE ${FFMPEG_LIBRARIES})
find_package(wil CONFIG REQUIRED)
target_link_libraries(XAudio2_9 PRIVATE WIL::WIL)
+67
View File
@@ -0,0 +1,67 @@
{
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"hidden": true,
"displayName": "Default Config",
"generator": "Ninja",
"binaryDir": "${sourceDir}/.cmake/${presetName}",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"CMAKE_RUNTIME_OUTPUT_DIRECTORY": "${sourceDir}/artifacts/${presetName}"
}
},
{
"name": "Debug",
"displayName": "Debug",
"inherits": "default",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
},
{
"name": "Release",
"displayName": "Release",
"inherits": "default",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
},
{
"name": "MinSizeRel",
"displayName": "MinSizeRel",
"inherits": "default",
"cacheVariables": { "CMAKE_BUILD_TYPE": "MinSizeRel" }
},
{
"name": "RelWithDebInfo",
"displayName": "RelWithDebInfo",
"inherits": "default",
"cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" }
}
],
"buildPresets": [
{
"name": "Debug",
"configurePreset": "Debug"
},
{
"name": "Release",
"configurePreset": "Release"
},
{
"name": "MinSizeRel",
"configurePreset": "MinSizeRel"
},
{
"name": "RelWithDebInfo",
"configurePreset": "RelWithDebInfo"
}
]
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 XWine1
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include <memory>
extern "C"
{
#include <libavcodec/avcodec.h>
}
struct AVPacketDeleter
{
void operator()(AVPacket *packet) const
{
av_packet_free(&packet);
}
};
using unique_avpacket = std::unique_ptr<AVPacket, AVPacketDeleter>;
struct AVFrameDeleter
{
void operator()(AVFrame *frame) const
{
av_frame_free(&frame);
}
};
using unique_avframe = std::unique_ptr<AVFrame, AVFrameDeleter>;
struct AVCodecContextDeleter
{
void operator()(AVCodecContext *context) const
{
avcodec_free_context(&context);
}
};
using unique_avcodec_context = std::unique_ptr<AVCodecContext, AVCodecContextDeleter>;
+719
View File
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
.code
extern OrdinalProc1 : qword
extern OrdinalProc2 : qword
extern OrdinalProc3 : qword
extern OrdinalProc4 : qword
extern OrdinalProc5 : qword
extern OrdinalProc6 : qword
OrdinalThunk1 proc
jmp qword ptr [OrdinalProc1]
OrdinalThunk1 endp
OrdinalThunk2 proc
jmp qword ptr [OrdinalProc2]
OrdinalThunk2 endp
OrdinalThunk3 proc
jmp qword ptr [OrdinalProc3]
OrdinalThunk3 endp
OrdinalThunk4 proc
jmp qword ptr [OrdinalProc4]
OrdinalThunk4 endp
OrdinalThunk5 proc
jmp qword ptr [OrdinalProc5]
OrdinalThunk5 endp
OrdinalThunk6 proc
jmp qword ptr [OrdinalProc6]
OrdinalThunk6 endp
end
+83
View File
@@ -0,0 +1,83 @@
#include <Windows.h>
#include "xaudio2_impl.h"
#define ORDINAL_PROC(n) extern "C" void *OrdinalProc##n; void *OrdinalProc##n; __pragma(comment(linker, "/export:OrdinalThunk" #n ",@" #n ",NONAME"))
//
// Variant 1 (older ERA titles)
// 1: XAudio2Create
// 2: CreateAudioReverb
// 3: CreateAudioVolumeMeter
// 4: CreateFX
// 5: X3DAudioCalculate
// 6: X3DAudioInitialize
//
// Variant 2 (newer ERA titles)
// 1: CreateAudioReverb
// 2: CreateAudioVolumeMeter
// 3: CreateFX
// 4: CreateXAudio2Object
// 5: X3DAudioCalculate
// 6: X3DAudioInitialize
//
ORDINAL_PROC(1);
ORDINAL_PROC(2);
ORDINAL_PROC(3);
ORDINAL_PROC(4);
ORDINAL_PROC(5);
ORDINAL_PROC(6);
#pragma comment(linker, "/export:CreateXAudio2Object")
#pragma comment(linker, "/export:XAudio2Create=CreateXAudio2Object")
// We need to export everything because GetModuleHandle("XAudio2_9") may resolve to this DLL.
#define XAUDIO2_FORWARD(Name) __pragma(comment(linker, "/export:" #Name "=C:\\WINDOWS\\System32\\XAudio2_9." #Name))
#define XAUDIO2_FORWARD_ORDINAL(Name, Ordinal) __pragma(comment(linker, "/export:" #Name "=C:\\WINDOWS\\System32\\XAudio2_9." #Name ",@" #Ordinal))
XAUDIO2_FORWARD(CreateAudioReverb)
XAUDIO2_FORWARD(CreateAudioVolumeMeter)
XAUDIO2_FORWARD(CreateFX)
XAUDIO2_FORWARD(X3DAudioCalculate)
XAUDIO2_FORWARD(X3DAudioInitialize)
XAUDIO2_FORWARD_ORDINAL(CreateAudioReverbV2_8, 7)
XAUDIO2_FORWARD_ORDINAL(XAudio2CreateV2_9, 8)
XAUDIO2_FORWARD_ORDINAL(XAudio2CreateWithVersionInfo, 9)
XAUDIO2_FORWARD_ORDINAL(XAudio2CreateWithSharedContexts, 10)
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved)
{
if (fdwReason != DLL_PROCESS_ATTACH)
return TRUE;
// TODO: Dynamic check
#if 1
OrdinalProc1 = GetProcAddress(hinstDLL, "CreateAudioReverb");
OrdinalProc2 = GetProcAddress(hinstDLL, "CreateAudioVolumeMeter");
OrdinalProc3 = GetProcAddress(hinstDLL, "CreateFX");
OrdinalProc4 = GetProcAddress(hinstDLL, "CreateXAudio2Object");
OrdinalProc5 = GetProcAddress(hinstDLL, "X3DAudioCalculate");
OrdinalProc6 = GetProcAddress(hinstDLL, "X3DAudioInitialize");
#else
OrdinalProc1 = GetProcAddress(hinstDLL, "XAudio2Create");
OrdinalProc2 = GetProcAddress(hinstDLL, "CreateAudioReverb");
OrdinalProc3 = GetProcAddress(hinstDLL, "CreateAudioVolumeMeter");
OrdinalProc4 = GetProcAddress(hinstDLL, "CreateFX");
OrdinalProc5 = GetProcAddress(hinstDLL, "X3DAudioCalculate");
OrdinalProc6 = GetProcAddress(hinstDLL, "X3DAudioInitialize");
#endif
return TRUE;
}
HRESULT CreateXAudio2Object(
IXAudio2 **ppXAudio2,
UINT32 Flags,
XAUDIO2_PROCESSOR XAudio2Processor,
void *pSharedShapeContexts)
{
HRESULT hr;
Microsoft::WRL::ComPtr<IXAudio2> pXAudio2;
RETURN_IF_FAILED(hr = XAudio2Create(&pXAudio2, Flags, XAudio2Processor));
*ppXAudio2 = new CXAudio2(pXAudio2.Get());
return hr;
}
+114
View File
@@ -0,0 +1,114 @@
#pragma once
#include <xaudio2.h>
#include <xma2defs.h>
#include <wrl/client.h>
#include <wil/result_macros.h>
#include "xma_voice.h"
class CXAudio2 final : public IXAudio2
{
LONG m_RefCount;
Microsoft::WRL::ComPtr<IXAudio2> m_pXAudio2;
public:
CXAudio2(IXAudio2 *pXAudio2) :
m_RefCount(1),
m_pXAudio2(pXAudio2)
{
}
//
// IUnknown
//
HRESULT QueryInterface(REFIID riid, void **ppvObject) override
{
RETURN_HR_IF_NULL(E_POINTER, ppvObject);
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(IXAudio2))
{
AddRef();
*ppvObject = this;
RETURN_HR(S_OK);
}
*ppvObject = nullptr;
RETURN_HR(E_NOINTERFACE);
}
ULONG AddRef() override
{
return InterlockedIncrement(&m_RefCount);
}
ULONG Release() override
{
ULONG uCount = InterlockedDecrement(&m_RefCount);
if (uCount == 0)
delete this;
return uCount;
}
//
// IXAudio2
//
HRESULT RegisterForCallbacks(IXAudio2EngineCallback *pCallback) override
{
return m_pXAudio2->RegisterForCallbacks(pCallback);
}
void UnregisterForCallbacks(IXAudio2EngineCallback *pCallback) override
{
m_pXAudio2->UnregisterForCallbacks(pCallback);
}
HRESULT CreateSourceVoice(IXAudio2SourceVoice **ppSourceVoice, WAVEFORMATEX const *pSourceFormat, UINT32 Flags, float MaxFrequencyRatio, IXAudio2VoiceCallback *pCallback, XAUDIO2_VOICE_SENDS const *pSendList, XAUDIO2_EFFECT_CHAIN const *pEffectChain) override
{
if (pSourceFormat->wFormatTag == WAVE_FORMAT_XMA2)
return CXAudio2SourceVoiceXMA2::Create(ppSourceVoice, this, (XMA2WAVEFORMATEX const *)pSourceFormat, Flags, MaxFrequencyRatio, pCallback, pSendList, pEffectChain);
return m_pXAudio2->CreateSourceVoice(ppSourceVoice, pSourceFormat, Flags, MaxFrequencyRatio, pCallback, pSendList, pEffectChain);
}
HRESULT CreateSubmixVoice(IXAudio2SubmixVoice **ppSubmixVoice, UINT32 InputChannels, UINT32 InputSampleRate, UINT32 Flags, UINT32 ProcessingStage, XAUDIO2_VOICE_SENDS const *pSendList, XAUDIO2_EFFECT_CHAIN const *pEffectChain) override
{
return m_pXAudio2->CreateSubmixVoice(ppSubmixVoice, InputChannels, InputSampleRate, Flags, ProcessingStage, pSendList, pEffectChain);
}
HRESULT CreateMasteringVoice(IXAudio2MasteringVoice **ppMasteringVoice, UINT32 InputChannels, UINT32 InputSampleRate, UINT32 Flags, LPCWSTR szDeviceId, XAUDIO2_EFFECT_CHAIN const *pEffectChain, AUDIO_STREAM_CATEGORY StreamCategory) override
{
return m_pXAudio2->CreateMasteringVoice(ppMasteringVoice, InputChannels, InputSampleRate, Flags, szDeviceId, pEffectChain, StreamCategory);
}
HRESULT StartEngine() override
{
return m_pXAudio2->StartEngine();
}
void StopEngine() override
{
m_pXAudio2->StopEngine();
}
HRESULT CommitChanges(UINT32 OperationSet) override
{
return m_pXAudio2->CommitChanges(OperationSet);
}
void GetPerformanceData(XAUDIO2_PERFORMANCE_DATA *pPerfData) override
{
m_pXAudio2->GetPerformanceData(pPerfData);
}
void SetDebugConfiguration(XAUDIO2_DEBUG_CONFIGURATION const *pDebugConfiguration, void *pReserved)
{
m_pXAudio2->SetDebugConfiguration(pDebugConfiguration, pReserved);
}
};
extern "C" HRESULT WINAPI CreateXAudio2Object(
IXAudio2 **ppXAudio2,
UINT32 Flags,
XAUDIO2_PROCESSOR XAudio2Processor,
void *pSharedShapeContexts);
+154
View File
@@ -0,0 +1,154 @@
#include "xma_voice.h"
#include <vector>
static void av_log_callback(void *ptr, int level, char const *fmt, va_list args)
{
static char buffer[4096];
vsnprintf(buffer, sizeof(buffer), fmt, args);
OutputDebugStringA(buffer);
}
CXAudio2SourceVoiceXMA2::~CXAudio2SourceVoiceXMA2()
{
m_bDecodeStopRequest = TRUE;
WaitForSingleObject(m_hDecodeThread.get(), INFINITE);
m_pSource->DestroyVoice();
}
CXAudio2SourceVoiceXMA2::CXAudio2SourceVoiceXMA2(IXAudio2SourceVoice *pSource, XMA2WAVEFORMATEX const *pSourceFormat) :
m_pSource(pSource),
m_hDecodeThread(nullptr),
m_pAudioBuffers{}
{
#if 0
av_log_set_level(AV_LOG_DEBUG);
av_log_set_callback(av_log_callback);
#endif
m_pCodec = avcodec_find_decoder(AV_CODEC_ID_XMA2);
m_pContext = unique_avcodec_context(avcodec_alloc_context3(m_pCodec));
av_channel_layout_default(&m_pContext->ch_layout, pSourceFormat->wfx.nChannels);
m_pContext->sample_rate = pSourceFormat->wfx.nSamplesPerSec;
m_pContext->extradata_size = sizeof(*pSourceFormat) - sizeof(pSourceFormat->wfx);
m_pContext->extradata = (uint8_t *)av_malloc(m_pContext->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(m_pContext->extradata, &pSourceFormat->wfx + 1, m_pContext->extradata_size);
if (avcodec_open2(m_pContext.get(), nullptr, nullptr) < 0)
{
av_free(m_pContext->extradata);
MessageBoxW(nullptr, L"Failed to open XMA2 codec", __FUNCTIONW__, MB_OK);
}
}
HRESULT CXAudio2SourceVoiceXMA2::Create(IXAudio2SourceVoice **ppSourceVoice, IXAudio2 *pXAudio2, XMA2WAVEFORMATEX const *pSourceFormat, UINT32 Flags, float MaxFrequencyRatio, IXAudio2VoiceCallback *pCallback, XAUDIO2_VOICE_SENDS const *pSendList, XAUDIO2_EFFECT_CHAIN const *pEffectChain)
{
RETURN_HR_IF_NULL(E_POINTER, ppSourceVoice);
RETURN_HR_IF_NULL(E_INVALIDARG, pXAudio2);
RETURN_HR_IF_NULL(E_INVALIDARG, pSourceFormat);
HRESULT hr;
WORD nChannels = pSourceFormat->wfx.nChannels;
// TODO
WAVEFORMATEX DestFormat
{
WAVE_FORMAT_IEEE_FLOAT,
nChannels,
pSourceFormat->wfx.nSamplesPerSec,
pSourceFormat->wfx.nSamplesPerSec * (nChannels * 32 / 8),
nChannels * 32 / 8,
32,
0
};
IXAudio2SourceVoice *pSource;
RETURN_IF_FAILED(hr = pXAudio2->CreateSourceVoice(&pSource, &DestFormat, Flags, MaxFrequencyRatio, pCallback, pSendList, pEffectChain));
RETURN_IF_NULL_ALLOC(*ppSourceVoice = new(std::nothrow) CXAudio2SourceVoiceXMA2(pSource, pSourceFormat));
return hr;
}
struct DecodeThreadParams
{
CXAudio2SourceVoiceXMA2 *pSource;
XAUDIO2_BUFFER Buffer;
DecodeThreadParams(CXAudio2SourceVoiceXMA2 *pSource, XAUDIO2_BUFFER const *pBuffer) :
pSource(pSource),
Buffer(*pBuffer)
{
}
};
DWORD CXAudio2SourceVoiceXMA2::DecodeThreadProc(LPVOID lpParam)
{
auto params = *(DecodeThreadParams *)lpParam;
delete lpParam;
auto frame = unique_avframe(av_frame_alloc());
RETURN_IF_NULL_ALLOC(frame);
DWORD currentBufferIndex = 0;
std::vector<float> samples{};
while (!params.pSource->m_bDecodeStopRequest && avcodec_receive_frame(params.pSource->m_pContext.get(), frame.get()) >= 0)
{
samples.clear();
for (int i = 0; i < frame->nb_samples; i++)
{
for (int j = 0; j < frame->ch_layout.nb_channels; j++)
{
samples.push_back(((float *)frame->data[j])[i]);
}
}
for (XAUDIO2_VOICE_STATE state; params.pSource->m_pSource->GetState(&state), (!params.pSource->m_bDecodeStopRequest && state.BuffersQueued >= MAX_AUDIO_BUFFER_COUNT);)
{
// TODO: Surely there is a better way of doing this that I am not thinking of right now
Sleep(1);
}
// Copy the sample buffer
INT64 AudioBytes = samples.size() * sizeof(float);
memcpy(params.pSource->m_pAudioBuffers[currentBufferIndex], samples.data(), AudioBytes);
XAUDIO2_BUFFER Buffer
{
// Only pass Flags for the last chunk
AudioBytes <= XAUDIO2_MAX_BUFFER_BYTES ? params.Buffer.Flags : 0,
// Cannot pass more than XAUDIO2_MAX_BUFFER_BYTES
min(AudioBytes, XAUDIO2_MAX_BUFFER_BYTES),
params.pSource->m_pAudioBuffers[currentBufferIndex],
// TODO: Handle these
0, // pBuffer->PlayBegin,
min(AudioBytes, XAUDIO2_MAX_BUFFER_BYTES) / sizeof(float) / params.pSource->m_pContext->ch_layout.nb_channels, // pBuffer->PlayLength,
0, // pBuffer->LoopBegin,
0, // pBuffer->LoopLength,
0, // pBuffer->LoopCount,
params.Buffer.pContext,
};
currentBufferIndex++;
currentBufferIndex %= MAX_AUDIO_BUFFER_COUNT;
RETURN_IF_FAILED(params.pSource->m_pSource->SubmitSourceBuffer(&Buffer, nullptr));
}
RETURN_HR(S_OK);
}
HRESULT CXAudio2SourceVoiceXMA2::SubmitSourceBuffer(XAUDIO2_BUFFER const *pBuffer, XAUDIO2_BUFFER_WMA const *pBufferWMA)
{
auto packet = unique_avpacket(av_packet_alloc());
RETURN_IF_NULL_ALLOC(packet);
av_init_packet(packet.get());
packet->data = (uint8_t *)pBuffer->pAudioData;
packet->size = pBuffer->AudioBytes;
avcodec_send_packet(m_pContext.get(), packet.get());
DecodeThreadParams *params;
RETURN_IF_NULL_ALLOC(params = new(std::nothrow) DecodeThreadParams(this, pBuffer));
m_hDecodeThread = wil::unique_handle(CreateThread(nullptr, 0, &DecodeThreadProc, params, 0, nullptr));
RETURN_HR(S_OK);
}
+178
View File
@@ -0,0 +1,178 @@
#pragma once
#include <xaudio2.h>
#include <xma2defs.h>
#include <wrl/client.h>
#include <wil/result_macros.h>
#include <wil/win32_helpers.h>
extern "C"
{
#include <libavcodec/avcodec.h>
}
#include <avcodec_raii.h>
class CXAudio2SourceVoiceXMA2 final : public IXAudio2SourceVoice
{
static constexpr size_t AUDIO_BUFFER_SIZE = 256 * 8192;
static constexpr size_t MAX_AUDIO_BUFFER_COUNT = 3;
IXAudio2SourceVoice *m_pSource;
AVCodec const *m_pCodec;
unique_avcodec_context m_pContext;
wil::unique_handle m_hDecodeThread;
BOOL m_bDecodeStopRequest = FALSE;
BYTE m_pAudioBuffers[MAX_AUDIO_BUFFER_COUNT][AUDIO_BUFFER_SIZE];
~CXAudio2SourceVoiceXMA2();
CXAudio2SourceVoiceXMA2(IXAudio2SourceVoice *pSource, XMA2WAVEFORMATEX const *pSourceFormat);
static DWORD WINAPI DecodeThreadProc(LPVOID lpParam);
public:
static HRESULT Create(IXAudio2SourceVoice **ppSourceVoice, IXAudio2 *pXAudio2, XMA2WAVEFORMATEX const *pSourceFormat, UINT32 Flags, float MaxFrequencyRatio, IXAudio2VoiceCallback *pCallback, XAUDIO2_VOICE_SENDS const *pSendList, XAUDIO2_EFFECT_CHAIN const *pEffectChain);
//
// IXAudio2Voice
//
void GetVoiceDetails(XAUDIO2_VOICE_DETAILS *pVoiceDetails) override
{
m_pSource->GetVoiceDetails(pVoiceDetails);
}
HRESULT SetOutputVoices(XAUDIO2_VOICE_SENDS const *pSendList) override
{
return m_pSource->SetOutputVoices(pSendList);
}
HRESULT SetEffectChain(XAUDIO2_EFFECT_CHAIN const *pEffectChain) override
{
return m_pSource->SetEffectChain(pEffectChain);
}
HRESULT EnableEffect(UINT32 EffectIndex, UINT32 OperationSet) override
{
return m_pSource->EnableEffect(EffectIndex, OperationSet);
}
HRESULT DisableEffect(UINT32 EffectIndex, UINT32 OperationSet) override
{
return m_pSource->DisableEffect(EffectIndex, OperationSet);
}
void GetEffectState(UINT32 EffectIndex, BOOL *pEnabled) override
{
m_pSource->GetEffectState(EffectIndex, pEnabled);
}
HRESULT SetEffectParameters(UINT32 EffectIndex, void const *pParameters, UINT32 ParametersByteSize, UINT32 OperationSet) override
{
return m_pSource->SetEffectParameters(EffectIndex, pParameters, ParametersByteSize, OperationSet);
}
HRESULT GetEffectParameters(UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize) override
{
return m_pSource->GetEffectParameters(EffectIndex, pParameters, ParametersByteSize);
}
HRESULT SetFilterParameters(XAUDIO2_FILTER_PARAMETERS const *pParameters, UINT32 OperationSet) override
{
return m_pSource->SetFilterParameters(pParameters, OperationSet);
}
void GetFilterParameters(XAUDIO2_FILTER_PARAMETERS *pParameters) override
{
return m_pSource->GetFilterParameters(pParameters);
}
HRESULT SetOutputFilterParameters(IXAudio2Voice *pDestinationVoice, XAUDIO2_FILTER_PARAMETERS const *pParameters, UINT32 OperationSet) override
{
return m_pSource->SetOutputFilterParameters(pDestinationVoice, pParameters, OperationSet);
}
void GetOutputFilterParameters(IXAudio2Voice *pDestinationVoice, XAUDIO2_FILTER_PARAMETERS *pParameters) override
{
m_pSource->GetOutputFilterParameters(pDestinationVoice, pParameters);
}
HRESULT SetVolume(float Volume, UINT32 OperationSet) override
{
return m_pSource->SetVolume(Volume, OperationSet);
}
void GetVolume(float *pVolume) override
{
m_pSource->GetVolume(pVolume);
}
HRESULT SetChannelVolumes(UINT32 Channels, float const *pVolumes, UINT32 OperationSet) override
{
return m_pSource->SetChannelVolumes(Channels, pVolumes, OperationSet);
}
void GetChannelVolumes(UINT32 Channels, float *pVolumes) override
{
m_pSource->GetChannelVolumes(Channels, pVolumes);
}
HRESULT SetOutputMatrix(IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, float const *pLevelMatrix, UINT32 OperationSet) override
{
return m_pSource->SetOutputMatrix(pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
}
void GetOutputMatrix(IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels, UINT32 DestinationChannels, float *pLevelMatrix) override
{
m_pSource->GetOutputMatrix(pDestinationVoice, SourceChannels, DestinationChannels, pLevelMatrix);
}
void DestroyVoice() override
{
delete this;
}
//
// IXAudio2SourceVoice
//
HRESULT Start(UINT32 Flags, UINT32 OperationSet) override
{
return m_pSource->Start(Flags, OperationSet);
}
HRESULT Stop(UINT32 Flags, UINT32 OperationSet) override
{
return m_pSource->Stop(Flags, OperationSet);
}
HRESULT SubmitSourceBuffer(XAUDIO2_BUFFER const *pBuffer, XAUDIO2_BUFFER_WMA const *pBufferWMA) override;
HRESULT FlushSourceBuffers() override
{
return m_pSource->FlushSourceBuffers();
}
HRESULT Discontinuity() override
{
return m_pSource->Discontinuity();
}
HRESULT ExitLoop(UINT32 OperationSet) override
{
return m_pSource->ExitLoop(OperationSet);
}
void GetState(XAUDIO2_VOICE_STATE *pVoiceState, UINT32 Flags) override
{
m_pSource->GetState(pVoiceState, Flags);
}
HRESULT SetFrequencyRatio(float Ratio, UINT32 OperationSet) override
{
return m_pSource->SetFrequencyRatio(Ratio, OperationSet);
}
void GetFrequencyRatio(float *pRatio) override
{
m_pSource->GetFrequencyRatio(pRatio);
}
HRESULT SetSourceSampleRate(UINT32 NewSourceSampleRate) override
{
return m_pSource->SetSourceSampleRate(NewSourceSampleRate);
}
};
+8
View File
@@ -0,0 +1,8 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json",
"default-registry": {
"kind": "git",
"baseline": "bb002e69deb36c00e9ce21810f69eff349a833f7",
"repository": "https://github.com/microsoft/vcpkg"
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"dependencies": [
"wil",
{
"name": "ffmpeg",
"default-features": false,
"features": ["avcodec"]
}
]
}