[PATCH 2/3] xaudio2: Add stub implementation of AudioVolumeMeter

Andrew Eikum aeikum at codeweavers.com
Tue Sep 8 09:33:44 CDT 2015


---
 dlls/xaudio2_7/tests/xaudio2.c    |  35 +++++-
 dlls/xaudio2_7/xaudio_classes.idl |   7 ++
 dlls/xaudio2_7/xaudio_dll.c       | 245 ++++++++++++++++++++++++++++++++++++++
 dlls/xaudio2_8/xaudio2_8.spec     |   1 +
 dlls/xaudio2_8/xaudio_dll.c       |   8 ++
 include/Makefile.in               |   1 +
 include/xaudio2fx.idl             |  26 ++++
 7 files changed, 321 insertions(+), 2 deletions(-)
 create mode 100644 include/xaudio2fx.idl

diff --git a/dlls/xaudio2_7/tests/xaudio2.c b/dlls/xaudio2_7/tests/xaudio2.c
index 949a5cf..0538f80 100644
--- a/dlls/xaudio2_7/tests/xaudio2.c
+++ b/dlls/xaudio2_7/tests/xaudio2.c
@@ -23,11 +23,14 @@
 #include "wine/test.h"
 #include "initguid.h"
 #include "xaudio2.h"
+#include "xaudio2fx.h"
+#include "xapo.h"
 #include "mmsystem.h"
 
 static BOOL xaudio27;
 
 static HRESULT (WINAPI *pXAudio2Create)(IXAudio2 **, UINT32, XAUDIO2_PROCESSOR) = NULL;
+static HRESULT (WINAPI *pCreateAudioVolumeMeter)(IUnknown**) = NULL;
 
 #define XA2CALL_0(method) if(xaudio27) hr = IXAudio27_##method((IXAudio27*)xa); else hr = IXAudio2_##method(xa);
 #define XA2CALL_0V(method) if(xaudio27) IXAudio27_##method((IXAudio27*)xa); else IXAudio2_##method(xa);
@@ -165,9 +168,12 @@ static void test_simple_streaming(IXAudio2 *xa)
     HRESULT hr;
     IXAudio2MasteringVoice *master;
     IXAudio2SourceVoice *src, *src2;
+    IUnknown *vumeter;
     WAVEFORMATEX fmt;
     XAUDIO2_BUFFER buf, buf2;
     XAUDIO2_VOICE_STATE state;
+    XAUDIO2_EFFECT_DESCRIPTOR effect;
+    XAUDIO2_EFFECT_CHAIN chain;
 
     memset(&ecb_state, 0, sizeof(ecb_state));
     memset(&src1_state, 0, sizeof(src1_state));
@@ -190,6 +196,7 @@ static void test_simple_streaming(IXAudio2 *xa)
         hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
     ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);
 
+    /* create first source voice */
     fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
     fmt.nChannels = 2;
     fmt.nSamplesPerSec = 44100;
@@ -212,7 +219,7 @@ static void test_simple_streaming(IXAudio2 *xa)
     hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
     ok(hr == S_OK, "Start failed: %08x\n", hr);
 
-
+    /* create second source voice */
     XA2CALL(CreateSourceVoice, &src2, &fmt, 0, 1.f, &vcb2, NULL, NULL);
     ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);
 
@@ -230,6 +237,28 @@ static void test_simple_streaming(IXAudio2 *xa)
     XA2CALL_0(StartEngine);
     ok(hr == S_OK, "StartEngine failed: %08x\n", hr);
 
