[PATCH v2 3/3] dmusic: Implement the master clock object.

Michael Stefaniuc mstefani at winehq.org
Sat Jun 15 10:09:24 CDT 2019


Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>


On 6/14/19 6:42 PM, Zebediah Figura wrote:
> Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
> ---
>  dlls/dmusic/dmusic.c       | 125 ++++++++++++++++++++++++++++++++++++-
>  dlls/dmusic/tests/dmusic.c |  12 ++--
>  2 files changed, 130 insertions(+), 7 deletions(-)
> 
> diff --git a/dlls/dmusic/dmusic.c b/dlls/dmusic/dmusic.c
> index a74a31e68bf..cc798ce4d92 100644
> --- a/dlls/dmusic/dmusic.c
> +++ b/dlls/dmusic/dmusic.c
> @@ -22,9 +22,132 @@
>  #include <stdio.h>
>  
>  #include "dmusic_private.h"
> +#include "wine/heap.h"
>  
>  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)
>  {
>      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->ref = 1;
> -    ret = DMUSIC_CreateReferenceClockImpl(&IID_IReferenceClock, (void **)&dmusic->master_clock, NULL);
> +    ret = master_clock_create(&dmusic->master_clock);
>      if (FAILED(ret)) {
>          HeapFree(GetProcessHeap(), 0, dmusic);
>          return ret;
> diff --git a/dlls/dmusic/tests/dmusic.c b/dlls/dmusic/tests/dmusic.c
> index d071e1cdef6..f6c417af306 100644
> --- a/dlls/dmusic/tests/dmusic.c
> +++ b/dlls/dmusic/tests/dmusic.c
> @@ -801,26 +801,26 @@ static void test_master_clock(void)
>      hr = IReferenceClock_GetTime(clock, &time1);
>      ok(hr == S_OK, "Got hr %#x.\n", hr);
>      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));
>  
>      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);
>      hr = IReferenceClock_GetTime(clock, &time2);
>      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));
>  
>      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);
> -    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);
> -    todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
> +    ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
>  
>      IReferenceClock_Release(clock);
>  
> 




More information about the wine-devel mailing list