-- v2: dmime: Implement IDirectMusicPerformance8_ClonePMsg. dmime: Cleanup IDirectMusicPerformance_SendPMsg. dmime: Cleanup IDirectMusicPerformance_FreePMsg. dmime: Cleanup IDirectMusicPerformance_AllocPMsg. dmime: Implement MusicToReferenceTime and ReferenceToMusicTime. dmime: Rewrite IDirectMusicPerformance8_GetTime.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 46 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index d277c5de043..5ae8941cd76 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -60,11 +60,12 @@ struct performance /** Message Processing */ HANDLE procThread; DWORD procThreadId; - REFERENCE_TIME procThreadStartTime; BOOL procThreadTicStarted; CRITICAL_SECTION safe; struct DMUS_PMSGItem *head; struct DMUS_PMSGItem *imm_head; + + IReferenceClock *master_clock; };
typedef struct DMUS_PMSGItem DMUS_PMSGItem; @@ -476,25 +477,21 @@ static HRESULT WINAPI performance_IsPlaying(IDirectMusicPerformance8 *iface, return S_FALSE; }
-static HRESULT WINAPI performance_GetTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *prtNow, MUSIC_TIME *pmtNow) +static HRESULT WINAPI performance_GetTime(IDirectMusicPerformance8 *iface, REFERENCE_TIME *time, MUSIC_TIME *music_time) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); - HRESULT hr = S_OK; - REFERENCE_TIME rtCur = 0; + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + REFERENCE_TIME now; + HRESULT hr;
- /*TRACE("(%p, %p, %p)\n", This, prtNow, pmtNow); */ - if (This->procThreadTicStarted) { - rtCur = ((REFERENCE_TIME) GetTickCount() * 10000) - This->procThreadStartTime; - } else { - /*return DMUS_E_NO_MASTER_CLOCK;*/ - } - if (NULL != prtNow) { - *prtNow = rtCur; - } - if (NULL != pmtNow) { - hr = IDirectMusicPerformance8_ReferenceToMusicTime(iface, rtCur, pmtNow); - } - return hr; + TRACE("(%p, %p, %p)\n", iface, time, music_time); + + if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK; + if (FAILED(hr = IReferenceClock_GetTime(This->master_clock, &now))) return hr; + + if (time) *time = now; + if (music_time) hr = IDirectMusicPerformance8_ReferenceToMusicTime(iface, now, music_time); + + return hr; }
static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULONG cb, DMUS_PMSG **ppPMSG) @@ -873,6 +870,11 @@ static HRESULT WINAPI performance_CloseDown(IDirectMusicPerformance8 *iface) This->procThreadTicStarted = FALSE; CloseHandle(This->procThread); } + if (This->master_clock) + { + IReferenceClock_Release(This->master_clock); + This->master_clock = NULL; + } if (This->dsound) { IDirectSound_Release(This->dsound); This->dsound = NULL; @@ -955,6 +957,9 @@ static HRESULT WINAPI performance_InitAudio(IDirectMusicPerformance8 *iface, IDi IDirectMusic8_AddRef(This->dmusic); }
+ if (FAILED(hr = IDirectMusic_GetMasterClock(This->dmusic, NULL, &This->master_clock))) + goto error; + if (!dsound || !*dsound) { hr = DirectSoundCreate8(NULL, (IDirectSound8 **)&This->dsound, NULL); if (FAILED(hr)) @@ -1006,6 +1011,11 @@ static HRESULT WINAPI performance_InitAudio(IDirectMusicPerformance8 *iface, IDi return S_OK;
error: + if (This->master_clock) + { + IReferenceClock_Release(This->master_clock); + This->master_clock = NULL; + } if (This->dsound) { IDirectSound_Release(This->dsound); This->dsound = NULL;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 40 ++++++++++++++++++++++++++++++++-------- dlls/dmime/tests/dmime.c | 28 ++++++++++++++-------------- 2 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 5ae8941cd76..7ce8ccb0d84 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -66,6 +66,7 @@ struct performance struct DMUS_PMSGItem *imm_head;
IReferenceClock *master_clock; + REFERENCE_TIME init_time; };
typedef struct DMUS_PMSGItem DMUS_PMSGItem; @@ -451,21 +452,41 @@ static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS }
static HRESULT WINAPI performance_MusicToReferenceTime(IDirectMusicPerformance8 *iface, - MUSIC_TIME mtTime, REFERENCE_TIME *prtTime) + MUSIC_TIME music_time, REFERENCE_TIME *time) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); + struct performance *This = impl_from_IDirectMusicPerformance8(iface);
- FIXME("(%p, %ld, %p): stub\n", This, mtTime, prtTime); - return S_OK; + FIXME("(%p, %ld, %p): semi-stub\n", This, music_time, time); + + if (!time) return E_POINTER; + *time = 0; + + if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK; + + /* FIXME: This should be (music_time * 60) / (DMUS_PPQ * tempo) + * but it gives innacurate results */ + *time = This->init_time + (music_time * 6510); + + return S_OK; }
static HRESULT WINAPI performance_ReferenceToMusicTime(IDirectMusicPerformance8 *iface, - REFERENCE_TIME rtTime, MUSIC_TIME *pmtTime) + REFERENCE_TIME time, MUSIC_TIME *music_time) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); + struct performance *This = impl_from_IDirectMusicPerformance8(iface);
- FIXME("(%p, 0x%s, %p): stub\n", This, wine_dbgstr_longlong(rtTime), pmtTime); - return S_OK; + FIXME("(%p, %I64d, %p): semi-stub\n", This, time, music_time); + + if (!music_time) return E_POINTER; + *music_time = 0; + + if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK; + + /* FIXME: This should be (time * DMUS_PPQ * tempo) / 60 + * but it gives innacurate results */ + *music_time = (time - This->init_time) / 6510; + + return S_OK; }
static HRESULT WINAPI performance_IsPlaying(IDirectMusicPerformance8 *iface, @@ -1006,6 +1027,9 @@ static HRESULT WINAPI performance_InitAudio(IDirectMusicPerformance8 *iface, IDi *dmusic = (IDirectMusic *)This->dmusic; IDirectMusic_AddRef(*dmusic); } + + if (FAILED(hr = IDirectMusicPerformance8_GetTime(iface, &This->init_time, NULL))) return hr; + PostMessageToProcessMsgThread(This, PROCESSMSG_START);
return S_OK; diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index e178960b18f..8999d5564db 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -1650,18 +1650,18 @@ static void test_performance_time(void)
hr = IDirectMusicPerformance_MusicToReferenceTime(performance, 0, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); time = 0xdeadbeef; hr = IDirectMusicPerformance_MusicToReferenceTime(performance, 0, &time); - todo_wine ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); - todo_wine ok(time == 0, "got %I64d\n", time); + ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); + ok(time == 0, "got %I64d\n", time);
hr = IDirectMusicPerformance_ReferenceToMusicTime(performance, 0, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); music_time = 0xdeadbeef; hr = IDirectMusicPerformance_ReferenceToMusicTime(performance, 0, &music_time); - todo_wine ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); - todo_wine ok(music_time == 0, "got %ld\n", music_time); + ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); + ok(music_time == 0, "got %ld\n", music_time);
dmusic = NULL; @@ -1684,38 +1684,38 @@ static void test_performance_time(void) time = 0xdeadbeef; hr = IDirectMusicPerformance_MusicToReferenceTime(performance, 1, &time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(time - init_time >= 6505, "got %I64d\n", time - init_time); + ok(time - init_time >= 6505, "got %I64d\n", time - init_time); ok(time - init_time <= 6515, "got %I64d\n", time - init_time); time = 0xdeadbeef; hr = IDirectMusicPerformance_MusicToReferenceTime(performance, 1000, &time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(time - init_time >= 1000 * 6505, "got %I64d\n", time - init_time); + ok(time - init_time >= 1000 * 6505, "got %I64d\n", time - init_time); ok(time - init_time <= 1000 * 6515, "got %I64d\n", time - init_time); time = 0xdeadbeef; hr = IDirectMusicPerformance_MusicToReferenceTime(performance, 2000, &time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(time - init_time >= 2000 * 6505, "got %I64d\n", time - init_time); + ok(time - init_time >= 2000 * 6505, "got %I64d\n", time - init_time); ok(time - init_time <= 2000 * 6515, "got %I64d\n", time - init_time);
music_time = 0xdeadbeef; hr = IDirectMusicPerformance_ReferenceToMusicTime(performance, init_time, &music_time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(music_time == 0, "got %ld\n", music_time); + ok(music_time == 0, "got %ld\n", music_time); music_time = 0xdeadbeef; hr = IDirectMusicPerformance_ReferenceToMusicTime(performance, init_time + 1000 * 6510, &music_time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(music_time == 1000, "got %ld\n", music_time); + ok(music_time == 1000, "got %ld\n", music_time); music_time = 0xdeadbeef; hr = IDirectMusicPerformance_ReferenceToMusicTime(performance, init_time + 2000 * 6510, &music_time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(music_time == 2000, "got %ld\n", music_time); + ok(music_time == 2000, "got %ld\n", music_time);
time = 0xdeadbeef; music_time = 0xdeadbeef; hr = IDirectMusicPerformance_GetTime(performance, &time, &music_time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(time - init_time <= 200 * 10000, "got %I64d\n", time - init_time); - todo_wine ok(music_time == (time - init_time) / 6510, "got %ld\n", music_time); + ok(time - init_time <= 200 * 10000, "got %I64d\n", time - init_time); + ok(music_time == (time - init_time) / 6510, "got %ld\n", music_time);
hr = IDirectMusicPerformance_CloseDown(performance);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 27 ++++++++++++--------------- dlls/dmime/tests/dmime.c | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 7ce8ccb0d84..7cf446d9816 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -81,7 +81,6 @@ struct DMUS_PMSGItem { };
#define DMUS_PMSGToItem(pMSG) ((DMUS_PMSGItem*) (((unsigned char*) pPMSG) - offsetof(DMUS_PMSGItem, pMsg))) -#define DMUS_ItemToPMSG(pItem) (&(pItem->pMsg)) #define DMUS_ItemRemoveFromQueue(This,pItem) \ {\ if (pItem->prev) pItem->prev->next = pItem->next;\ @@ -515,23 +514,21 @@ static HRESULT WINAPI performance_GetTime(IDirectMusicPerformance8 *iface, REFER return hr; }
-static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULONG cb, DMUS_PMSG **ppPMSG) +static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULONG size, DMUS_PMSG **msg) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); - DMUS_PMSGItem* pItem = NULL; + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + DMUS_PMSGItem *message;
- FIXME("(%p, %ld, %p): stub\n", This, cb, ppPMSG); + TRACE("(%p, %ld, %p)\n", This, size, msg);
- if (sizeof(DMUS_PMSG) > cb) { - return E_INVALIDARG; - } - if (NULL == ppPMSG) { - return E_POINTER; - } - if (!(pItem = calloc(1, cb - sizeof(DMUS_PMSG) + sizeof(DMUS_PMSGItem)))) return E_OUTOFMEMORY; - pItem->pMsg.dwSize = cb; - *ppPMSG = DMUS_ItemToPMSG(pItem); - return S_OK; + if (!msg) return E_POINTER; + if (size < sizeof(DMUS_PMSG)) return E_INVALIDARG; + + if (!(message = calloc(1, size - sizeof(DMUS_PMSG) + sizeof(DMUS_PMSGItem)))) return E_OUTOFMEMORY; + message->pMsg.dwSize = size; + *msg = &message->pMsg; + + return S_OK; }
static HRESULT WINAPI performance_FreePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *pPMSG) diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index 8999d5564db..5a1d5c9733e 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -1747,7 +1747,7 @@ static void test_performance_pmsg(void)
hr = IDirectMusicPerformance_AllocPMsg(performance, 0, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); hr = IDirectMusicPerformance_AllocPMsg(performance, sizeof(DMUS_PMSG) - 1, &msg); ok(hr == E_INVALIDARG, "got %#lx\n", hr);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 47 +++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 7cf446d9816..bcb7faa405e 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -80,7 +80,7 @@ struct DMUS_PMSGItem { DMUS_PMSG pMsg; };
-#define DMUS_PMSGToItem(pMSG) ((DMUS_PMSGItem*) (((unsigned char*) pPMSG) - offsetof(DMUS_PMSGItem, pMsg))) +#define DMUS_PMSGToItem(pMSG) ((DMUS_PMSGItem *)(((unsigned char *)pMSG) - offsetof(DMUS_PMSGItem, pMsg))) #define DMUS_ItemRemoveFromQueue(This,pItem) \ {\ if (pItem->prev) pItem->prev->next = pItem->next;\ @@ -531,37 +531,30 @@ static HRESULT WINAPI performance_AllocPMsg(IDirectMusicPerformance8 *iface, ULO return S_OK; }
-static HRESULT WINAPI performance_FreePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *pPMSG) +static HRESULT WINAPI performance_FreePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); - DMUS_PMSGItem* pItem = NULL; - - FIXME("(%p, %p): stub\n", This, pPMSG); - - if (NULL == pPMSG) { - return E_POINTER; - } - pItem = DMUS_PMSGToItem(pPMSG); - if (pItem->bInUse) { - /** prevent for freeing PMsg in queue (ie to be processed) */ - return DMUS_E_CANNOT_FREE; - } - /** now we can remove it safely */ - EnterCriticalSection(&This->safe); - DMUS_ItemRemoveFromQueue( This, pItem ); - LeaveCriticalSection(&This->safe); + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + DMUS_PMSGItem *message; + HRESULT hr;
- if (pPMSG->pTool) - IDirectMusicTool_Release(pPMSG->pTool); + TRACE("(%p, %p)\n", This, msg);
- if (pPMSG->pGraph) - IDirectMusicGraph_Release(pPMSG->pGraph); + if (!msg) return E_POINTER; + message = DMUS_PMSGToItem(msg);
- if (pPMSG->punkUser) - IUnknown_Release(pPMSG->punkUser); + EnterCriticalSection(&This->safe); + hr = message->bInUse ? DMUS_E_CANNOT_FREE : S_OK; + LeaveCriticalSection(&This->safe);
- free(pItem); - return S_OK; + if (SUCCEEDED(hr)) + { + if (msg->pTool) IDirectMusicTool_Release(msg->pTool); + if (msg->pGraph) IDirectMusicGraph_Release(msg->pGraph); + if (msg->punkUser) IUnknown_Release(msg->punkUser); + free(message); + } + + return hr; }
static HRESULT WINAPI performance_GetGraph(IDirectMusicPerformance8 *iface, IDirectMusicGraph **graph)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 99 +++++++++++++++++++++------------------- dlls/dmime/tests/dmime.c | 8 ++-- 2 files changed, 57 insertions(+), 50 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index bcb7faa405e..d08f72d8d1f 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -399,55 +399,62 @@ static HRESULT WINAPI performance_GetBumperLength(IDirectMusicPerformance8 *ifac return S_OK; }
-static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *pPMSG) +static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); - DMUS_PMSGItem* pItem = NULL; - DMUS_PMSGItem* it = NULL; - DMUS_PMSGItem* prev_it = NULL; - DMUS_PMSGItem** queue = NULL; + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + DMUS_PMSGItem *message; + DMUS_PMSGItem *it = NULL; + DMUS_PMSGItem *prev_it = NULL; + DMUS_PMSGItem **queue; + HRESULT hr;
- FIXME("(%p, %p): stub\n", This, pPMSG); - - if (NULL == pPMSG) { - return E_POINTER; - } - pItem = DMUS_PMSGToItem(pPMSG); - if (pItem->bInUse) { - return DMUS_E_ALREADY_SENT; - } - - /* TODO: Valid Flags */ - /* TODO: DMUS_PMSGF_MUSICTIME */ - pItem->rtItemTime = pPMSG->rtTime; - - if (pPMSG->dwFlags & DMUS_PMSGF_TOOL_IMMEDIATE) { - queue = &This->imm_head; - } else { - queue = &This->head; - } + FIXME("(%p, %p): semi-stub\n", This, msg);
- EnterCriticalSection(&This->safe); - for (it = *queue; NULL != it && it->rtItemTime < pItem->rtItemTime; it = it->next) { - prev_it = it; - } - if (NULL == prev_it) { - pItem->prev = NULL; - if (NULL != *queue) pItem->next = (*queue)->next; - /*assert( NULL == pItem->next->prev );*/ - if (NULL != pItem->next) pItem->next->prev = pItem; - *queue = pItem; - } else { - pItem->prev = prev_it; - pItem->next = prev_it->next; - prev_it->next = pItem; - if (NULL != pItem->next) pItem->next->prev = pItem; - } - LeaveCriticalSection(&This->safe); - - /** now in use, prevent from stupid Frees */ - pItem->bInUse = TRUE; - return S_OK; + if (!msg) return E_POINTER; + if (!This->dmusic) return DMUS_E_NO_MASTER_CLOCK; + if (!(msg->dwFlags & (DMUS_PMSGF_MUSICTIME | DMUS_PMSGF_REFTIME))) return E_INVALIDARG; + + if (msg->dwFlags & DMUS_PMSGF_TOOL_IMMEDIATE) queue = &This->imm_head; + else queue = &This->head; + + message = DMUS_PMSGToItem(msg); + + EnterCriticalSection(&This->safe); + + if (message->bInUse) + hr = DMUS_E_ALREADY_SENT; + else + { + /* TODO: Valid Flags */ + /* TODO: DMUS_PMSGF_MUSICTIME */ + message->rtItemTime = msg->rtTime; + + for (it = *queue; NULL != it && it->rtItemTime < message->rtItemTime; it = it->next) + prev_it = it; + + if (!prev_it) + { + message->prev = NULL; + if (*queue) message->next = (*queue)->next; + /*assert( NULL == message->next->prev );*/ + if (message->next) message->next->prev = message; + *queue = message; + } + else + { + message->prev = prev_it; + message->next = prev_it->next; + prev_it->next = message; + if (message->next) message->next->prev = message; + } + + message->bInUse = TRUE; + hr = S_OK; + } + + LeaveCriticalSection(&This->safe); + + return hr; }
static HRESULT WINAPI performance_MusicToReferenceTime(IDirectMusicPerformance8 *iface, diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index 5a1d5c9733e..f5d64498abb 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -1767,12 +1767,12 @@ static void test_performance_pmsg(void) hr = IDirectMusicPerformance_SendPMsg(performance, NULL); ok(hr == E_POINTER, "got %#lx\n", hr); hr = IDirectMusicPerformance_SendPMsg(performance, msg); - todo_wine ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); + ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr);
hr = IDirectMusicPerformance_FreePMsg(performance, NULL); ok(hr == E_POINTER, "got %#lx\n", hr); hr = IDirectMusicPerformance_FreePMsg(performance, msg); - todo_wine ok(hr == S_OK, "got %#lx\n", hr); + ok(hr == S_OK, "got %#lx\n", hr);
hr = IDirectMusicPerformance_Init(performance, NULL, 0, 0); @@ -1802,7 +1802,7 @@ static void test_performance_pmsg(void) ok(!msg->dwGroupID, "got %ld\n", msg->dwGroupID); ok(!msg->punkUser, "got %p\n", msg->punkUser); hr = IDirectMusicPerformance_SendPMsg(performance, msg); - todo_wine ok(hr == E_INVALIDARG, "got %#lx\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr);
hr = IDirectMusicPerformance8_ClonePMsg((IDirectMusicPerformance8 *)performance, msg, NULL); todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); @@ -1816,7 +1816,7 @@ static void test_performance_pmsg(void) msg->mtTime = 500; msg->dwFlags = DMUS_PMSGF_MUSICTIME; hr = IDirectMusicPerformance_SendPMsg(performance, msg); - todo_wine ok(hr == S_OK, "got %#lx\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicPerformance_SendPMsg(performance, msg); ok(hr == DMUS_E_ALREADY_SENT, "got %#lx\n", hr); hr = IDirectMusicPerformance_FreePMsg(performance, msg);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 19 ++++++++++++++----- dlls/dmime/tests/dmime.c | 9 ++++----- 2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index d08f72d8d1f..b3fd4851d45 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -1071,13 +1071,22 @@ static HRESULT WINAPI performance_StopEx(IDirectMusicPerformance8 *iface, IUnkno return S_OK; }
-static HRESULT WINAPI performance_ClonePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *pSourcePMSG, - DMUS_PMSG **ppCopyPMSG) +static HRESULT WINAPI performance_ClonePMsg(IDirectMusicPerformance8 *iface, DMUS_PMSG *msg, DMUS_PMSG **clone) { - struct performance *This = impl_from_IDirectMusicPerformance8(iface); + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + HRESULT hr;
- FIXME("(%p, %p, %p): stub\n", This, pSourcePMSG, ppCopyPMSG); - return S_OK; + TRACE("(%p, %p, %p)\n", This, msg, clone); + + if (!msg || !clone) return E_POINTER; + if (FAILED(hr = IDirectMusicPerformance8_AllocPMsg(iface, msg->dwSize, clone))) return hr; + + memcpy(*clone, msg, msg->dwSize); + if (msg->pTool) IDirectMusicTool_AddRef(msg->pTool); + if (msg->pGraph) IDirectMusicGraph_AddRef(msg->pGraph); + if (msg->punkUser) IUnknown_AddRef(msg->punkUser); + + return S_OK; }
static HRESULT WINAPI performance_CreateAudioPath(IDirectMusicPerformance8 *iface, diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index f5d64498abb..26efdd4c72f 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -1805,13 +1805,13 @@ static void test_performance_pmsg(void) ok(hr == E_INVALIDARG, "got %#lx\n", hr);
hr = IDirectMusicPerformance8_ClonePMsg((IDirectMusicPerformance8 *)performance, msg, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); hr = IDirectMusicPerformance8_ClonePMsg((IDirectMusicPerformance8 *)performance, NULL, &clone); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); clone = NULL; hr = IDirectMusicPerformance8_ClonePMsg((IDirectMusicPerformance8 *)performance, msg, &clone); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(clone != NULL, "got %p\n", clone); + ok(clone != NULL, "got %p\n", clone);
msg->mtTime = 500; msg->dwFlags = DMUS_PMSGF_MUSICTIME; @@ -1822,8 +1822,7 @@ static void test_performance_pmsg(void) hr = IDirectMusicPerformance_FreePMsg(performance, msg); ok(hr == DMUS_E_CANNOT_FREE, "got %#lx\n", hr);
- if (!clone) hr = S_OK; - else hr = IDirectMusicPerformance_FreePMsg(performance, clone); + hr = IDirectMusicPerformance_FreePMsg(performance, clone); ok(hr == S_OK, "got %#lx\n", hr);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=137381
Your paranoid android.
=== w7u_adm (32 bit report) ===
dmime: dmime.c:1925: Test failed: got 140
I forgot to mention that IDirectMusicPerformance is a high level API and needs to call down to lower level APIs. The temptation is to implement stuff directly in IDirectMusicPerformance as that is what applications call. But applications can and do mix and match IDirectMusicPerformance with lower level APIs.
Implementing the lower level graph makes testing it easier, otherwise the tests only pass on Windows and, for instance, we would not be able to use the tests to validate the messages that are passing through using tools.
The implementation in dmime: Implement MusicToReferenceTime and ReferenceToMusicTime. feels wrong:
- Magic value 6510
- DMUS_E_NO_MASTER_CLOCK as error if dmusic pointer is missing
This feels like that should call down to a lower level API and eventually to the SynthSink methods SampleToRefTime / RefTimeToSample. I don't see a path down there though. Maybe calculated based on values it gets from the port via IKsControl::KsProperty? http://doc.51windows.net/directx9_sdk/htm/ksproperty.htm%5C Or maybe by comparing the latency clock to the master clock? https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/clock-synch...
I don't think the performance has anything to do with the output port, they are quite independent, and messages may go to one port or another. I also don't see how these functions could involve the dmusic master clock in any way, but maybe DMUS_E_NO_MASTER_CLOCK is returned because native gets a pointer to dmusic master clock on Init, and checks it here as a hint of whether Init was called or not. I've done the same, so that we use the same master clock for performance time over the entire playback.
Instead, it looks like the magic value needs to involve DMUS_PPQ, as described in https://learn.microsoft.com/en-us/previous-versions/ms807045(v=msdn.10). It should also involve the current tempo, but I couldn't figure how to change it in a way that it has an effect on the music time. I'll leave the value hardcoded for now, as even the formula suggested in https://learn.microsoft.com/en-us/previous-versions/ms810782(v=msdn.10) gives inaccurate values (unless we use a weird default tempo float value) and that 6510 seems to be very accurately returned by native.
I've changed the trace to semi-stub until we can figure this out in a better way but I'd like to have them implemented already so that we can convert PMSG time in SendPMsg.
This merge request was approved by Michael Stefaniuc.
Yeah, that's fine. I just got confused by the different times and the Synth stuff I dealt with last.