2 * Copyright 2010 Maarten Lankhorst for Codeweavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define NONAMELESSUNION
28 #elif defined(HAVE_OPENAL_AL_H)
29 #include <OpenAL/al.h>
30 #include <OpenAL/alc.h>
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
41 #include "mmdeviceapi.h"
44 #include "audioclient.h"
45 #include "endpointvolume.h"
46 #include "audiopolicy.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
54 typedef struct ACRender ACRender;
55 typedef struct ACCapture ACCapture;
56 typedef struct ACSession ACSession;
57 typedef struct ASVolume ASVolume;
58 typedef struct AClock AClock;
60 typedef struct ACImpl {
61 const IAudioClientVtbl *lpVtbl;
65 CRITICAL_SECTION *crst;
69 static const IAudioClientVtbl ACImpl_Vtbl;
71 HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv)
73 ACImpl *This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
74 *ppv = (IAudioClient*)This;
77 This->crst = &parent->crst;
78 This->lpVtbl = &ACImpl_Vtbl;
80 This->parent = parent;
84 static void AudioClient_Destroy(ACImpl *This)
86 HeapFree(GetProcessHeap(), 0, This);
89 static HRESULT WINAPI AC_QueryInterface(IAudioClient *iface, REFIID riid, void **ppv)
91 TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);
96 if (IsEqualIID(riid, &IID_IUnknown)
97 || IsEqualIID(riid, &IID_IAudioClient))
100 IUnknown_AddRef((IUnknown*)*ppv);
103 WARN("Unknown interface %s\n", debugstr_guid(riid));
104 return E_NOINTERFACE;
107 static ULONG WINAPI AC_AddRef(IAudioClient *iface)
109 ACImpl *This = (ACImpl*)iface;
111 ref = InterlockedIncrement(&This->ref);
112 TRACE("Refcount now %i\n", ref);
116 static ULONG WINAPI AC_Release(IAudioClient *iface)
118 ACImpl *This = (ACImpl*)iface;
120 ref = InterlockedDecrement(&This->ref);
121 TRACE("Refcount now %i\n", ref);
123 AudioClient_Destroy(This);
127 static HRESULT WINAPI AC_Initialize(IAudioClient *iface, AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration, REFERENCE_TIME period, const WAVEFORMATEX *pwfx, const GUID *sessionguid)
129 ACImpl *This = (ACImpl*)iface;
131 TRACE("(%p)->(%x,%x,%u,%u,%p,%s)\n", This, mode, flags, (int)duration, (int)period, pwfx, debugstr_guid(sessionguid));
137 static HRESULT WINAPI AC_GetBufferSize(IAudioClient *iface, UINT32 *frames)
139 ACImpl *This = (ACImpl*)iface;
140 TRACE("(%p)->(%p)\n", This, frames);
142 return AUDCLNT_E_NOT_INITIALIZED;
150 static HRESULT WINAPI AC_GetStreamLatency(IAudioClient *iface, REFERENCE_TIME *latency)
152 ACImpl *This = (ACImpl*)iface;
153 TRACE("(%p)->(%p)\n", This, latency);
156 return AUDCLNT_E_NOT_INITIALIZED;
158 return IAudioClient_GetDevicePeriod(iface, latency, NULL);
161 static HRESULT WINAPI AC_GetCurrentPadding(IAudioClient *iface, UINT32 *numpad)
163 ACImpl *This = (ACImpl*)iface;
165 TRACE("(%p)->(%p)\n", This, numpad);
167 return AUDCLNT_E_NOT_INITIALIZED;
175 static HRESULT WINAPI AC_IsFormatSupported(IAudioClient *iface, AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *pwfx, WAVEFORMATEX **outpwfx)
177 ACImpl *This = (ACImpl*)iface;
178 TRACE("(%p)->(%x,%p,%p)\n", This, mode, pwfx, outpwfx);
182 if (mode == AUDCLNT_SHAREMODE_SHARED && !outpwfx)
184 if (mode != AUDCLNT_SHAREMODE_SHARED
185 && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) {
186 WARN("Unknown mode %x\n", mode);
189 if (pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE
190 && pwfx->wFormatTag != WAVE_FORMAT_PCM)
191 return AUDCLNT_E_UNSUPPORTED_FORMAT;
192 if (pwfx->nSamplesPerSec < 8000
193 || pwfx->nSamplesPerSec > 192000)
194 return AUDCLNT_E_UNSUPPORTED_FORMAT;
195 if (pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE
196 || !IsEqualIID(&((WAVEFORMATEXTENSIBLE*)pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
197 if (pwfx->wBitsPerSample > 16)
198 return AUDCLNT_E_UNSUPPORTED_FORMAT;
205 static HRESULT WINAPI AC_GetMixFormat(IAudioClient *iface, WAVEFORMATEX **pwfx)
207 ACImpl *This = (ACImpl*)iface;
209 TRACE("(%p)->(%p)\n", This, pwfx);
217 static HRESULT WINAPI AC_GetDevicePeriod(IAudioClient *iface, REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
219 ACImpl *This = (ACImpl*)iface;
221 TRACE("(%p)->(%p)\n", This, minperiod);
222 if (!defperiod && !minperiod)
229 static HRESULT WINAPI AC_Start(IAudioClient *iface)
231 ACImpl *This = (ACImpl*)iface;
233 TRACE("(%p)\n", This);
235 return AUDCLNT_E_NOT_INITIALIZED;
241 static HRESULT WINAPI AC_Stop(IAudioClient *iface)
243 ACImpl *This = (ACImpl*)iface;
244 TRACE("(%p)\n", This);
246 return AUDCLNT_E_NOT_INITIALIZED;
252 static HRESULT WINAPI AC_Reset(IAudioClient *iface)
254 ACImpl *This = (ACImpl*)iface;
255 TRACE("(%p)\n", This);
257 return AUDCLNT_E_NOT_INITIALIZED;
263 static HRESULT WINAPI AC_SetEventHandle(IAudioClient *iface, HANDLE handle)
265 ACImpl *This = (ACImpl*)iface;
266 TRACE("(%p)\n", This);
268 return AUDCLNT_E_NOT_INITIALIZED;
276 static HRESULT WINAPI AC_GetService(IAudioClient *iface, REFIID riid, void **ppv)
278 ACImpl *This = (ACImpl*)iface;
280 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
282 return AUDCLNT_E_NOT_INITIALIZED;
291 IUnknown_AddRef((IUnknown*)*ppv);
295 FIXME("stub %s\n", debugstr_guid(riid));
296 return E_NOINTERFACE;
299 static const IAudioClientVtbl ACImpl_Vtbl =
307 AC_GetCurrentPadding,
308 AC_IsFormatSupported,