From: Yuxuan Shui yshui@codeweavers.com
--- dlls/dmime/miditrack.c | 53 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/dlls/dmime/miditrack.c b/dlls/dmime/miditrack.c index a51cc3ea9a5..1e55475af0f 100644 --- a/dlls/dmime/miditrack.c +++ b/dlls/dmime/miditrack.c @@ -211,11 +211,62 @@ static HRESULT WINAPI midi_sequence_track_Play(IDirectMusicTrack8 *iface, void * IDirectMusicPerformance *performance, IDirectMusicSegmentState *segment_state, DWORD track_id) { struct midi_sequence_track *This = impl_from_IDirectMusicTrack8(iface); + struct list *cursor; + IDirectMusicGraph *graph; + HRESULT hr; + UINT i; + ULONG ticks = 0; + MUSIC_TIME music_time;
TRACE("(%p, %p, %ld, %ld, %ld, %#lx, %p, %p, %ld): stub\n", This, state_data, start_time, end_time, time_offset, segment_flags, performance, segment_state, track_id);
- return E_NOTIMPL; + if (segment_flags) FIXME("segment_flags %#lx not implemented\n", segment_flags); + if (segment_state) FIXME("segment_state %p not implemented\n", segment_state); + + if (FAILED(hr = IDirectMusicPerformance_QueryInterface(performance, &IID_IDirectMusicGraph, (void **)&graph))) + return hr; + + cursor = list_head(&This->events); + for (i = 0; SUCCEEDED(hr) && i < This->event_count; i++, cursor = list_next(&This->events, cursor)) + { + struct event *item = LIST_ENTRY(cursor, struct event, entry); + DMUS_MIDI_PMSG *msg; + + ticks += item->deltaTime; + if (This->ticks_per_quarter_note) + music_time = (ULONGLONG)ticks * DMUS_PPQ / This->ticks_per_quarter_note; + else + /* This is the "fake" tempo case, ticks and MUSIC_TIME should mean + * the same thing. */ + music_time = ticks; + + if (music_time < start_time || music_time >= end_time) continue; + + if (item->status == 0xff || item->status == 0xf0 || item->status == 0xf7) continue; + + if (FAILED(hr = IDirectMusicPerformance_AllocPMsg(performance, sizeof(*msg), (DMUS_PMSG **)&msg))) + break; + + msg->dwFlags = DMUS_PMSGF_MUSICTIME; + msg->mtTime = music_time; + msg->dwPChannel = item->status & 0xf; + msg->dwVirtualTrackID = track_id; + msg->dwType = DMUS_PMSGT_MIDI; + msg->dwGroupID = 1; + msg->bStatus = item->status; + msg->bByte1 = item->data.fixed.byte[0]; + msg->bByte2 = item->data.fixed.byte[1]; + + if (FAILED(hr = IDirectMusicGraph_StampPMsg(graph, (DMUS_PMSG *)msg)) || + FAILED(hr = IDirectMusicPerformance_SendPMsg(performance, (DMUS_PMSG *)msg))) + { + IDirectMusicPerformance_FreePMsg(performance, (DMUS_PMSG *)msg); + break; + } + } + + return SUCCEEDED(hr) ? S_OK : hr; }
static HRESULT WINAPI midi_sequence_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type,