[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