Will make it behave more like native for the tests, and avoid queueing every single message from every track on start (which may be large).
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/performance.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 83c2401c083..7ab11773314 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -88,6 +88,19 @@ static inline struct message *message_from_DMUS_PMSG(DMUS_PMSG *msg) return msg ? CONTAINING_RECORD(msg, struct message, msg) : NULL; }
+static void performance_queue_message(struct performance *This, struct message *message, struct list *hint) +{ + struct message *prev; + + LIST_FOR_EACH_ENTRY_REV(prev, hint ? hint : &This->messages, struct message, entry) + { + if (&prev->entry == &This->messages) break; + if (prev->msg.rtTime <= message->msg.rtTime) break; + } + + list_add_after(&prev->entry, &message->entry); +} + static HRESULT performance_process_message(struct performance *This, DMUS_PMSG *msg, DWORD *timeout) { static const DWORD delivery_flags = DMUS_PMSGF_TOOL_IMMEDIATE | DMUS_PMSGF_TOOL_QUEUE | DMUS_PMSGF_TOOL_ATTIME; @@ -133,8 +146,8 @@ static HRESULT performance_process_message(struct performance *This, DMUS_PMSG * static DWORD WINAPI message_thread_proc(void *args) { struct performance *This = args; - struct message *message, *next; - HRESULT hr; + HRESULT hr = DMUS_S_REQUEUE; + struct list *ptr;
TRACE("performance %p message thread\n", This); SetThreadDescription(GetCurrentThread(), L"wine_dmime_message"); @@ -145,13 +158,15 @@ static DWORD WINAPI message_thread_proc(void *args) { DWORD timeout = INFINITE;
- LIST_FOR_EACH_ENTRY_SAFE(message, next, &This->messages, struct message, entry) + while ((ptr = list_head(&This->messages))) { + struct message *message = LIST_ENTRY(ptr, struct message, entry); + struct list *next = ptr->next; list_remove(&message->entry); list_init(&message->entry);
hr = performance_process_message(This, &message->msg, &timeout); - if (hr == DMUS_S_REQUEUE) list_add_before(&next->entry, &message->entry); + if (hr == DMUS_S_REQUEUE) performance_queue_message(This, message, next); if (hr != S_OK) break; }
@@ -486,7 +501,7 @@ static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS { const DWORD delivery_flags = DMUS_PMSGF_TOOL_IMMEDIATE | DMUS_PMSGF_TOOL_QUEUE | DMUS_PMSGF_TOOL_ATTIME; struct performance *This = impl_from_IDirectMusicPerformance8(iface); - struct message *message, *next; + struct message *message; HRESULT hr;
TRACE("(%p, %p)\n", This, msg); @@ -523,10 +538,7 @@ static HRESULT WINAPI performance_SendPMsg(IDirectMusicPerformance8 *iface, DMUS if (hr != DMUS_S_REQUEUE) goto done; }
- LIST_FOR_EACH_ENTRY(next, &This->messages, struct message, entry) - if (next->msg.rtTime > message->msg.rtTime) break; - list_add_before(&next->entry, &message->entry); - + performance_queue_message(This, message, NULL); hr = S_OK; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmband/bandtrack.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/dmband/bandtrack.c b/dlls/dmband/bandtrack.c index f2a40c21751..4756ed194ef 100644 --- a/dlls/dmband/bandtrack.c +++ b/dlls/dmband/bandtrack.c @@ -159,7 +159,7 @@ static HRESULT WINAPI band_track_EndPlay(IDirectMusicTrack8 *iface, void *state_ }
static HRESULT WINAPI band_track_Play(IDirectMusicTrack8 *iface, void *state_data, - MUSIC_TIME start_time, MUSIC_TIME end_time, MUSIC_TIME time_offset, DWORD segment_flags, + MUSIC_TIME start_time, MUSIC_TIME end_time, MUSIC_TIME time_offset, DWORD track_flags, IDirectMusicPerformance *performance, IDirectMusicSegmentState *segment_state, DWORD track_id) { struct band_track *This = impl_from_IDirectMusicTrack8(iface); @@ -168,13 +168,11 @@ static HRESULT WINAPI band_track_Play(IDirectMusicTrack8 *iface, void *state_dat HRESULT hr;
TRACE("(%p, %p, %ld, %ld, %ld, %#lx, %p, %p, %ld)\n", This, state_data, start_time, end_time, - time_offset, segment_flags, performance, segment_state, track_id); + time_offset, track_flags, performance, segment_state, track_id);
if (!performance) return DMUS_S_END;
- if (start_time != 0) FIXME("start_time %ld not implemented\n", start_time); - if (end_time != -1) FIXME("end_time %ld not implemented\n", end_time); - if (segment_flags) FIXME("segment_flags %#lx not implemented\n", segment_flags); + if (track_flags) FIXME("track_flags %#lx not implemented\n", track_flags); if (segment_state) FIXME("segment_state %p not implemented\n", segment_state);
if (FAILED(hr = IDirectMusicPerformance_QueryInterface(performance, @@ -184,7 +182,13 @@ static HRESULT WINAPI band_track_Play(IDirectMusicTrack8 *iface, void *state_dat LIST_FOR_EACH_ENTRY(entry, &This->bands, struct band_entry, entry) { MUSIC_TIME music_time = entry->head.lBandTimeLogical; - if (music_time != -1) music_time += time_offset; + if (music_time == -1 && !(track_flags & DMUS_TRACKF_START)) continue; + else if (music_time != -1) + { + if (music_time < start_time || music_time >= end_time) continue; + music_time += time_offset; + } + if (FAILED(hr = band_send_messages(entry->band, performance, graph, music_time, track_id))) break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/seqtrack.c | 8 ++++++-- dlls/dmime/wavetrack.c | 11 ++++++----- 2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/dlls/dmime/seqtrack.c b/dlls/dmime/seqtrack.c index 56c61c02576..3252580afb6 100644 --- a/dlls/dmime/seqtrack.c +++ b/dlls/dmime/seqtrack.c @@ -120,8 +120,6 @@ static HRESULT WINAPI sequence_track_Play(IDirectMusicTrack8 *iface, void *state TRACE("(%p, %p, %ld, %ld, %ld, %#lx, %p, %p, %ld)\n", This, state_data, start_time, end_time, time_offset, segment_flags, performance, segment_state, track_id);
- if (start_time != 0) FIXME("start_time %ld not implemented\n", start_time); - if (end_time != -1) FIXME("end_time %ld not implemented\n", end_time); if (segment_flags) FIXME("segment_flags %#lx not implemented\n", segment_flags); if (segment_state) FIXME("segment_state %p not implemented\n", segment_state);
@@ -134,6 +132,9 @@ static HRESULT WINAPI sequence_track_Play(IDirectMusicTrack8 *iface, void *state DMUS_IO_SEQ_ITEM *item = This->items + i; DMUS_NOTE_PMSG *msg;
+ if (item->mtTime < start_time) continue; + if (item->mtTime >= end_time) continue; + if (FAILED(hr = IDirectMusicPerformance_AllocPMsg(performance, sizeof(*msg), (DMUS_PMSG **)&msg))) break; @@ -164,6 +165,9 @@ static HRESULT WINAPI sequence_track_Play(IDirectMusicTrack8 *iface, void *state DMUS_IO_CURVE_ITEM *item = This->curve_items + i; DMUS_CURVE_PMSG *msg;
+ if (item->mtStart < start_time) continue; + if (item->mtStart >= end_time) continue; + if (FAILED(hr = IDirectMusicPerformance_AllocPMsg(performance, sizeof(*msg), (DMUS_PMSG **)&msg))) break; diff --git a/dlls/dmime/wavetrack.c b/dlls/dmime/wavetrack.c index 974e656cfe5..7f2fe4a8e5f 100644 --- a/dlls/dmime/wavetrack.c +++ b/dlls/dmime/wavetrack.c @@ -144,7 +144,7 @@ static HRESULT WINAPI wave_track_EndPlay(IDirectMusicTrack8 *iface, void *pState }
static HRESULT WINAPI wave_track_Play(IDirectMusicTrack8 *iface, void *state_data, - MUSIC_TIME start_time, MUSIC_TIME end_time, MUSIC_TIME time_offset, DWORD segment_flags, + MUSIC_TIME start_time, MUSIC_TIME end_time, MUSIC_TIME time_offset, DWORD track_flags, IDirectMusicPerformance *performance, IDirectMusicSegmentState *segment_state, DWORD track_id) { struct wave_track *This = impl_from_IDirectMusicTrack8(iface); @@ -155,12 +155,11 @@ static HRESULT WINAPI wave_track_Play(IDirectMusicTrack8 *iface, void *state_dat HRESULT hr;
TRACE("(%p, %p, %ld, %ld, %ld, %#lx, %p, %p, %ld)\n", This, state_data, start_time, end_time, - time_offset, segment_flags, performance, segment_state, track_id); + time_offset, track_flags, performance, segment_state, track_id);
- if (start_time != 0) FIXME("start_time %ld not implemented\n", start_time); - if (end_time != -1) FIXME("end_time %ld not implemented\n", end_time); - if (segment_flags) FIXME("segment_flags %#lx not implemented\n", segment_flags); + if (track_flags) FIXME("track_flags %#lx not implemented\n", track_flags); if (segment_state) FIXME("segment_state %p not implemented\n", segment_state); + if (!(track_flags & DMUS_TRACKF_START)) return S_OK;
if (FAILED(hr = IDirectMusicPerformance_QueryInterface(performance, &IID_IDirectMusicGraph, (void **)&graph))) @@ -175,6 +174,8 @@ static HRESULT WINAPI wave_track_Play(IDirectMusicTrack8 *iface, void *state_dat DMUS_WAVE_PMSG *msg;
if (!item->buffer) continue; + if (item->header.rtTime < start_time) continue; + if (item->header.rtTime >= end_time) continue;
if (FAILED(hr = IDirectMusicPerformance_AllocPMsg(performance, sizeof(*msg), (DMUS_PMSG **)&msg)))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/dmime_private.h | 3 ++ dlls/dmime/performance.c | 66 +++++++++++++++++++++++++++++++++----- dlls/dmime/segmentstate.c | 53 ++++++++++++++++++++++++++---- 3 files changed, 107 insertions(+), 15 deletions(-)
diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index 28836694ed9..212ee254192 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -75,12 +75,15 @@ extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSo extern HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time, IDirectMusicPerformance8 *performance, IDirectMusicSegmentState **ret_iface); extern HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance); +extern HRESULT segment_state_tick(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance); extern HRESULT segment_state_end_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance);
extern HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry *parent, IDirectMusicTrack8 **ret_iface);
extern HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound); +extern HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, + IDirectMusicSegmentState *state); extern HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state);
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 7ab11773314..6f77f8677ba 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -28,6 +28,7 @@ enum dmus_internal_message_type { DMUS_PMSGT_INTERNAL_FIRST = 0x10, DMUS_PMSGT_INTERNAL_SEGMENT_END = DMUS_PMSGT_INTERNAL_FIRST, + DMUS_PMSGT_INTERNAL_SEGMENT_TICK, };
struct pchannel_block { @@ -275,6 +276,43 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi return CONTAINING_RECORD(iface, struct performance, IDirectMusicPerformance8_iface); }
+static HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, + IDirectMusicSegmentState *state) +{ + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + HRESULT hr; + + if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_performance, + GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED, NULL))) + return hr; + if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART, (IUnknown *)state))) + return hr; + if (FAILED(hr = performance_send_pmsg(This, music_time, DMUS_PMSGF_TOOL_IMMEDIATE, + DMUS_PMSGT_DIRTY, NULL))) + return hr; + + return S_OK; +} + +HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, + IDirectMusicSegmentState *state) +{ + struct performance *This = impl_from_IDirectMusicPerformance8(iface); + REFERENCE_TIME time; + HRESULT hr; + + if (FAILED(hr = IDirectMusicPerformance8_MusicToReferenceTime(iface, music_time, &time))) + return hr; + if (FAILED(hr = IDirectMusicPerformance8_ReferenceToMusicTime(iface, time + 2000000, &music_time))) + return hr; + if (FAILED(hr = performance_send_pmsg(This, music_time, DMUS_PMSGF_TOOL_QUEUE, + DMUS_PMSGT_INTERNAL_SEGMENT_TICK, (IUnknown *)state))) + return hr; + + return S_OK; +} + HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state) { @@ -1235,16 +1273,11 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, return hr; }
+ EnterCriticalSection(&This->safe); + hr = IDirectMusicSegment_GetLength(segment, &length); if (SUCCEEDED(hr)) - hr = performance_send_notification_pmsg(This, music_time, This->notification_performance, - GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTARTED, NULL); - if (SUCCEEDED(hr)) - hr = performance_send_notification_pmsg(This, music_time, This->notification_segment, - GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGSTART, (IUnknown *)state); - if (SUCCEEDED(hr)) - hr = performance_send_pmsg(This, music_time, DMUS_PMSGF_TOOL_IMMEDIATE, DMUS_PMSGT_DIRTY, NULL); - + hr = performance_send_segment_start(iface, music_time, state); if (SUCCEEDED(hr)) hr = segment_state_play(state, iface);
@@ -1266,6 +1299,8 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, IDirectMusicSegmentState_AddRef(state); }
+ LeaveCriticalSection(&This->safe); + IDirectMusicSegmentState_Release(state); IDirectMusicSegment_Release(segment); return hr; @@ -1839,6 +1874,21 @@ static HRESULT WINAPI performance_tool_ProcessPMsg(IDirectMusicTool *iface, WARN("Failed to play wave buffer, hr %#lx\n", hr); break;
+ case DMUS_PMSGT_INTERNAL_SEGMENT_TICK: + msg->rtTime += 10000000; + msg->dwFlags &= ~DMUS_PMSGF_MUSICTIME; + + /* re-send the tick message until segment_state_tick returns S_FALSE */ + if (FAILED(hr = segment_state_tick((IDirectMusicSegmentState *)msg->punkUser, + (IDirectMusicPerformance8 *)performance))) + ERR("Failed to tick segment state %p, hr %#lx\n", msg->punkUser, hr); + else if (hr == S_FALSE) + return DMUS_S_FREE; /* done ticking */ + else if (FAILED(hr = IDirectMusicPerformance_SendPMsg(performance, msg))) + ERR("Failed to queue tick for segment state %p, hr %#lx\n", msg->punkUser, hr); + + return S_OK; + case DMUS_PMSGT_INTERNAL_SEGMENT_END: if (FAILED(hr = segment_state_end_play((IDirectMusicSegmentState *)msg->punkUser, (IDirectMusicPerformance8 *)performance))) diff --git a/dlls/dmime/segmentstate.c b/dlls/dmime/segmentstate.c index 21b98ccc14c..fa49d06836b 100644 --- a/dlls/dmime/segmentstate.c +++ b/dlls/dmime/segmentstate.c @@ -51,6 +51,7 @@ struct segment_state MUSIC_TIME start_time; MUSIC_TIME start_point; MUSIC_TIME end_point; + MUSIC_TIME played; BOOL auto_download;
struct list tracks; @@ -271,25 +272,63 @@ HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time return hr; }
-HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance) +static HRESULT segment_state_play_chunk(struct segment_state *This, IDirectMusicPerformance8 *performance, + REFERENCE_TIME duration, DWORD track_flags) { - struct segment_state *This = impl_from_IDirectMusicSegmentState8((IDirectMusicSegmentState8 *)iface); - DWORD track_flags = DMUS_TRACKF_DIRTY | DMUS_TRACKF_START | DMUS_TRACKF_SEEK; - MUSIC_TIME start_time = This->start_point, end_time = This->end_point; + IDirectMusicSegmentState *iface = (IDirectMusicSegmentState *)&This->IDirectMusicSegmentState8_iface; + MUSIC_TIME next_time, played; struct track_entry *entry; + REFERENCE_TIME time; HRESULT hr = S_OK;
+ if (FAILED(hr = IDirectMusicPerformance8_MusicToReferenceTime(performance, + This->start_time + This->played, &time))) + return hr; + if (FAILED(hr = IDirectMusicPerformance8_ReferenceToMusicTime(performance, + time + duration, &next_time))) + return hr; + played = min(next_time - This->start_time, This->end_point - This->start_point); + LIST_FOR_EACH_ENTRY(entry, &This->tracks, struct track_entry, entry) { - if (FAILED(hr = IDirectMusicTrack_Play(entry->track, entry->state_data, start_time, end_time, - This->start_time, track_flags, (IDirectMusicPerformance *)performance, iface, entry->track_id))) + if (FAILED(hr = IDirectMusicTrack_Play(entry->track, entry->state_data, + This->start_point + This->played, This->start_point + played, + This->start_time, track_flags, (IDirectMusicPerformance *)performance, + iface, entry->track_id))) { WARN("Failed to play track %p, hr %#lx\n", entry->track, hr); break; } }
- return hr; + This->played = played; + if (This->start_point + This->played >= This->end_point) + return S_FALSE; + return S_OK; +} + +HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance) +{ + struct segment_state *This = impl_from_IDirectMusicSegmentState8((IDirectMusicSegmentState8 *)iface); + HRESULT hr; + + TRACE("%p %p\n", iface, performance); + + if (FAILED(hr = segment_state_play_chunk(This, performance, 10000000, + DMUS_TRACKF_START | DMUS_TRACKF_SEEK | DMUS_TRACKF_DIRTY))) + return hr; + + if (hr == S_FALSE) return S_OK; + return performance_send_segment_tick(performance, This->start_time, iface); +} + +HRESULT segment_state_tick(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance) +{ + struct segment_state *This = impl_from_IDirectMusicSegmentState8((IDirectMusicSegmentState8 *)iface); + + TRACE("%p %p\n", iface, performance); + + return segment_state_play_chunk(This, performance, 10000000, 0); }
HRESULT segment_state_end_play(IDirectMusicSegmentState *iface, IDirectMusicPerformance8 *performance)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmime/dmime_private.h | 2 ++ dlls/dmime/performance.c | 38 +++++++++++++++++--------------------- dlls/dmime/segmentstate.c | 22 ++++++++++++++++++---- dlls/dmime/tests/dmime.c | 7 +++---- 4 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h index 212ee254192..e1a2374facf 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h @@ -82,6 +82,8 @@ extern HRESULT wave_track_create_from_chunk(IStream *stream, struct chunk_entry IDirectMusicTrack8 **ret_iface);
extern HRESULT performance_get_dsound(IDirectMusicPerformance8 *iface, IDirectSound **dsound); +extern HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, + IDirectMusicSegmentState *state); extern HRESULT performance_send_segment_tick(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state); extern HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 6f77f8677ba..a08c00502d9 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -276,7 +276,7 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi return CONTAINING_RECORD(iface, struct performance, IDirectMusicPerformance8_iface); }
-static HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, +HRESULT performance_send_segment_start(IDirectMusicPerformance8 *iface, MUSIC_TIME music_time, IDirectMusicSegmentState *state) { struct performance *This = impl_from_IDirectMusicPerformance8(iface); @@ -319,6 +319,18 @@ HRESULT performance_send_segment_end(IDirectMusicPerformance8 *iface, MUSIC_TIME struct performance *This = impl_from_IDirectMusicPerformance8(iface); HRESULT hr;
+ if (FAILED(hr = performance_send_notification_pmsg(This, music_time - 1450, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND, (IUnknown *)state))) + return hr; + if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_segment, + GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND, (IUnknown *)state))) + return hr; + if (FAILED(hr = performance_send_pmsg(This, music_time, DMUS_PMSGF_TOOL_IMMEDIATE, + DMUS_PMSGT_DIRTY, NULL))) + return hr; + if (FAILED(hr = performance_send_notification_pmsg(This, music_time, This->notification_performance, + GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED, NULL))) + return hr; if (FAILED(hr = performance_send_pmsg(This, music_time, DMUS_PMSGF_TOOL_ATTIME, DMUS_PMSGT_INTERNAL_SEGMENT_END, (IUnknown *)state))) return hr; @@ -1253,8 +1265,8 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, { struct performance *This = impl_from_IDirectMusicPerformance8(iface); IDirectMusicSegmentState *state; - MUSIC_TIME length, music_time; IDirectMusicSegment *segment; + MUSIC_TIME music_time; HRESULT hr;
FIXME("(%p, %p, %s, %p, %#lx, %I64d, %p, %p, %p): stub\n", This, source, debugstr_w(segment_name), @@ -1275,25 +1287,9 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface,
EnterCriticalSection(&This->safe);
- hr = IDirectMusicSegment_GetLength(segment, &length); - if (SUCCEEDED(hr)) - hr = performance_send_segment_start(iface, music_time, state); - if (SUCCEEDED(hr)) - hr = segment_state_play(state, iface); - - if (SUCCEEDED(hr)) - hr = performance_send_notification_pmsg(This, music_time + length - 1450, This->notification_segment, - GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGALMOSTEND, (IUnknown *)state); - if (SUCCEEDED(hr)) - hr = performance_send_notification_pmsg(This, music_time + length, This->notification_segment, - GUID_NOTIFICATION_SEGMENT, DMUS_NOTIFICATION_SEGEND, (IUnknown *)state); - if (SUCCEEDED(hr)) - hr = performance_send_pmsg(This, music_time + length, DMUS_PMSGF_TOOL_IMMEDIATE, DMUS_PMSGT_DIRTY, NULL); - if (SUCCEEDED(hr)) - hr = performance_send_notification_pmsg(This, music_time + length, This->notification_performance, - GUID_NOTIFICATION_PERFORMANCE, DMUS_NOTIFICATION_MUSICSTOPPED, NULL); - - if (SUCCEEDED(hr) && segment_state) + if (FAILED(hr = segment_state_play(state, iface))) + ERR("Failed to play segment state, hr %#lx\n", hr); + else if (segment_state) { *segment_state = state; IDirectMusicSegmentState_AddRef(state); diff --git a/dlls/dmime/segmentstate.c b/dlls/dmime/segmentstate.c index fa49d06836b..f2f895de881 100644 --- a/dlls/dmime/segmentstate.c +++ b/dlls/dmime/segmentstate.c @@ -215,8 +215,8 @@ HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time IDirectMusicSegmentState *iface; struct segment_state *This; IDirectMusicTrack *track; - UINT i, duration; HRESULT hr; + UINT i;
TRACE("(%p, %lu, %p)\n", segment, start_time, ret_iface);
@@ -264,9 +264,6 @@ HRESULT segment_state_create(IDirectMusicSegment *segment, MUSIC_TIME start_time } }
- duration = This->end_point - This->start_point; - if (SUCCEEDED(hr)) hr = performance_send_segment_end(performance, start_time + duration, iface); - if (SUCCEEDED(hr)) *ret_iface = iface; else IDirectMusicSegmentState_Release(iface); return hr; @@ -303,7 +300,18 @@ static HRESULT segment_state_play_chunk(struct segment_state *This, IDirectMusic
This->played = played; if (This->start_point + This->played >= This->end_point) + { + MUSIC_TIME end_time = This->start_time + This->played; + + if (FAILED(hr = performance_send_segment_end(performance, end_time, iface))) + { + ERR("Failed to send segment end, hr %#lx\n", hr); + return hr; + } + return S_FALSE; + } + return S_OK; }
@@ -314,6 +322,12 @@ HRESULT segment_state_play(IDirectMusicSegmentState *iface, IDirectMusicPerforma
TRACE("%p %p\n", iface, performance);
+ if (FAILED(hr = performance_send_segment_start(performance, This->start_time, iface))) + { + ERR("Failed to send segment start, hr %#lx\n", hr); + return hr; + } + if (FAILED(hr = segment_state_play_chunk(This, performance, 10000000, DMUS_TRACKF_START | DMUS_TRACKF_SEEK | DMUS_TRACKF_DIRTY))) return hr; diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c index 05dc653a935..79fbb902868 100644 --- a/dlls/dmime/tests/dmime.c +++ b/dlls/dmime/tests/dmime.c @@ -3147,8 +3147,8 @@ static void test_notification_pmsg(void) ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 50, &msg); - todo_wine ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret); - if (ret == WAIT_TIMEOUT) ret = test_tool_wait_message(tool, 500, &msg); + ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret); + ret = test_tool_wait_message(tool, 500, &msg); ok(!ret, "got %#lx\n", ret); check_dmus_dirty_pmsg(msg, music_time + length); hr = IDirectMusicPerformance_FreePMsg(performance, msg); @@ -3312,8 +3312,7 @@ static void test_notification_pmsg(void) ok(hr == S_OK, "got %#lx\n", hr);
ret = test_tool_wait_message(tool, 500, &msg); - todo_wine ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret); - if (!ret) IDirectMusicPerformance_FreePMsg(performance, msg); + ok(ret == WAIT_TIMEOUT, "got %#lx\n", ret);
IDirectMusicSegmentState_Release(state); IDirectMusicSegment_Release(segment);
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=139641
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 1838 dmime.c:3235: Test failed: got punkUser 0174C5E8 dmime.c:3242: Test failed: got mtTime 1838
=== w7u_adm (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 1839 dmime.c:3235: Test failed: got punkUser 0082D820 dmime.c:3242: Test failed: got mtTime 1839
=== w7u_el (32 bit report) ===
dmime: dmime.c:3235: Test failed: got punkUser 0096AA58 dmime.c:3242: Test failed: got mtTime 1830 dmime.c:3249: Test failed: got mtTime 1830 dmime.c:3249: Test failed: got punkUser 00000000 0a70:dmime: unhandled exception c0000005 at 00CDDFD6
=== w864 (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 465 dmime.c:3235: Test failed: got punkUser 033A9720
=== w1064v1507 (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 466 dmime.c:3235: Test failed: got punkUser 04369DB8 dmime.c:3242: Test failed: got mtTime 1848 dmime.c:3249: Test failed: got mtTime 1848
=== w1064v1809 (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 463 dmime.c:3235: Test failed: got punkUser 031772E8 dmime.c:3242: Test failed: got mtTime 1846 dmime.c:3249: Test failed: got mtTime 1846
=== w10pro64 (32 bit report) ===
dmime: 0e8c:dmime: unhandled exception c0000005 at 00B52B2D
=== w10pro64_en_AE_u8 (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 463 dmime.c:3235: Test failed: got punkUser 04AD9BF0 dmime.c:3242: Test failed: got mtTime 1846 dmime.c:3249: Test failed: got mtTime 1846
=== w11pro64 (32 bit report) ===
dmime: dmime.c:3235: Test failed: got mtTime 464 dmime.c:3235: Test failed: got punkUser 04413040 dmime.c:3242: Test failed: got mtTime 1846 dmime.c:3249: Test failed: got mtTime 1846
Michael Stefaniuc (@mstefani) commented about dlls/dmime/performance.c:
What's the magic number `2000000` ?
On Tue Nov 7 20:00:24 2023 +0000, Michael Stefaniuc wrote:
What's the magic number `2000000` ?
This is 200ms, so that we schedule the first (and later) tick ahead in time, and avoid queueing the next 1s batch of messages too close to when the previous one ends.
Unrelated test failures in ddraw7.c and win.c
This merge request was approved by Michael Stefaniuc.