+    /* hook up volume meter */
+    if(xaudio27){
+        hr = CoCreateInstance(&CLSID_AudioVolumeMeter, NULL,
+                CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&vumeter);
+        ok(hr == S_OK, "CoCreateInstance(AudioVolumeMeter) failed: %08x\n", hr);
+    }else{
+        hr = pCreateAudioVolumeMeter(&vumeter);
+        ok(hr == S_OK, "CreateAudioVolumeMeter failed: %08x\n", hr);
+    }
+
+    effect.InitialState = TRUE;
+    effect.OutputChannels = 2;
+    effect.pEffect = vumeter;
+
+    chain.EffectCount = 1;
+    chain.pEffectDescriptors = &effect;
+
+    hr = IXAudio2MasteringVoice_SetEffectChain(master, &chain);
+    ok(hr == S_OK, "SetEffectchain failed: %08x\n", hr);
+
+    IUnknown_Release(vumeter);
+
     while(1){
         if(xaudio27)
             IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
@@ -471,8 +500,10 @@ START_TEST(xaudio2)
     CoInitialize(NULL);
 
     xa28dll = LoadLibraryA("xaudio2_8.dll");
-    if(xa28dll)
+    if(xa28dll){
         pXAudio2Create = (void*)GetProcAddress(xa28dll, "XAudio2Create");
+        pCreateAudioVolumeMeter = (void*)GetProcAddress(xa28dll, "CreateAudioVolumeMeter");
+    }
 
     /* XAudio 2.7 (Jun 2010 DirectX) */
     hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER,
diff --git a/dlls/xaudio2_7/xaudio_classes.idl b/dlls/xaudio2_7/xaudio_classes.idl
index 79bc7a4..a39d082 100644
--- a/dlls/xaudio2_7/xaudio_classes.idl
+++ b/dlls/xaudio2_7/xaudio_classes.idl
@@ -26,3 +26,10 @@
     uuid(5a508685-a254-4fba-9b82-9a24b00306af)
 ]
 coclass XAudio2 { interface IXAudio2; }
+
+[
+    helpstring("XAudio2 Volume Meter Class"),
+    threading(both),
+    uuid(cac1105f-619b-4d04-831a-44e1cbf12d57)
+]
+coclass AudioVolumeMeter { interface IUnknown; }
diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
index 453645b..7a5f45b 100644
--- a/dlls/xaudio2_7/xaudio_dll.c
+++ b/dlls/xaudio2_7/xaudio_dll.c
@@ -36,6 +36,8 @@
 
 #include "mmsystem.h"
 #include "xaudio2.h"
+#include "xaudio2fx.h"
+#include "xapo.h"
 #include "devpkey.h"
 #include "mmdeviceapi.h"
 #include "audioclient.h"
@@ -2231,6 +2233,208 @@ static const IXAudio27Vtbl XAudio27_Vtbl = {
     XA27_SetDebugConfiguration
 };
 
