wine-staging/patches/06-winepulse/0006-winepulse-Add-IAudioClock-and-IAudioClock2.patch
2013-12-06 21:09:21 +01:00

210 lines
6.1 KiB
Diff

From fa8bdbe20707458b7b43f9afc2d93adaadc833be Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Date: Fri, 22 Nov 2013 21:29:57 +0100
Subject: [PATCH 13/42] winepulse: Add IAudioClock and IAudioClock2
---
dlls/winepulse.drv/mmdevdrv.c | 172 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
index 01cfd25..3ed2288 100644
--- a/dlls/winepulse.drv/mmdevdrv.c
+++ b/dlls/winepulse.drv/mmdevdrv.c
@@ -167,6 +167,16 @@ static inline ACImpl *impl_from_IAudioCaptureClient(IAudioCaptureClient *iface)
return CONTAINING_RECORD(iface, ACImpl, IAudioCaptureClient_iface);
}
+static inline ACImpl *impl_from_IAudioClock(IAudioClock *iface)
+{
+ return CONTAINING_RECORD(iface, ACImpl, IAudioClock_iface);
+}
+
+static inline ACImpl *impl_from_IAudioClock2(IAudioClock2 *iface)
+{
+ return CONTAINING_RECORD(iface, ACImpl, IAudioClock2_iface);
+}
+
/* Following pulseaudio design here, mainloop has the lock taken whenever
* it is handling something for pulse, and the lock is required whenever
* doing any pa_* call that can affect the state in any way
@@ -1449,6 +1459,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
if (This->dataflow != eCapture)
return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
*ppv = &This->IAudioCaptureClient_iface;
+ } else if (IsEqualIID(riid, &IID_IAudioClock)) {
+ *ppv = &This->IAudioClock_iface;
}
if (*ppv) {
@@ -1750,6 +1762,166 @@ static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl =
AudioCaptureClient_GetNextPacketSize
};
+static HRESULT WINAPI AudioClock_QueryInterface(IAudioClock *iface,
+ REFIID riid, void **ppv)
+{
+ ACImpl *This = impl_from_IAudioClock(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->IAudioClock2_iface;
+ if (*ppv) {
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+ }
+
+ WARN("Unknown interface %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI AudioClock_AddRef(IAudioClock *iface)
+{
+ ACImpl *This = impl_from_IAudioClock(iface);
+ return IAudioClient_AddRef(&This->IAudioClient_iface);
+}
+
+static ULONG WINAPI AudioClock_Release(IAudioClock *iface)
+{
+ ACImpl *This = impl_from_IAudioClock(iface);
+ return IAudioClient_Release(&This->IAudioClient_iface);
+}
+
+static HRESULT WINAPI AudioClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
+{
+ ACImpl *This = impl_from_IAudioClock(iface);
+ HRESULT hr;
+
+ TRACE("(%p)->(%p)\n", This, freq);
+
+ pthread_mutex_lock(&pulse_lock);
+ hr = pulse_stream_valid(This);
+ if (SUCCEEDED(hr))
+ *freq = This->ss.rate * pa_frame_size(&This->ss);
+ pthread_mutex_unlock(&pulse_lock);
+ return hr;
+}
+
+static HRESULT WINAPI AudioClock_GetPosition(IAudioClock *iface, UINT64 *pos,
+ UINT64 *qpctime)
+{
+ ACImpl *This = impl_from_IAudioClock(iface);
+ pa_usec_t time;
+ HRESULT hr;
+
+ TRACE("(%p)->(%p, %p)\n", This, pos, qpctime);
+
+ if (!pos)
+ return E_POINTER;
+
+ pthread_mutex_lock(&pulse_lock);
+ hr = pulse_stream_valid(This);
+ if (FAILED(hr)) {
+ pthread_mutex_unlock(&pulse_lock);
+ return hr;
+ }
+
+ *pos = This->clock_written;
+ if (This->clock_pulse != PA_USEC_INVALID && pa_stream_get_time(This->stream, &time) >= 0) {
+ UINT32 delta = pa_usec_to_bytes(time - This->clock_pulse, &This->ss);
+ if (delta < This->pad)
+ *pos += delta;
+ else
+ *pos += This->pad;
+ }
+
+ /* Make time never go backwards */
+ if (*pos < This->clock_lastpos)
+ *pos = This->clock_lastpos;
+ else
+ This->clock_lastpos = *pos;
+ pthread_mutex_unlock(&pulse_lock);
+
+ TRACE("%p Position: %u\n", This, (unsigned)*pos);
+
+ if (qpctime) {
+ LARGE_INTEGER stamp, freq;
+ QueryPerformanceCounter(&stamp);
+ QueryPerformanceFrequency(&freq);
+ *qpctime = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI AudioClock_GetCharacteristics(IAudioClock *iface,
+ DWORD *chars)
+{
+ ACImpl *This = impl_from_IAudioClock(iface);
+
+ TRACE("(%p)->(%p)\n", This, chars);
+
+ if (!chars)
+ return E_POINTER;
+
+ *chars = AUDIOCLOCK_CHARACTERISTIC_FIXED_FREQ;
+
+ return S_OK;
+}
+
+static const IAudioClockVtbl AudioClock_Vtbl =
+{
+ AudioClock_QueryInterface,
+ AudioClock_AddRef,
+ AudioClock_Release,
+ AudioClock_GetFrequency,
+ AudioClock_GetPosition,
+ AudioClock_GetCharacteristics
+};
+
+static HRESULT WINAPI AudioClock2_QueryInterface(IAudioClock2 *iface,
+ REFIID riid, void **ppv)
+{
+ ACImpl *This = impl_from_IAudioClock2(iface);
+ return IAudioClock_QueryInterface(&This->IAudioClock_iface, riid, ppv);
+}
+
+static ULONG WINAPI AudioClock2_AddRef(IAudioClock2 *iface)
+{
+ ACImpl *This = impl_from_IAudioClock2(iface);
+ return IAudioClient_AddRef(&This->IAudioClient_iface);
+}
+
+static ULONG WINAPI AudioClock2_Release(IAudioClock2 *iface)
+{
+ ACImpl *This = impl_from_IAudioClock2(iface);
+ return IAudioClient_Release(&This->IAudioClient_iface);
+}
+
+static HRESULT WINAPI AudioClock2_GetDevicePosition(IAudioClock2 *iface,
+ UINT64 *pos, UINT64 *qpctime)
+{
+ ACImpl *This = impl_from_IAudioClock2(iface);
+ HRESULT hr = AudioClock_GetPosition(&This->IAudioClock_iface, pos, qpctime);
+ if (SUCCEEDED(hr))
+ *pos /= pa_frame_size(&This->ss);
+ return hr;
+}
+
+static const IAudioClock2Vtbl AudioClock2_Vtbl =
+{
+ AudioClock2_QueryInterface,
+ AudioClock2_AddRef,
+ AudioClock2_Release,
+ AudioClock2_GetDevicePosition
+};
+
HRESULT WINAPI AUDDRV_GetAudioSessionManager(IMMDevice *device,
IAudioSessionManager2 **out)
{
--
1.8.4.4