Akihiro Sagawa : winmm: Make TIME_TICKS position continuous.
Alexandre Julliard
julliard at winehq.org
Wed Jul 11 15:53:51 CDT 2018
Module: wine
Branch: master
Commit: ced8ce55b499e4b8e62549a3c353324a93f8f3db
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ced8ce55b499e4b8e62549a3c353324a93f8f3db
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Wed Jul 11 22:33:23 2018 +0900
winmm: Make TIME_TICKS position continuous.
Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winmm/tests/midi.c | 2 +-
dlls/winmm/winmm.c | 28 ++++++++++++++++++++++++++--
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c
index c550dfa..66f35ef 100644
--- a/dlls/winmm/tests/midi.c
+++ b/dlls/winmm/tests/midi.c
@@ -893,7 +893,7 @@ static void test_midiStream(UINT udev, HWND hwnd)
expected = ret;
ret = get_position(hm, TIME_TICKS);
- todo_wine ok(ret > strmNopsWithDelta[0].dwDeltaTime && ret < strmNopsWithDelta[1].dwDeltaTime,
+ ok(ret > strmNopsWithDelta[0].dwDeltaTime && ret < strmNopsWithDelta[1].dwDeltaTime,
"TIME_TICKS position is continuous, got %u\n", ret);
/* shouldn't set time division property while playing */
diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index 4b8d4de..f2dfae9 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -919,6 +919,7 @@ typedef struct WINE_MIDIStream {
DWORD dwPulses;
DWORD dwStartTicks;
DWORD dwElapsedMS;
+ DWORD dwLastPositionMS;
WORD wFlags;
WORD status;
HANDLE hEvent;
@@ -1008,6 +1009,7 @@ static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
lpMidiStrm->dwPulses = 0;
lpMidiStrm->dwElapsedMS = 0;
lpMidiStrm->position_usec = 0;
+ lpMidiStrm->dwLastPositionMS = 0;
LeaveCriticalSection(&lpMidiStrm->lock);
/* this is not quite what MS doc says... */
midiOutReset(lpMidiStrm->hDevice);
@@ -1181,7 +1183,6 @@ start_header:
if (me->dwDeltaTime) {
EnterCriticalSection(&lpMidiStrm->lock);
lpMidiStrm->position_usec += MMSYSTEM_MidiStream_Convert(lpMidiStrm, me->dwDeltaTime);
- lpMidiStrm->dwPulses += me->dwDeltaTime;
LeaveCriticalSection(&lpMidiStrm->lock);
dwToGo = lpMidiStrm->dwStartTicks + lpMidiStrm->position_usec / 1000;
@@ -1205,6 +1206,10 @@ start_header:
break;
}
}
+ EnterCriticalSection(&lpMidiStrm->lock);
+ lpMidiStrm->dwPulses += me->dwDeltaTime;
+ lpMidiStrm->dwLastPositionMS = midistream_get_playing_position(lpMidiStrm);
+ LeaveCriticalSection(&lpMidiStrm->lock);
}
switch (MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK)) {
case MEVT_COMMENT:
@@ -1332,6 +1337,7 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
lpMidiStrm->dwTempo = 500000; /* microseconds per quarter note, i.e. 120 BPM */
lpMidiStrm->dwTimeDiv = 24; /* ticks per quarter note */
lpMidiStrm->position_usec = 0;
+ lpMidiStrm->dwLastPositionMS = 0;
lpMidiStrm->status = MSM_STATUS_PAUSED;
lpMidiStrm->dwElapsedMS = 0;
@@ -1467,6 +1473,24 @@ MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
return midistream_post_message_and_wait(lpMidiStrm, WINE_MSM_PAUSE, 0);
}
+static DWORD midistream_get_current_pulse(WINE_MIDIStream* lpMidiStrm)
+{
+ DWORD pulses = 0;
+ DWORD now = midistream_get_playing_position(lpMidiStrm);
+ DWORD delta = now - lpMidiStrm->dwLastPositionMS;
+ if (lpMidiStrm->dwTimeDiv > 0x8000) {
+ /* SMPTE, unchecked FIXME */
+ BYTE nf = 256 - HIBYTE(lpMidiStrm->dwTimeDiv);
+ BYTE nsf = LOBYTE(lpMidiStrm->dwTimeDiv);
+ pulses = (delta * nf * nsf) / 1000;
+ }
+ else if (lpMidiStrm->dwTimeDiv) {
+ pulses = (DWORD)((double)(delta * lpMidiStrm->dwTimeDiv) *
+ 1000.0 / (double)lpMidiStrm->dwTempo);
+ }
+ return lpMidiStrm->dwPulses + pulses;
+}
+
/**************************************************************************
* midiStreamPosition [WINMM.@]
*/
@@ -1496,7 +1520,7 @@ MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbm
TRACE("=> %d ms\n", lpMMT->u.ms);
break;
case TIME_TICKS:
- lpMMT->u.ticks = lpMidiStrm->dwPulses;
+ lpMMT->u.ticks = midistream_get_current_pulse(lpMidiStrm);
TRACE("=> %d ticks\n", lpMMT->u.ticks);
break;
}
More information about the wine-cvs
mailing list