Akihiro Sagawa : winmm: Return a continuous stream position in MIDI stream.

Alexandre Julliard julliard at winehq.org
Tue May 29 16:08:31 CDT 2018


Module: wine
Branch: master
Commit: 2e2ff80567b4f64f5670330421421762a724b7c5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2e2ff80567b4f64f5670330421421762a724b7c5

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Tue May 29 08:18:36 2018 -0500

winmm: Return a continuous stream position in MIDI stream.

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 |  8 ++++----
 dlls/winmm/winmm.c      | 37 +++++++++++++++++++++++++++++++++----
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c
index c78e465..091a500 100644
--- a/dlls/winmm/tests/midi.c
+++ b/dlls/winmm/tests/midi.c
@@ -869,7 +869,7 @@ static void test_midiStream(UINT udev, HWND hwnd)
 
     expected = 50;
     ret = get_position(hm, TIME_MS);
-    todo_wine ok(ret >= expected && ret < expected + MARGIN, "expected %ums or greater, got %ums\n", expected, ret);
+    ok(ret >= expected && ret < expected + MARGIN, "expected %ums or greater, got %ums\n", expected, ret);
     expected = ret;
 
     Sleep(100);
@@ -882,7 +882,7 @@ static void test_midiStream(UINT udev, HWND hwnd)
 
     Sleep(1);
     ret = get_position(hm, TIME_MS);
-    todo_wine ok(ret > expected && ret < expected + MARGIN, "expected greater than %ums, got %ums\n", expected, ret);
+    ok(ret > expected && ret < expected + MARGIN, "expected greater than %ums, got %ums\n", expected, ret);
     expected = ret;
 
     ret = WaitForSingleObject(records.done, INFINITE);
@@ -893,7 +893,7 @@ static void test_midiStream(UINT udev, HWND hwnd)
 
     expected = 250; /* = 12 ticks in 120 BPM */
     ret = get_position(hm, TIME_MS);
-    ok(ret >= expected - MARGIN && ret <= expected + MARGIN,
+    todo_wine ok(ret >= expected - MARGIN && ret <= expected + MARGIN,
        "expected greater than %ums, got %ums\n", expected, ret);
     trace("after playing, got %ums\n", ret);
 
@@ -924,7 +924,7 @@ static void test_midiStream(UINT udev, HWND hwnd)
     ok(!rc, "midiStreamStop(dev=%d) rc=%s\n", udev, mmsys_error(rc));
 
     ret = get_position(hm, TIME_MS);
-    todo_wine ok(ret == 0, "expected 0ms, got %ums\n", ret);
+    ok(ret == 0, "expected 0ms, got %ums\n", ret);
 
     rc = midiStreamClose(hm);
     ok(!rc, "midiStreamClose(dev=%d) rc=%s\n", udev, mmsys_error(rc));
diff --git a/dlls/winmm/winmm.c b/dlls/winmm/winmm.c
index 76807ab..2031c79 100644
--- a/dlls/winmm/winmm.c
+++ b/dlls/winmm/winmm.c
@@ -918,6 +918,7 @@ typedef struct WINE_MIDIStream {
     DWORD			dwPositionMS;
     DWORD			dwPulses;
     DWORD			dwStartTicks;
+    DWORD			dwElapsedMS;
     WORD			wFlags;
     WORD			status;
     HANDLE			hEvent;
@@ -973,6 +974,20 @@ static	DWORD	MMSYSTEM_MidiStream_Convert(WINE_MIDIStream* lpMidiStrm, DWORD puls
     return ret;
 }
 
+static DWORD midistream_get_playing_position(WINE_MIDIStream* lpMidiStrm)
+{
+    switch (lpMidiStrm->status) {
+    case MSM_STATUS_STOPPED:
+    case MSM_STATUS_PAUSED:
+        return lpMidiStrm->dwElapsedMS;
+    case MSM_STATUS_PLAYING:
+        return GetTickCount() - lpMidiStrm->dwStartTicks;
+    default:
+        FIXME("Unknown playing status %hu\n", lpMidiStrm->status);
+        return 0;
+    }
+}
+
 /**************************************************************************
  * 			MMSYSTEM_MidiStream_MessageHandler	[internal]
  */
@@ -988,7 +1003,11 @@ static	BOOL	MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
             return FALSE;
         case WINE_MSM_STOP:
             TRACE("STOP\n");
+            EnterCriticalSection(&lpMidiStrm->lock);
             lpMidiStrm->status = MSM_STATUS_STOPPED;
+            lpMidiStrm->dwPulses = 0;
+            lpMidiStrm->dwElapsedMS = 0;
+            LeaveCriticalSection(&lpMidiStrm->lock);
             /* this is not quite what MS doc says... */
             midiOutReset(lpMidiStrm->hDevice);
             /* empty list of already submitted buffers */
@@ -1008,13 +1027,22 @@ static	BOOL	MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWI
             return TRUE;
         case WINE_MSM_RESUME:
             /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
-            lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
-            lpMidiStrm->status = MSM_STATUS_PLAYING;
+            if (lpMidiStrm->status != MSM_STATUS_PLAYING) {
+                EnterCriticalSection(&lpMidiStrm->lock);
+                lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwElapsedMS;
+                lpMidiStrm->status = MSM_STATUS_PLAYING;
+                LeaveCriticalSection(&lpMidiStrm->lock);
+            }
             SetEvent((HANDLE)msg->wParam);
             return TRUE;
         case WINE_MSM_PAUSE:
             /* FIXME: send out cc64 0 (turn off sustain pedal) on every channel */
-            lpMidiStrm->status = MSM_STATUS_PAUSED;
+            if (lpMidiStrm->status != MSM_STATUS_PAUSED) {
+                EnterCriticalSection(&lpMidiStrm->lock);
+                lpMidiStrm->dwElapsedMS = GetTickCount() - lpMidiStrm->dwStartTicks;
+                lpMidiStrm->status = MSM_STATUS_PAUSED;
+                LeaveCriticalSection(&lpMidiStrm->lock);
+            }
             SetEvent((HANDLE)msg->wParam);
             break;
 	/* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
@@ -1302,6 +1330,7 @@ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
     lpMidiStrm->dwTimeDiv = 24;    /* ticks per quarter note */
     lpMidiStrm->dwPositionMS = 0;
     lpMidiStrm->status = MSM_STATUS_PAUSED;
+    lpMidiStrm->dwElapsedMS = 0;
 
     mosm.dwStreamID = (DWORD)lpMidiStrm;
     /* FIXME: the correct value is not allocated yet for MAPPER */
@@ -1460,7 +1489,7 @@ MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbm
 	    lpMMT->wType = TIME_MS;
 	    /* fall through to alternative format */
 	case TIME_MS:
-	    lpMMT->u.ms = lpMidiStrm->dwPositionMS;
+	    lpMMT->u.ms = midistream_get_playing_position(lpMidiStrm);
 	    TRACE("=> %d ms\n", lpMMT->u.ms);
 	    break;
 	case TIME_TICKS:




More information about the wine-cvs mailing list