diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index a370fcf66d4..ef1b0ce9eef 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -8,6 +8,7 @@ EXTRALIBS = @FRAMEWORK_OPENAL@ C_SRCS = \ audio.c \ + audiovolume.c \ devenum.c \ main.c \ regsvr.c diff --git a/dlls/mmdevapi/audiovolume.c b/dlls/mmdevapi/audiovolume.c new file mode 100644 index 00000000000..61cbed488ca --- /dev/null +++ b/dlls/mmdevapi/audiovolume.c @@ -0,0 +1,297 @@ +/* + * Copyright 2010 Maarten Lankhorst for Codeweavers + * + * 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 + */ + + +#define NONAMELESSUNION +#define CINTERFACE +#define COBJMACROS +#include "config.h" + +#include +#ifdef HAVE_AL_AL_H +#include +#include +#elif defined(HAVE_OPENAL_AL_H) +#include +#include +#endif + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +#include "ole2.h" +#include "mmdeviceapi.h" +#include "dshow.h" +#include "dsound.h" +#include "audioclient.h" +#include "endpointvolume.h" +#include "audiopolicy.h" + +#include "mmdevapi.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + +#ifdef HAVE_OPENAL + +static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl; + +typedef struct AEVImpl { + const IAudioEndpointVolumeExVtbl *lpVtbl; + LONG ref; +} AEVImpl; + +HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolume **ppv) +{ + AEVImpl *This; + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); + *ppv = (IAudioEndpointVolume*)This; + if (!This) + return E_OUTOFMEMORY; + This->lpVtbl = &AEVImpl_Vtbl; + This->ref = 1; + return S_OK; +} + +static void AudioEndpointVolume_Destroy(AEVImpl *This) +{ + HeapFree(GetProcessHeap(), 0, This); +} + +static HRESULT WINAPI AEV_QueryInterface(IAudioEndpointVolumeEx *iface, REFIID riid, void **ppv) +{ + AEVImpl *This = (AEVImpl*)iface; + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv); + if (!ppv) + return E_POINTER; + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAudioEndpointVolume) || + IsEqualIID(riid, &IID_IAudioEndpointVolumeEx)) { + *ppv = This; + } + else + return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)*ppv); + return S_OK; +} + +static ULONG WINAPI AEV_AddRef(IAudioEndpointVolumeEx *iface) +{ + AEVImpl *This = (AEVImpl*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) new ref %u\n", This, ref); + return ref; +} + +static ULONG WINAPI AEV_Release(IAudioEndpointVolumeEx *iface) +{ + AEVImpl *This = (AEVImpl*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p) new ref %u\n", This, ref); + if (!ref) + AudioEndpointVolume_Destroy(This); + return ref; +} + +static HRESULT WINAPI AEV_RegisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify) +{ + TRACE("(%p)->(%p)\n", iface, notify); + if (!notify) + return E_POINTER; + FIXME("stub\n"); + return S_OK; +} + +static HRESULT WINAPI AEV_UnregisterControlChangeNotify(IAudioEndpointVolumeEx *iface, IAudioEndpointVolumeCallback *notify) +{ + TRACE("(%p)->(%p)\n", iface, notify); + if (!notify) + return E_POINTER; + FIXME("stub\n"); + return S_OK; +} + +static HRESULT WINAPI AEV_GetChannelCount(IAudioEndpointVolumeEx *iface, UINT *count) +{ + TRACE("(%p)->(%p)\n", iface, count); + if (!count) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_SetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float leveldb, const GUID *ctx) +{ + TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_SetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float level, const GUID *ctx) +{ + TRACE("(%p)->(%f,%s)\n", iface, level, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetMasterVolumeLevel(IAudioEndpointVolumeEx *iface, float *leveldb) +{ + TRACE("(%p)->(%p)\n", iface, leveldb); + if (!leveldb) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetMasterVolumeLevelScalar(IAudioEndpointVolumeEx *iface, float *level) +{ + TRACE("(%p)->(%p)\n", iface, level); + if (!level) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_SetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float leveldb, const GUID *ctx) +{ + TRACE("(%p)->(%f,%s)\n", iface, leveldb, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_SetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float level, const GUID *ctx) +{ + TRACE("(%p)->(%u,%f,%s)\n", iface, chan, level, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetChannelVolumeLevel(IAudioEndpointVolumeEx *iface, UINT chan, float *leveldb) +{ + TRACE("(%p)->(%u,%p)\n", iface, chan, leveldb); + if (!leveldb) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetChannelVolumeLevelScalar(IAudioEndpointVolumeEx *iface, UINT chan, float *level) +{ + TRACE("(%p)->(%u,%p)\n", iface, chan, level); + if (!level) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_SetMute(IAudioEndpointVolumeEx *iface, BOOL mute, const GUID *ctx) +{ + TRACE("(%p)->(%u,%s)\n", iface, mute, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetMute(IAudioEndpointVolumeEx *iface, BOOL *mute) +{ + TRACE("(%p)->(%p)\n", iface, mute); + if (!mute) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetVolumeStepInfo(IAudioEndpointVolumeEx *iface, UINT *stepsize, UINT *stepcount) +{ + TRACE("(%p)->(%p,%p)\n", iface, stepsize, stepcount); + if (!stepsize && !stepcount) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_VolumeStepUp(IAudioEndpointVolumeEx *iface, const GUID *ctx) +{ + TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_VolumeStepDown(IAudioEndpointVolumeEx *iface, const GUID *ctx) +{ + TRACE("(%p)->(%s)\n", iface, debugstr_guid(ctx)); + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_QueryHardwareSupport(IAudioEndpointVolumeEx *iface, DWORD *mask) +{ + TRACE("(%p)->(%p)\n", iface, mask); + if (!mask) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetVolumeRange(IAudioEndpointVolumeEx *iface, float *mindb, float *maxdb, float *inc) +{ + TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc); + if (!mindb || !maxdb || !inc) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI AEV_GetVolumeRangeChannel(IAudioEndpointVolumeEx *iface, UINT chan, float *mindb, float *maxdb, float *inc) +{ + TRACE("(%p)->(%p,%p,%p)\n", iface, mindb, maxdb, inc); + if (!mindb || !maxdb || !inc) + return E_POINTER; + FIXME("stub\n"); + return E_NOTIMPL; +} + +static const IAudioEndpointVolumeExVtbl AEVImpl_Vtbl = { + AEV_QueryInterface, + AEV_AddRef, + AEV_Release, + AEV_RegisterControlChangeNotify, + AEV_UnregisterControlChangeNotify, + AEV_GetChannelCount, + AEV_SetMasterVolumeLevel, + AEV_SetMasterVolumeLevelScalar, + AEV_GetMasterVolumeLevel, + AEV_GetMasterVolumeLevelScalar, + AEV_SetChannelVolumeLevel, + AEV_SetChannelVolumeLevelScalar, + AEV_GetChannelVolumeLevel, + AEV_GetChannelVolumeLevelScalar, + AEV_SetMute, + AEV_GetMute, + AEV_GetVolumeStepInfo, + AEV_VolumeStepUp, + AEV_VolumeStepDown, + AEV_QueryHardwareSupport, + AEV_GetVolumeRange, + AEV_GetVolumeRangeChannel +}; + +#endif diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 977f25a9e20..a5f49a6caea 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -270,29 +270,25 @@ static ULONG WINAPI MMDevice_Release(IMMDevice *iface) static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD clsctx, PROPVARIANT *params, void **ppv) { - MMDevice *This = (MMDevice *)iface; HRESULT hr = E_NOINTERFACE; + +#ifdef HAVE_OPENAL + MMDevice *This = (MMDevice *)iface; + TRACE("(%p)->(%p,%x,%p,%p)\n", iface, riid, clsctx, params, ppv); if (!ppv) return E_POINTER; - if (IsEqualIID(riid, &IID_IAudioClient)) + if (!openal_loaded) { -#ifdef HAVE_OPENAL - if (openal_loaded) - hr = AudioClient_Create(This, (IAudioClient**)ppv); - else -#endif - { - ERR("Trying to open a device with openal not available\n"); - hr = AUDCLNT_E_SERVICE_NOT_RUNNING; - } + WARN("OpenAL is still not loaded\n"); + hr = AUDCLNT_E_SERVICE_NOT_RUNNING; } + else if (IsEqualIID(riid, &IID_IAudioClient)) + hr = AudioClient_Create(This, (IAudioClient**)ppv); else if (IsEqualIID(riid, &IID_IAudioEndpointVolume)) - { - FIXME("IID_IAudioEndpointVolume unsupported\n"); - } + hr = AudioEndpointVolume_Create(This, (IAudioEndpointVolume**)ppv); else if (IsEqualIID(riid, &IID_IAudioSessionManager) || IsEqualIID(riid, &IID_IAudioSessionManager2)) { @@ -355,6 +351,10 @@ static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD cls } else ERR("Invalid/unknown iid %s\n", debugstr_guid(riid)); +#else + if (!ppv) return E_POINTER; + hr = AUDCLNT_E_SERVICE_NOT_RUNNING; +#endif if (FAILED(hr)) *ppv = NULL; diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h index 2cb93856175..afe7bba9401 100644 --- a/dlls/mmdevapi/mmdevapi.h +++ b/dlls/mmdevapi/mmdevapi.h @@ -41,6 +41,7 @@ typedef struct MMDevice { } MMDevice; extern HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv); +extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolume **ppv); #ifdef HAVE_OPENAL