From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 35 +++++++++++++++++++++++++++-------- dlls/dmime/tests/dmime.c | 26 +++++++++++++------------- 2 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index d277c5de043..67fcdfd2d67 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -65,6 +65,8 @@ struct performance CRITICAL_SECTION safe; struct DMUS_PMSGItem *head; struct DMUS_PMSGItem *imm_head; + + REFERENCE_TIME init_time; };
typedef struct DMUS_PMSGItem DMUS_PMSGItem; @@ -450,21 +452,35 @@ 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; + TRACE("(%p, %ld, %p)\n", This, music_time, time); + + if (!time) return E_POINTER; + *time = 0; + + if (!This->dmusic) return DMUS_E_NO_MASTER_CLOCK; + *time = This->init_time + 6510 * music_time; + + 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; + TRACE("(%p, %I64d, %p)\n", This, time, music_time); + + if (!music_time) return E_POINTER; + *music_time = 0; + + if (!This->dmusic) return DMUS_E_NO_MASTER_CLOCK; + *music_time = (time - This->init_time) / 6510; + + return S_OK; }
static HRESULT WINAPI performance_IsPlaying(IDirectMusicPerformance8 *iface, @@ -1001,6 +1017,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..6e7fef20d10 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(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 | 35 ++++++++++++++++++----------------- dlls/dmime/tests/dmime.c | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 67fcdfd2d67..b74d3f47e7b 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -492,25 +492,26 @@ 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); + IReferenceClock *clock; + 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->dmusic) return DMUS_E_NO_MASTER_CLOCK; + if (SUCCEEDED(hr = IDirectMusic_GetMasterClock(This->dmusic, NULL, &clock))) + { + hr = IReferenceClock_GetTime(clock, &now); + IReferenceClock_Release(clock); + } + + if (FAILED(hr)) 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) diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index 6e7fef20d10..8999d5564db 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -1714,7 +1714,7 @@ static void test_performance_time(void) 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); + ok(time - init_time <= 200 * 10000, "got %I64d\n", time - init_time); ok(music_time == (time - init_time) / 6510, "got %ld\n", music_time);
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 b74d3f47e7b..941c3be804a 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;\ @@ -514,23 +513,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 941c3be804a..d4f5d41dfc0 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;\ @@ -530,37 +530,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 d4f5d41dfc0..85031f1f840 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 85031f1f840..3ad10e8bf13 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -1057,13 +1057,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);
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.
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'm fine to have this go in as is but the magic value "6510" needs at least a comment on were that comes from.