dmusic: Implement the master clock object.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Michael Stefaniuc <mstefani@winehq.org> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
89ecfe19ca
commit
6e3c9d6e49
|
@ -22,9 +22,132 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "dmusic_private.h"
|
#include "dmusic_private.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dmusic);
|
WINE_DEFAULT_DEBUG_CHANNEL(dmusic);
|
||||||
|
|
||||||
|
struct master_clock {
|
||||||
|
IReferenceClock IReferenceClock_iface;
|
||||||
|
LONG ref;
|
||||||
|
double freq;
|
||||||
|
REFERENCE_TIME last_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct master_clock *impl_from_IReferenceClock(IReferenceClock *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct master_clock, IReferenceClock_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI master_IReferenceClock_QueryInterface(IReferenceClock *iface, REFIID riid,
|
||||||
|
void **ret_iface)
|
||||||
|
{
|
||||||
|
TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(riid), ret_iface);
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IReferenceClock))
|
||||||
|
*ret_iface = iface;
|
||||||
|
else {
|
||||||
|
WARN("no interface for %s\n", debugstr_dmguid(riid));
|
||||||
|
*ret_iface = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IReferenceClock_AddRef(iface);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI master_IReferenceClock_AddRef(IReferenceClock *iface)
|
||||||
|
{
|
||||||
|
struct master_clock *This = impl_from_IReferenceClock(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref = %u\n", iface, ref);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI master_IReferenceClock_Release(IReferenceClock *iface)
|
||||||
|
{
|
||||||
|
struct master_clock *This = impl_from_IReferenceClock(iface);
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref = %u\n", iface, ref);
|
||||||
|
|
||||||
|
if (!ref)
|
||||||
|
heap_free(This);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI master_IReferenceClock_GetTime(IReferenceClock *iface,
|
||||||
|
REFERENCE_TIME *time)
|
||||||
|
{
|
||||||
|
struct master_clock *This = impl_from_IReferenceClock(iface);
|
||||||
|
LARGE_INTEGER counter;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", iface, time);
|
||||||
|
|
||||||
|
QueryPerformanceCounter(&counter);
|
||||||
|
*time = counter.QuadPart * This->freq;
|
||||||
|
hr = (*time == This->last_time) ? S_FALSE : S_OK;
|
||||||
|
This->last_time = *time;
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI master_IReferenceClock_AdviseTime(IReferenceClock *iface,
|
||||||
|
REFERENCE_TIME base, REFERENCE_TIME offset, HANDLE event, DWORD *cookie)
|
||||||
|
{
|
||||||
|
TRACE("(%p, %s, %s, %p, %p): method not implemented\n", iface, wine_dbgstr_longlong(base),
|
||||||
|
wine_dbgstr_longlong(offset), event, cookie);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI master_IReferenceClock_AdvisePeriodic(IReferenceClock *iface,
|
||||||
|
REFERENCE_TIME start, REFERENCE_TIME period, HANDLE semaphore, DWORD *cookie)
|
||||||
|
{
|
||||||
|
TRACE("(%p, %s, %s, %p, %p): method not implemented\n", iface, wine_dbgstr_longlong(start),
|
||||||
|
wine_dbgstr_longlong(period), semaphore, cookie);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI master_IReferenceClock_Unadvise(IReferenceClock *iface, DWORD cookie)
|
||||||
|
{
|
||||||
|
TRACE("(%p, %#x): method not implemented\n", iface, cookie);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IReferenceClockVtbl master_clock_vtbl = {
|
||||||
|
master_IReferenceClock_QueryInterface,
|
||||||
|
master_IReferenceClock_AddRef,
|
||||||
|
master_IReferenceClock_Release,
|
||||||
|
master_IReferenceClock_GetTime,
|
||||||
|
master_IReferenceClock_AdviseTime,
|
||||||
|
master_IReferenceClock_AdvisePeriodic,
|
||||||
|
master_IReferenceClock_Unadvise,
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT master_clock_create(IReferenceClock **clock)
|
||||||
|
{
|
||||||
|
struct master_clock *obj;
|
||||||
|
LARGE_INTEGER freq;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", clock);
|
||||||
|
|
||||||
|
if (!(obj = heap_alloc_zero(sizeof(*obj))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
obj->IReferenceClock_iface.lpVtbl = &master_clock_vtbl;
|
||||||
|
obj->ref = 1;
|
||||||
|
QueryPerformanceFrequency(&freq);
|
||||||
|
obj->freq = 10000000.0 / freq.QuadPart;
|
||||||
|
|
||||||
|
*clock = &obj->IReferenceClock_iface;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static inline IDirectMusic8Impl *impl_from_IDirectMusic8(IDirectMusic8 *iface)
|
static inline IDirectMusic8Impl *impl_from_IDirectMusic8(IDirectMusic8 *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, IDirectMusic8Impl, IDirectMusic8_iface);
|
return CONTAINING_RECORD(iface, IDirectMusic8Impl, IDirectMusic8_iface);
|
||||||
|
@ -483,7 +606,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPU
|
||||||
|
|
||||||
dmusic->IDirectMusic8_iface.lpVtbl = &DirectMusic8_Vtbl;
|
dmusic->IDirectMusic8_iface.lpVtbl = &DirectMusic8_Vtbl;
|
||||||
dmusic->ref = 1;
|
dmusic->ref = 1;
|
||||||
ret = DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock, (void **)&dmusic->master_clock, NULL);
|
ret = master_clock_create(&dmusic->master_clock);
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
HeapFree(GetProcessHeap(), 0, dmusic);
|
HeapFree(GetProcessHeap(), 0, dmusic);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -801,26 +801,26 @@ static void test_master_clock(void)
|
||||||
hr = IReferenceClock_GetTime(clock, &time1);
|
hr = IReferenceClock_GetTime(clock, &time1);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
time2 = counter.QuadPart * 10000000.0 / freq.QuadPart;
|
time2 = counter.QuadPart * 10000000.0 / freq.QuadPart;
|
||||||
todo_wine ok(abs(time1 - time2) < 20 * 10000, "Expected about %s, got %s.\n",
|
ok(abs(time1 - time2) < 20 * 10000, "Expected about %s, got %s.\n",
|
||||||
wine_dbgstr_longlong(time2), wine_dbgstr_longlong(time1));
|
wine_dbgstr_longlong(time2), wine_dbgstr_longlong(time1));
|
||||||
|
|
||||||
hr = IReferenceClock_GetTime(clock, &time2);
|
hr = IReferenceClock_GetTime(clock, &time2);
|
||||||
todo_wine ok(hr == (time2 == time1 ? S_FALSE : S_OK), "Got hr %#x.\n", hr);
|
ok(hr == (time2 == time1 ? S_FALSE : S_OK), "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
hr = IReferenceClock_GetTime(clock, &time2);
|
hr = IReferenceClock_GetTime(clock, &time2);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
todo_wine ok(time2 - time1 > 80 * 10000, "Expected about %s, but got %s.\n",
|
ok(time2 - time1 > 80 * 10000, "Expected about %s, but got %s.\n",
|
||||||
wine_dbgstr_longlong(time1 + 100 * 10000), wine_dbgstr_longlong(time2));
|
wine_dbgstr_longlong(time1 + 100 * 10000), wine_dbgstr_longlong(time2));
|
||||||
|
|
||||||
hr = IReferenceClock_AdviseTime(clock, 0, 0, NULL, &cookie);
|
hr = IReferenceClock_AdviseTime(clock, 0, 0, NULL, &cookie);
|
||||||
todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IReferenceClock_AdvisePeriodic(clock, 0, 0, NULL, &cookie);
|
hr = IReferenceClock_AdvisePeriodic(clock, 0, 0, NULL, &cookie);
|
||||||
todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IReferenceClock_Unadvise(clock, 0);
|
hr = IReferenceClock_Unadvise(clock, 0);
|
||||||
todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
IReferenceClock_Release(clock);
|
IReferenceClock_Release(clock);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue