[PATCH 14/16] mmdevapi: Add support for the clock interface
Maarten Lankhorst
m.b.lankhorst at gmail.com
Sun Apr 11 03:07:34 CDT 2010
---
dlls/mmdevapi/audio.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 165 insertions(+), 0 deletions(-)
diff --git a/dlls/mmdevapi/audio.c b/dlls/mmdevapi/audio.c
index a693574..34f4bcd 100644
--- a/dlls/mmdevapi/audio.c
+++ b/dlls/mmdevapi/audio.c
@@ -77,6 +77,7 @@ typedef struct ACImpl {
ACRender *render;
ACCapture *capture;
+ AClock *clock;
} ACImpl;
struct ACRender {
@@ -91,14 +92,25 @@ struct ACCapture {
ACImpl *parent;
};
+struct AClock {
+ const IAudioClockVtbl *lpVtbl;
+ const IAudioClock2Vtbl *lp2Vtbl;
+ LONG ref;
+ ACImpl *parent;
+};
+
static const IAudioClientVtbl ACImpl_Vtbl;
static const IAudioRenderClientVtbl ACRender_Vtbl;
static const IAudioCaptureClientVtbl ACCapture_Vtbl;
+static const IAudioClockVtbl AClock_Vtbl;
+static const IAudioClock2Vtbl AClock2_Vtbl;
static HRESULT AudioRenderClient_Create(ACImpl *parent, ACRender **ppv);
static void AudioRenderClient_Destroy(ACRender *This);
static HRESULT AudioCaptureClient_Create(ACImpl *parent, ACCapture **ppv);
static void AudioCaptureClient_Destroy(ACCapture *This);
+static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv);
+static void AudioClock_Destroy(AClock *This);
static int get_format_PCM(WAVEFORMATEX *format)
{
@@ -277,6 +289,8 @@ static void AudioClient_Destroy(ACImpl *This)
AudioRenderClient_Destroy(This->render);
if (This->capture)
AudioCaptureClient_Destroy(This->capture);
+ if (This->clock)
+ AudioClock_Destroy(This->clock);
if (This->parent->flow == eRender && This->init) {
setALContext(This->parent->ctx);
IAudioClient_Stop((IAudioClient*)This);
@@ -846,6 +860,10 @@ static HRESULT WINAPI AC_GetService(IAudioClient *iface, REFIID riid, void **ppv
if (!This->capture)
hr = AudioCaptureClient_Create(This, &This->capture);
*ppv = This->capture;
+ } else if (IsEqualIID(riid, &IID_IAudioClock)) {
+ if (!This->clock)
+ hr = AudioClock_Create(This, &This->clock);
+ *ppv = This->clock;
}
if (FAILED(hr))
@@ -1212,5 +1230,152 @@ static const IAudioCaptureClientVtbl ACCapture_Vtbl =
ACC_GetNextPacketSize
};
+static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv)
+{
+ AClock *This;
+ This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ if (!This)
+ return E_OUTOFMEMORY;
+ This->lpVtbl = &AClock_Vtbl;
+ This->lp2Vtbl = &AClock2_Vtbl;
+ This->ref = 0;
+ This->parent = parent;
+ return S_OK;
+}
+
+static void AudioClock_Destroy(AClock *This)
+{
+ This->parent->clock = NULL;
+ HeapFree(GetProcessHeap(), 0, This);
+}
+
+static HRESULT WINAPI AClock_QueryInterface(IAudioClock *iface, REFIID riid, void **ppv)
+{
+ AClock *This = (AClock*)iface;
+ TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);
+
+ if (!ppv)
+ return E_POINTER;
+ *ppv = NULL;
+ if (IsEqualIID(riid, &IID_IUnknown)
+ || IsEqualIID(riid, &IID_IAudioClock))
+ *ppv = iface;
+ else if (IsEqualIID(riid, &IID_IAudioClock2))
+ *ppv = &This->lp2Vtbl;
+ if (*ppv) {
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+ }
+ WARN("Unknown interface %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI AClock_AddRef(IAudioClock *iface)
+{
+ AClock *This = (AClock*)iface;
+ ULONG ref;
+ ref = InterlockedIncrement(&This->ref);
+ TRACE("Refcount now %i\n", ref);
+ return ref;
+}
+
+static ULONG WINAPI AClock_Release(IAudioClock *iface)
+{
+ AClock *This = (AClock*)iface;
+ ULONG ref;
+ ref = InterlockedDecrement(&This->ref);
+ TRACE("Refcount now %i\n", ref);
+ if (!ref)
+ AudioClock_Destroy(This);
+ return ref;
+}
+
+static HRESULT WINAPI AClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
+{
+ AClock *This = (AClock*)iface;
+ TRACE("(%p)->(%p)\n", This, freq);
+
+ *freq = (UINT64)This->parent->pwfx->nSamplesPerSec;
+ return S_OK;
+}
+
+static HRESULT WINAPI AClock_GetPosition(IAudioClock *iface, UINT64 *pos, UINT64 *qpctime)
+{
+ AClock *This = (AClock*)iface;
+ DWORD pad;
+
+ TRACE("(%p)->(%p,%p)\n", This, pos, qpctime);
+
+ if (!pos)
+ return E_POINTER;
+
+ EnterCriticalSection(This->parent->crst);
+ AC_GetCurrentPadding((IAudioClient*)This->parent, &pad);
+ *pos = This->parent->frameswritten - pad;
+ if (qpctime)
+ *qpctime = gettime();
+ LeaveCriticalSection(This->parent->crst);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI AClock_GetCharacteristics(IAudioClock *iface, DWORD *chars)
+{
+ AClock *This = (AClock*)iface;
+ TRACE("(%p)->(%p)\n", This, chars);
+
+ if (!chars)
+ return E_POINTER;
+ *chars = AUDIOCLOCK_CHARACTERISTIC_FIXED_FREQ;
+ return S_OK;
+}
+
+static const IAudioClockVtbl AClock_Vtbl =
+{
+ AClock_QueryInterface,
+ AClock_AddRef,
+ AClock_Release,
+ AClock_GetFrequency,
+ AClock_GetPosition,
+ AClock_GetCharacteristics
+};
+
+static AClock *get_clock_from_clock2(IAudioClock2 *iface)
+{
+ return (AClock*)((char*)iface - offsetof(AClock,lp2Vtbl));
+}
+
+static HRESULT WINAPI AClock2_QueryInterface(IAudioClock2 *iface, REFIID riid, void **ppv)
+{
+ AClock *This = get_clock_from_clock2(iface);
+ return IUnknown_QueryInterface((IUnknown*)This, riid, ppv);
+}
+
+static ULONG WINAPI AClock2_AddRef(IAudioClock2 *iface)
+{
+ AClock *This = get_clock_from_clock2(iface);
+ return IUnknown_AddRef((IUnknown*)This);
+}
+
+static ULONG WINAPI AClock2_Release(IAudioClock2 *iface)
+{
+ AClock *This = get_clock_from_clock2(iface);
+ return IUnknown_Release((IUnknown*)This);
+}
+
+static HRESULT WINAPI AClock2_GetPosition(IAudioClock2 *iface, UINT64 *pos, UINT64 *qpctime)
+{
+ AClock *This = get_clock_from_clock2(iface);
+ return AClock_GetPosition((IAudioClock*)This, pos, qpctime);
+}
+
+static const IAudioClock2Vtbl AClock2_Vtbl =
+{
+ AClock2_QueryInterface,
+ AClock2_AddRef,
+ AClock2_Release,
+ AClock2_GetPosition
+};
+
#endif
--
1.7.0
--------------030009080303090600000709--
More information about the wine-patches
mailing list