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