+typedef struct _VUMeterImpl {
+    IXAPO IXAPO_iface;
+    IXAPOParameters IXAPOParameters_iface;
+
+    LONG ref;
+} VUMeterImpl;
+
+static VUMeterImpl *VUMeterImpl_from_IXAPO(IXAPO *iface)
+{
+    return CONTAINING_RECORD(iface, VUMeterImpl, IXAPO_iface);
+}
+
+static VUMeterImpl *VUMeterImpl_from_IXAPOParameters(IXAPOParameters *iface)
+{
+    return CONTAINING_RECORD(iface, VUMeterImpl, IXAPOParameters_iface);
+}
+
+static HRESULT WINAPI VUMXAPO_QueryInterface(IXAPO *iface, REFIID riid,
+        void **ppvObject)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+
+    TRACE("%p, %s, %p\n", This, wine_dbgstr_guid(riid), ppvObject);
+
+    if(IsEqualGUID(riid, &IID_IUnknown) ||
+            IsEqualGUID(riid, &IID_IXAPO) ||
+            IsEqualGUID(riid, &IID_IXAPO27))
+        *ppvObject = &This->IXAPO_iface;
+    else if(IsEqualGUID(riid, &IID_IXAPOParameters))
+        *ppvObject = &This->IXAPOParameters_iface;
+    else
+        *ppvObject = NULL;
+
+    if(*ppvObject){
+        IUnknown_AddRef((IUnknown*)*ppvObject);
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI VUMXAPO_AddRef(IXAPO *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+    TRACE("(%p)->(): Refcount now %u\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI VUMXAPO_Release(IXAPO *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(): Refcount now %u\n", This, ref);
+
+    if(!ref)
+        HeapFree(GetProcessHeap(), 0, This);
+
+    return ref;
+}
+
+static HRESULT WINAPI VUMXAPO_GetRegistrationProperties(IXAPO *iface,
+    XAPO_REGISTRATION_PROPERTIES **props)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %p\n", This, props);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VUMXAPO_IsInputFormatSupported(IXAPO *iface,
+        const WAVEFORMATEX *output_fmt, const WAVEFORMATEX *input_fmt,
+        WAVEFORMATEX **supported_fmt)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %p, %p, %p\n", This, output_fmt, input_fmt, supported_fmt);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VUMXAPO_IsOutputFormatSupported(IXAPO *iface,
+        const WAVEFORMATEX *input_fmt, const WAVEFORMATEX *output_fmt,
+        WAVEFORMATEX **supported_fmt)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %p, %p, %p\n", This, input_fmt, output_fmt, supported_fmt);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VUMXAPO_Initialize(IXAPO *iface, const void *data,
+        UINT32 data_len)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %p, %u\n", This, data, data_len);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VUMXAPO_Reset(IXAPO *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p\n", This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI VUMXAPO_LockForProcess(IXAPO *iface,
+        UINT32 in_params_count,
+        const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS *in_params,
+        UINT32 out_params_count,
+        const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS *out_params)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %u, %p, %u, %p\n", This, in_params_count, in_params,
+            out_params_count, out_params);
+    return E_NOTIMPL;
+}
+
+static void WINAPI VUMXAPO_UnlockForProcess(IXAPO *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p\n", This);
+}
+
+static void WINAPI VUMXAPO_Process(IXAPO *iface, UINT32 in_params_count,
+        const XAPO_PROCESS_BUFFER_PARAMETERS *in_params,
+        UINT32 out_params_count,
+        const XAPO_PROCESS_BUFFER_PARAMETERS *out_params, BOOL enabled)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %u, %p, %u, %p, %u\n", This, in_params_count, in_params,
+            out_params_count, out_params, enabled);
+}
+
+static UINT32 WINAPI VUMXAPO_CalcInputFrames(IXAPO *iface, UINT32 output_frames)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %u\n", This, output_frames);
+    return 0;
+}
+
+static UINT32 WINAPI VUMXAPO_CalcOutputFrames(IXAPO *iface, UINT32 input_frames)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPO(iface);
+    TRACE("%p, %u\n", This, input_frames);
+    return 0;
+}
+
+static const IXAPOVtbl VUMXAPO_Vtbl = {
+    VUMXAPO_QueryInterface,
+    VUMXAPO_AddRef,
+    VUMXAPO_Release,
+    VUMXAPO_GetRegistrationProperties,
+    VUMXAPO_IsInputFormatSupported,
+    VUMXAPO_IsOutputFormatSupported,
+    VUMXAPO_Initialize,
+    VUMXAPO_Reset,
+    VUMXAPO_LockForProcess,
+    VUMXAPO_UnlockForProcess,
+    VUMXAPO_Process,
+    VUMXAPO_CalcInputFrames,
+    VUMXAPO_CalcOutputFrames
+};
+
+static HRESULT WINAPI VUMXAPOParams_QueryInterface(IXAPOParameters *iface,
+        REFIID riid, void **ppvObject)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPOParameters(iface);
+    return VUMXAPO_QueryInterface(&This->IXAPO_iface, riid, ppvObject);
+}
+
+static ULONG WINAPI VUMXAPOParams_AddRef(IXAPOParameters *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPOParameters(iface);
+    return VUMXAPO_AddRef(&This->IXAPO_iface);
+}
+
+static ULONG WINAPI VUMXAPOParams_Release(IXAPOParameters *iface)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPOParameters(iface);
+    return VUMXAPO_Release(&This->IXAPO_iface);
+}
+
+static void WINAPI VUMXAPOParams_SetParameters(IXAPOParameters *iface,
+        const void *params, UINT32 params_len)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPOParameters(iface);
+    TRACE("%p, %p, %u\n", This, params, params_len);
+}
+
+static void WINAPI VUMXAPOParams_GetParameters(IXAPOParameters *iface,
+        void *params, UINT32 params_len)
+{
+    VUMeterImpl *This = VUMeterImpl_from_IXAPOParameters(iface);
+    TRACE("%p, %p, %u\n", This, params, params_len);
+}
+
+static const IXAPOParametersVtbl VUMXAPOParameters_Vtbl = {
+    VUMXAPOParams_QueryInterface,
+    VUMXAPOParams_AddRef,
+    VUMXAPOParams_Release,
+    VUMXAPOParams_SetParameters,
+    VUMXAPOParams_GetParameters
+};
+
 static HRESULT WINAPI XAudio2CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
 {
     if(IsEqualGUID(riid, &IID_IUnknown)
@@ -2382,6 +2586,35 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p
     return hr;
 }
 
+static HRESULT WINAPI VUMeterCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
+        REFIID riid, void **ppobj)
+{
+    HRESULT hr;
+    VUMeterImpl *object;
+
+    TRACE("(static)->(%p,%s,%p)\n", pOuter, debugstr_guid(riid), ppobj);
+
+    *ppobj = NULL;
+
+    if(pOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+    if(!object)
+        return E_OUTOFMEMORY;
+
+    object->IXAPO_iface.lpVtbl = &VUMXAPO_Vtbl;
+    object->IXAPOParameters_iface.lpVtbl = &VUMXAPOParameters_Vtbl;
+
+    hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
+    if(FAILED(hr)){
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    return S_OK;
+}
+
 static HRESULT WINAPI XAudio2CF_LockServer(IClassFactory *iface, BOOL dolock)
 {
     FIXME("(static)->(%d): stub!\n", dolock);
@@ -2397,7 +2630,17 @@ static const IClassFactoryVtbl XAudio2CF_Vtbl =
     XAudio2CF_LockServer
 };
 
+static const IClassFactoryVtbl VUMeterCF_Vtbl =
+{
+    XAudio2CF_QueryInterface,
+    XAudio2CF_AddRef,
+    XAudio2CF_Release,
+    VUMeterCF_CreateInstance,
+    XAudio2CF_LockServer
+};
+
 static IClassFactory xaudio2_cf = { &XAudio2CF_Vtbl };
+static IClassFactory vumeter_cf = { &VUMeterCF_Vtbl };
 
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
 {
@@ -2407,6 +2650,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
 
     if(IsEqualGUID(rclsid, &CLSID_XAudio2)) {
         factory = &xaudio2_cf;
+    }else if(IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter)) {
+        factory = &vumeter_cf;
     }
     if(!factory) return CLASS_E_CLASSNOTAVAILABLE;
 
diff --git a/dlls/xaudio2_8/xaudio2_8.spec b/dlls/xaudio2_8/xaudio2_8.spec
index dd4fee1..3228d71 100644
--- a/dlls/xaudio2_8/xaudio2_8.spec
+++ b/dlls/xaudio2_8/xaudio2_8.spec
@@ -1 +1,2 @@
 @ stdcall XAudio2Create(ptr long long)
+@ stdcall CreateAudioVolumeMeter(ptr)
diff --git a/dlls/xaudio2_8/xaudio_dll.c b/dlls/xaudio2_8/xaudio_dll.c
index e5dfb9d..521cc29 100644
--- a/dlls/xaudio2_8/xaudio_dll.c
+++ b/dlls/xaudio2_8/xaudio_dll.c
@@ -26,6 +26,8 @@
 
 #include "initguid.h"
 #include "xaudio2.h"
+#include "xaudio2fx.h"
+#include "xapo.h"
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
@@ -71,3 +73,9 @@ HRESULT WINAPI XAudio2Create(IXAudio2 **ppxa2, UINT32 flags, XAUDIO2_PROCESSOR p
 
     return S_OK;
 }
+
+HRESULT WINAPI CreateAudioVolumeMeter(IUnknown **out)
+{
+    return CoCreateInstance(&CLSID_AudioVolumeMeter, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IUnknown, (void**)out);
+}
diff --git a/include/Makefile.in b/include/Makefile.in
index b123e2f..b3e48d0 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -147,6 +147,7 @@ PUBLIC_IDL_H_SRCS = \
 	wuapi.idl \
 	xapo.idl \
 	xaudio2.idl \
+	xaudio2fx.idl \
 	xmllite.idl
 
 IDL_TLB_SRCS = \
diff --git a/include/xaudio2fx.idl b/include/xaudio2fx.idl
new file mode 100644
index 0000000..8d74264
--- /dev/null
+++ b/include/xaudio2fx.idl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 Andrew Eikum
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "unknwn.idl";
+
+[
+    uuid(cac1105f-619b-4d04-831a-44e1cbf12d57)
+]
+coclass AudioVolumeMeter {
+    interface IUnknown;
+}
-- 
2.5.1





More information about the wine-patches mailing list