Jörg Höhle : mciwave: Implement Cue as no-op.

Alexandre Julliard julliard at winehq.org
Wed Nov 11 08:33:25 CST 2009


Module: wine
Branch: master
Commit: 096b774db22c87d2145821add5a562d03c896c38
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=096b774db22c87d2145821add5a562d03c896c38

Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date:   Mon Oct 19 18:31:57 2009 +0200

mciwave: Implement Cue as no-op.

Tests show that it must not close the opened wave file.

---

 dlls/mciwave/mciwave.c |   60 ++++++++++++++++++++---------------------------
 dlls/winmm/tests/mci.c |    4 +++
 2 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/dlls/mciwave/mciwave.c b/dlls/mciwave/mciwave.c
index deb7b40..5437c58 100644
--- a/dlls/mciwave/mciwave.c
+++ b/dlls/mciwave/mciwave.c
@@ -562,46 +562,38 @@ static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_P
 /**************************************************************************
  *                               WAVE_mciCue             [internal]
  */
-static DWORD WAVE_mciCue(MCIDEVICEID wDevID, LPARAM dwParam, LPMCI_GENERIC_PARMS lpParms)
+static DWORD WAVE_mciCue(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
-    /*
-      FIXME
-
-      This routine is far from complete. At the moment only a check is done on the
-      MCI_WAVE_INPUT flag. No explicit check on MCI_WAVE_OUTPUT is done since that
-      is the default.
-
-      The flags MCI_NOTIFY (and the callback parameter in lpParms) and MCI_WAIT
-      are ignored
-    */
-
-    DWORD		dwRet;
     WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);
 
-    FIXME("(%u, %08lX, %p); likely to fail\n", wDevID, dwParam, lpParms);
+    TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
 
-    if (wmw == NULL)	return MCIERR_INVALID_DEVICE_ID;
+    /* Tests on systems without sound drivers show that Cue, like
+     * Record and Play, opens winmm, returning MCIERR_WAVE_xyPUTSUNSUITABLE.
+     * The first Cue Notify does not immediately return the
+     * notification, as if a player or recorder thread is started.
+     * PAUSE mode is reported when successful, but this mode is
+     * different from the normal Pause, because a) Pause then returns
+     * NONAPPLICABLE_FUNCTION instead of 0 and b) Set Channels etc. is
+     * still accepted, returning the original notification as ABORTED.
+     * I.e. Cue allows subsequent format changes, unlike Record or
+     * Open file, closes winmm if the format changes and stops this
+     * thread.
+     * Wine creates one player or recorder thread per async. Play or
+     * Record command.  Notification behaviour suggests that MS-W*
+     * reuses a single thread to improve response times.  Having Cue
+     * start this thread early helps to improve Play/Record's initial
+     * response time.  In effect, Cue is a performance hint, which
+     * justifies our almost no-op implementation.
+     */
 
-    /* FIXME */
-    /* always close elements ? */
-    if (wmw->hFile != 0) {
-	mmioClose(wmw->hFile, 0);
-	wmw->hFile = 0;
-    }
+    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;
+    if (wmw->dwStatus != MCI_MODE_STOP) return MCIERR_NONAPPLICABLE_FUNCTION;
 
-    dwRet = MMSYSERR_NOERROR;  /* assume success */
+    if ((dwFlags & MCI_NOTIFY) && lpParms)
+	WAVE_mciNotify(lpParms->dwCallback,wmw,MCI_NOTIFY_SUCCESSFUL);
 
-    if ((dwParam & MCI_WAVE_INPUT) && !wmw->fInput) {
-	dwRet = waveOutClose(wmw->hWave);
-	if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-	wmw->fInput = TRUE;
-    } else if (wmw->fInput) {
-	dwRet = waveInClose(wmw->hWave);
-	if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
-	wmw->fInput = FALSE;
-    }
-    wmw->hWave = 0;
-    return (dwRet == MMSYSERR_NOERROR) ? 0 : MCIERR_INTERNAL;
+    return MMSYSERR_NOERROR;
 }
 
 /**************************************************************************
diff --git a/dlls/winmm/tests/mci.c b/dlls/winmm/tests/mci.c
index e6d83e2..248958b 100644
--- a/dlls/winmm/tests/mci.c
+++ b/dlls/winmm/tests/mci.c
@@ -478,6 +478,10 @@ static void test_asyncWAVE(HWND hwnd)
     test_notification(hwnd,"pause aborted play #1 notification",MCI_NOTIFY_SUPERSEDED);
     test_notification(hwnd,"impossible pause notification",0);
 
+    err = mciSendString("cue mysound output notify", NULL, 0, hwnd);
+    ok(err==MCIERR_NONAPPLICABLE_FUNCTION,"mci cue output while paused returned error: %d\n", err);
+    test_notification(hwnd,"cue output notify #2",0);
+
     /* Seek or even Stop used to hang Wine on MacOS. */
     err = mciSendString("seek mysound to 0 wait", NULL, 0, NULL);
     ok(!err,"mci seek to start returned error: %d\n", err);




More information about the wine-cvs mailing list