From e5286cbe39f3ea841881117d5d6dc824ac4e6d98 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 4 Dec 2011 01:10:16 +0100 Subject: [PATCH] Update XAudio for pure C. --- audio/xaudio-c/xaudio-c.c | 162 +++++++++++++++++++ audio/xaudio-c/xaudio-c.cpp | 164 ------------------- audio/xaudio-c/{xaudio2.hpp => xaudio.h} | 195 +++++------------------ 3 files changed, 206 insertions(+), 315 deletions(-) create mode 100644 audio/xaudio-c/xaudio-c.c delete mode 100644 audio/xaudio-c/xaudio-c.cpp rename audio/xaudio-c/{xaudio2.hpp => xaudio.h} (64%) mode change 100755 => 100644 diff --git a/audio/xaudio-c/xaudio-c.c b/audio/xaudio-c/xaudio-c.c new file mode 100644 index 0000000000..e516b4ad7e --- /dev/null +++ b/audio/xaudio-c/xaudio-c.c @@ -0,0 +1,162 @@ +/* + Simple C interface for XAudio2 + Author: Hans-Kristian Arntzen + License: Public Domain +*/ + +#include "xaudio-c.h" +#include "xaudio.h" +#include + +#define MAX_BUFFERS 16 +#define MAX_BUFFERS_MASK (MAX_BUFFERS - 1) + +struct xaudio2 +{ + const IXAudio2VoiceCallbackVtbl *lpVtbl; + + uint8_t *buf; + IXAudio2 *pXAudio2; + IXAudio2MasteringVoice *pMasterVoice; + IXAudio2SourceVoice *pSourceVoice; + HANDLE hEvent; + + volatile long buffers; + unsigned bufsize; + unsigned bufptr; + unsigned write_buffer; +}; + +static void WINAPI voice_on_buffer_end(void *handle_, void *data) +{ + (void)data; + xaudio2_t *handle = handle_; + InterlockedDecrement(&handle->buffers); + SetEvent(handle->hEvent); +} + +static void WINAPI dummy_voidp(void *handle, void *data) { (void)handle; (void)data; } +static void WINAPI dummy_nil(void *handle) { (void)handle; } +static void WINAPI dummy_uint32(void *handle, UINT32 dummy) { (void)handle; (void)dummy; } +static void WINAPI dummy_voidp_hresult(void *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; } + +const struct IXAudio2VoiceCallbackVtbl voice_vtable = { + .OnBufferStart = dummy_voidp, + .OnBufferEnd = voice_on_buffer_end, + .OnLoopEnd = dummy_voidp, + .OnVoiceProcessingPassEnd = dummy_nil, + .OnVoiceProcessingPassStart = dummy_uint32, + .OnVoiceError = dummy_voidp_hresult, + .OnStreamEnd = dummy_nil, +}; + +xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, size_t size) +{ + xaudio2_t *handle = calloc(1, sizeof(*handle)); + if (!handle) + return NULL; + + handle->lpVtbl = &voice_vtable; + CoInitializeEx(0, COINIT_MULTITHREADED); + if (FAILED(XAudio2Create(&handle->pXAudio2))) + goto error; + if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2, + &handle->pMasterVoice, channels, samplerate, 0, 0, 0))) + goto error; + + WAVEFORMATEX wfx; + wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + wfx.nChannels = channels; + wfx.nSamplesPerSec = samplerate; + wfx.nBlockAlign = channels * sizeof(float); + wfx.wBitsPerSample = sizeof(float) * 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize = 0; + if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2, + &handle->pSourceVoice, &wfx, + XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, + (IXAudio2VoiceCallback*)handle, 0, 0))) + goto error; + + handle->hEvent = CreateEvent(0, FALSE, FALSE, 0); + if (!handle->hEvent) + goto error; + + IXAudio2SourceVoice_Start(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW); + + handle->bufsize = size / MAX_BUFFERS; + handle->buf = calloc(1, handle->bufsize * MAX_BUFFERS); + if (!handle->buf) + goto error; + + return handle; + +error: + xaudio2_free(handle); + return NULL; +} + +size_t xaudio2_write_avail(xaudio2_t *handle) +{ + return handle->bufsize * (MAX_BUFFERS - handle->buffers - 1); +} + +size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_) +{ + unsigned bytes = bytes_; + const uint8_t *buffer = buf; + while (bytes > 0) + { + unsigned need = min(bytes, handle->bufsize - handle->bufptr); + memcpy(handle->buf + handle->write_buffer * handle->bufsize + handle->bufptr, + buffer, need); + + handle->bufptr += need; + buffer += need; + bytes -= need; + + if (handle->bufptr == handle->bufsize) + { + while (handle->buffers == MAX_BUFFERS - 1) + WaitForSingleObject(handle->hEvent, INFINITE); + + XAUDIO2_BUFFER xa2buffer = {0}; + xa2buffer.AudioBytes = handle->bufsize; + xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize; + xa2buffer.pContext = 0; + if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(handle->pSourceVoice, &xa2buffer, NULL))) + return 0; + + InterlockedIncrement(&handle->buffers); + handle->bufptr = 0; + handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK; + } + } + + return bytes_; +} + +void xaudio2_free(xaudio2_t *handle) +{ + if (handle) + { + if (handle->pSourceVoice) + { + IXAudio2SourceVoice_Stop(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_DestroyVoice(handle->pSourceVoice); + } + + if (handle->pMasterVoice) + IXAudio2MasteringVoice_DestroyVoice(handle->pMasterVoice); + + if (handle->pXAudio2) + IXAudio2_Release(handle->pXAudio2); + + if (handle->hEvent) + CloseHandle(handle->hEvent); + + free(handle->buf); + free(handle); + } +} + diff --git a/audio/xaudio-c/xaudio-c.cpp b/audio/xaudio-c/xaudio-c.cpp deleted file mode 100644 index 7f2b22171e..0000000000 --- a/audio/xaudio-c/xaudio-c.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - Simple C interface for XAudio2 - Author: Hans-Kristian Arntzen - License: Public Domain -*/ - -#include "xaudio-c.h" -#include "xaudio2.hpp" -#include -#include - -struct xaudio2 : public IXAudio2VoiceCallback -{ - xaudio2(unsigned samplerate, unsigned channels, unsigned size) : - buf(0), pXAudio2(0), pMasterVoice(0), pSourceVoice(0), - buffers(0), bufptr(0) - { - CoInitializeEx(0, COINIT_MULTITHREADED); - if (FAILED(XAudio2Create(&pXAudio2, 0))) - throw -1; - if (FAILED(pXAudio2->CreateMasteringVoice( - &pMasterVoice, channels, samplerate, 0, 0, 0))) - throw -1; - - WAVEFORMATEX wfx; - wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - wfx.nChannels = channels; - wfx.nSamplesPerSec = samplerate; - wfx.nBlockAlign = channels * sizeof(float); - wfx.wBitsPerSample = sizeof(float) * 8; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - wfx.cbSize = 0; - if (FAILED(pXAudio2->CreateSourceVoice( - &pSourceVoice, &wfx, XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, this, 0, 0))) - throw -1; - - hEvent = CreateEvent(0, FALSE, FALSE, 0); - if (!hEvent) - throw -1; - - pSourceVoice->Start(0); - - bufsize = size / max_buffers; - buf = new uint8_t[bufsize * max_buffers]; - write_buffer = 0; - } - - virtual ~xaudio2() - { - if (pSourceVoice) - { - pSourceVoice->Stop(0); - pSourceVoice->DestroyVoice(); - } - - if (pMasterVoice) - pMasterVoice->DestroyVoice(); - - if (pXAudio2) - pXAudio2->Release(); - - if (hEvent) - CloseHandle(hEvent); - - if (buf) - delete[] buf; - } - - size_t write_avail() const - { - return bufsize * (max_buffers - buffers - 1); - } - - size_t write(const void *buffer_, size_t bytes_) - { - unsigned bytes = bytes_; - const uint8_t *buffer = reinterpret_cast(buffer_); - while (bytes > 0) - { - unsigned need = std::min(bytes, bufsize - bufptr); - memcpy(buf + write_buffer * bufsize + bufptr, - buffer, need); - - bufptr += need; - buffer += need; - bytes -= need; - - if (bufptr == bufsize) - { - WaitForSingleObject(hEvent, 0); // Clear out ready state. - while (buffers == max_buffers - 1) - WaitForSingleObject(hEvent, INFINITE); - - XAUDIO2_BUFFER xa2buffer = {0}; - xa2buffer.AudioBytes = bufsize; - xa2buffer.pAudioData = buf + write_buffer * bufsize; - xa2buffer.pContext = 0; - if (FAILED(pSourceVoice->SubmitSourceBuffer(&xa2buffer))) - return 0; - - InterlockedIncrement(&buffers); - bufptr = 0; - write_buffer = (write_buffer + 1) & (max_buffers_mask); - } - } - - return bytes_; - } - - enum { max_buffers = 16, max_buffers_mask = max_buffers - 1 }; - - STDMETHOD_(void, OnBufferStart) (void *) {} - STDMETHOD_(void, OnBufferEnd) (void *) - { - InterlockedDecrement(&buffers); - SetEvent(hEvent); - } - STDMETHOD_(void, OnLoopEnd) (void *) {} - STDMETHOD_(void, OnStreamEnd) () {} - STDMETHOD_(void, OnVoiceError) (void *, HRESULT) {} - STDMETHOD_(void, OnVoiceProcessingPassEnd) () {} - STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {} - - uint8_t *buf; - IXAudio2 *pXAudio2; - IXAudio2MasteringVoice *pMasterVoice; - IXAudio2SourceVoice *pSourceVoice; - HANDLE hEvent; - - volatile long buffers; - unsigned bufsize; - unsigned bufptr; - unsigned write_buffer; -}; - -xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, size_t size) -{ - xaudio2 *handle = 0; - try { - handle = new xaudio2(samplerate, channels, size); - } catch(...) { delete handle; return 0; } - - return handle; -} - -size_t xaudio2_write_avail(xaudio2_t *handle) -{ - try { - return handle->write_avail(); - } catch(...) { return 0; } -} - -size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes) -{ - try { - return handle->write(buf, bytes); - } catch(...) { return 0; } -} - -void xaudio2_free(xaudio2_t *handle) -{ - delete handle; -} - diff --git a/audio/xaudio-c/xaudio2.hpp b/audio/xaudio-c/xaudio.h old mode 100755 new mode 100644 similarity index 64% rename from audio/xaudio-c/xaudio2.hpp rename to audio/xaudio-c/xaudio.h index ae4b094e8c..c4c9f335d3 --- a/audio/xaudio-c/xaudio2.hpp +++ b/audio/xaudio-c/xaudio.h @@ -1,35 +1,33 @@ /* - xaudio2.hpp (2010-08-14) - author: OV2 + xaudio.h (2010-08-14) / (2011-12-04) + authors: OV2, Themaister */ +// Kinda stripped down. Only contains the bare essentials used in SSNES. + #ifndef XAUDIO2_MINGW_H #define XAUDIO2_MINGW_H #define WIN32_LEAN_AND_MEAN #include -#undef min -#undef max #include #include #include -// 64-bit GCC fix -#define GUID_EXT EXTERN_C -#define GUID_SECT - -#define DEFINE_GUID_X(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) #define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8) -#define X2DEFAULT(x) =x +#define X2DEFAULT(x) DEFINE_CLSID_X(XAudio2, e21a7345, eb21, 468e, be, 50, 80, 4d, b9, 7c, f7, 08); -DEFINE_CLSID_X(XAudio2_Debug, f7a76c21, 53d4, 46bb, ac, 53, 8b, 45, 9c, ae, 46, bd); DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); -DECLARE_INTERFACE(IXAudio2Voice); +#ifndef INTERFACE +#define INTERFACE void +#endif #define XAUDIO2_COMMIT_NOW 0 #define XAUDIO2_DEFAULT_CHANNELS 0 @@ -46,95 +44,33 @@ typedef enum XAUDIO2_DEVICE_ROLE DefaultCommunicationsDevice = 0x4, DefaultGameDevice = 0x8, GlobalDefaultDevice = 0xf, - InvalidDeviceRole = ~GlobalDefaultDevice + InvalidDeviceRole = ~GlobalDefaultDevice } XAUDIO2_DEVICE_ROLE; -typedef struct XAUDIO2_DEVICE_DETAILS -{ - WCHAR DeviceID[256]; - WCHAR DisplayName[256]; - XAUDIO2_DEVICE_ROLE Role; - WAVEFORMATEXTENSIBLE OutputFormat; -} XAUDIO2_DEVICE_DETAILS; - -typedef struct XAUDIO2_VOICE_DETAILS -{ - UINT32 CreationFlags; - UINT32 InputChannels; - UINT32 InputSampleRate; -} XAUDIO2_VOICE_DETAILS; - typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER { - Processor1 = 0x00000001, - Processor2 = 0x00000002, - Processor3 = 0x00000004, - Processor4 = 0x00000008, - Processor5 = 0x00000010, - Processor6 = 0x00000020, - Processor7 = 0x00000040, - Processor8 = 0x00000080, - Processor9 = 0x00000100, - Processor10 = 0x00000200, - Processor11 = 0x00000400, - Processor12 = 0x00000800, - Processor13 = 0x00001000, - Processor14 = 0x00002000, - Processor15 = 0x00004000, - Processor16 = 0x00008000, - Processor17 = 0x00010000, - Processor18 = 0x00020000, - Processor19 = 0x00040000, - Processor20 = 0x00080000, - Processor21 = 0x00100000, - Processor22 = 0x00200000, - Processor23 = 0x00400000, - Processor24 = 0x00800000, - Processor25 = 0x01000000, - Processor26 = 0x02000000, - Processor27 = 0x04000000, - Processor28 = 0x08000000, - Processor29 = 0x10000000, - Processor30 = 0x20000000, - Processor31 = 0x40000000, - Processor32 = 0x80000000, - XAUDIO2_ANY_PROCESSOR = 0xffffffff, - XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR + XAUDIO2_ANY_PROCESSOR = 0xffffffff, + XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR } XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR; -typedef struct XAUDIO2_VOICE_SENDS -{ - UINT32 OutputCount; - IXAudio2Voice** pOutputVoices; -} XAUDIO2_VOICE_SENDS; - -typedef struct XAUDIO2_EFFECT_DESCRIPTOR -{ - IUnknown* pEffect; - BOOL InitialState; - UINT32 OutputChannels; -} XAUDIO2_EFFECT_DESCRIPTOR; - -typedef struct XAUDIO2_EFFECT_CHAIN -{ - UINT32 EffectCount; - const XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors; -} XAUDIO2_EFFECT_CHAIN; - -typedef enum XAUDIO2_FILTER_TYPE -{ +typedef enum XAUDIO2_FILTER_TYPE { LowPassFilter, BandPassFilter, - HighPassFilter + HighPassFilter } XAUDIO2_FILTER_TYPE; -typedef struct XAUDIO2_FILTER_PARAMETERS -{ - XAUDIO2_FILTER_TYPE Type; - float Frequency; - float OneOverQ; - -} XAUDIO2_FILTER_PARAMETERS; +typedef struct XAUDIO2_DEVICE_DETAILS XAUDIO2_DEVICE_DETAILS; +typedef struct XAUDIO2_VOICE_DETAILS XAUDIO2_VOICE_DETAILS; +typedef struct XAUDIO2_VOICE_SENDS XAUDIO2_VOICE_SENDS; +typedef struct XAUDIO2_EFFECT_DESCRIPTOR XAUDIO2_EFFECT_DESCRIPTOR; +typedef struct XAUDIO2_EFFECT_CHAIN XAUDIO2_EFFECT_CHAIN; +typedef struct XAUDIO2_FILTER_PARAMETERS XAUDIO2_FILTER_PARAMETERS; +typedef struct XAUDIO2_BUFFER_WMA XAUDIO2_BUFFER_WMA; +typedef struct XAUDIO2_VOICE_STATE XAUDIO2_VOICE_STATE; +typedef struct XAUDIO2_PERFORMANCE_DATA XAUDIO2_PERFORMANCE_DATA; +typedef struct XAUDIO2_DEBUG_CONFIGURATION XAUDIO2_DEBUG_CONFIGURATION; +typedef struct IXAudio2EngineCallback IXAudio2EngineCallback; +typedef struct IXAudio2SubmixVoice IXAudio2SubmixVoice; typedef struct XAUDIO2_BUFFER { @@ -149,53 +85,6 @@ typedef struct XAUDIO2_BUFFER void *pContext; } XAUDIO2_BUFFER; -typedef struct XAUDIO2_BUFFER_WMA -{ - const UINT32* pDecodedPacketCumulativeBytes; - UINT32 PacketCount; -} XAUDIO2_BUFFER_WMA; - -typedef struct XAUDIO2_VOICE_STATE -{ - void *pCurrentBufferContext; - UINT32 BuffersQueued; - UINT64 SamplesPlayed; -} XAUDIO2_VOICE_STATE; - -typedef struct XAUDIO2_PERFORMANCE_DATA -{ - UINT64 AudioCyclesSinceLastQuery; - UINT64 TotalCyclesSinceLastQuery; - UINT32 MinimumCyclesPerQuantum; - UINT32 MaximumCyclesPerQuantum; - UINT32 MemoryUsageInBytes; - UINT32 CurrentLatencyInSamples; - UINT32 GlitchesSinceEngineStarted; - UINT32 ActiveSourceVoiceCount; - UINT32 TotalSourceVoiceCount; - UINT32 ActiveSubmixVoiceCount; - UINT32 TotalSubmixVoiceCount; - UINT32 ActiveXmaSourceVoices; - UINT32 ActiveXmaStreams; -} XAUDIO2_PERFORMANCE_DATA; - -typedef struct XAUDIO2_DEBUG_CONFIGURATION -{ - UINT32 TraceMask; - UINT32 BreakMask; - BOOL LogThreadID; - BOOL LogFileline; - BOOL LogFunctionName; - BOOL LogTiming; -} XAUDIO2_DEBUG_CONFIGURATION; - -DECLARE_INTERFACE(IXAudio2EngineCallback) -{ - STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE; - STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE; - STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE; -}; - DECLARE_INTERFACE(IXAudio2VoiceCallback) { STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE; @@ -245,17 +134,11 @@ DECLARE_INTERFACE(IXAudio2Voice) Declare_IXAudio2Voice_Methods(); }; - DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice) { Declare_IXAudio2Voice_Methods(); }; -DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice) -{ - Declare_IXAudio2Voice_Methods(); -}; - DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice) { Declare_IXAudio2Voice_Methods(); @@ -307,20 +190,30 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown) void *pReserved X2DEFAULT(NULL)) PURE; }; -static inline HRESULT XAudio2Create(IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0), - XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) +// C hooks. +#define IXAudio2_Initialize(THIS, a, b) (THIS)->lpVtbl->Initialize(THIS, a, b) +#define IXAudio2_Release(THIS) (THIS)->lpVtbl->Release(THIS) +#define IXAudio2_CreateSourceVoice(THIS, a, b, c, d, e, f, g) (THIS)->lpVtbl->CreateSourceVoice(THIS, a, b, c, d, e, f, g) +#define IXAudio2_CreateMasteringVoice(THIS, a, b, c, d, e, f) (THIS)->lpVtbl->CreateMasteringVoice(THIS, a, b, c, d, e, f) + +#define IXAudio2SourceVoice_Start(THIS, a, b) (THIS)->lpVtbl->Start(THIS, a, b) +#define IXAudio2SourceVoice_Stop(THIS, a, b) (THIS)->lpVtbl->Stop(THIS, a, b) +#define IXAudio2SourceVoice_SubmitSourceBuffer(THIS, a, b) (THIS)->lpVtbl->SubmitSourceBuffer(THIS, a, b) +#define IXAudio2SourceVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS) +#define IXAudio2MasteringVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS) + +static inline HRESULT XAudio2Create(IXAudio2 **ppXAudio2) { - IXAudio2* pXAudio2; - HRESULT hr = CoCreateInstance((Flags & XAUDIO2_DEBUG_ENGINE) ? CLSID_XAudio2_Debug : CLSID_XAudio2, - NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, reinterpret_cast(&pXAudio2)); + IXAudio2 *pXAudio2; + HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); if (SUCCEEDED(hr)) { - hr = pXAudio2->Initialize(Flags, XAudio2Processor); + hr = IXAudio2_Initialize(pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); if (SUCCEEDED(hr)) *ppXAudio2 = pXAudio2; else - pXAudio2->Release(); + IXAudio2_Release(pXAudio2); } return hr; }