Ken Thomases : winecoreaudio: Improve state tracking.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 1 06:49:00 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 6a6aec72d3a63411cd5b1d831bd99c5735f461b8
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=6a6aec72d3a63411cd5b1d831bd99c5735f461b8

Author: Ken Thomases <ken at codeweavers.com>
Date:   Wed May 24 05:34:04 2006 -0500

winecoreaudio: Improve state tracking.

Improved tracking of device state (stopped, playing, or paused).
Also, tied starting and stopping the AudioUnit more directly to the
state.  No need to change the state when preparing or unpreparing
wavehdrs.  Pausing overrides both playing and stopped states; if
stopped, pausing prevents output from starting when the program
writes.  When, restarting from the paused state, the device starts
playing if there are queued wavehdrs.  Otherwise, it goes to stopped
state.

---

 dlls/winmm/winecoreaudio/audio.c |   94 +++++++++++++++++++++++++-------------
 1 files changed, 62 insertions(+), 32 deletions(-)

diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c
index 945fc80..771bdb6 100644
--- a/dlls/winmm/winecoreaudio/audio.c
+++ b/dlls/winmm/winecoreaudio/audio.c
@@ -782,8 +782,6 @@ static DWORD wodClose(WORD wDevID)
 */
 static DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-    OSStatus status;
-
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
     
     if (wDevID >= MAX_WAVEOUTDRV) {
@@ -796,17 +794,7 @@ static DWORD wodPrepare(WORD wDevID, LPW
     
     lpWaveHdr->dwFlags |= WHDR_PREPARED;
     lpWaveHdr->dwFlags &= ~WHDR_DONE;
-  
-    WOutDev[wDevID].state = WINE_WS_STOPPED;
-    
-    status = AudioOutputUnitStart(WOutDev[wDevID].audioUnit);
-    if (status) {
-        ERR("AudioOutputUnitStart return %c%c%c%c\n", (char) (status >> 24),
-                                                        (char) (status >> 16),
-                                                        (char) (status >> 8),
-                                                        (char) status);
-        return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */
-    }
+
     return MMSYSERR_NOERROR;
 }
 
@@ -815,8 +803,6 @@ static DWORD wodPrepare(WORD wDevID, LPW
 */
 static DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
-    OSStatus status;
-
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
     
     if (wDevID >= MAX_WAVEOUTDRV) {
@@ -830,11 +816,6 @@ static DWORD wodUnprepare(WORD wDevID, L
     lpWaveHdr->dwFlags &= ~WHDR_PREPARED;
     lpWaveHdr->dwFlags |= WHDR_DONE;
    
-    status = AudioOutputUnitStop(WOutDev[wDevID].audioUnit);
-    if (status) {
-        ERR("AudioOutputUnitStop return %c%c%c%c\n", (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
-        return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */
-    }
     return MMSYSERR_NOERROR;
 }
 
@@ -848,12 +829,32 @@ static DWORD wodUnprepare(WORD wDevID, L
 */
 static void wodHelper_BeginWaveHdr(WINE_WAVEOUT* wwo, LPWAVEHDR lpWaveHdr)
 {
+    OSStatus status;
+
     wwo->lpPlayPtr = lpWaveHdr;
     
     if (!lpWaveHdr)
     {
+        if (wwo->state == WINE_WS_PLAYING)
+        {
+            wwo->state = WINE_WS_STOPPED;
+            status = AudioOutputUnitStop(wwo->audioUnit);
+            if (status)
+                fprintf(stderr, "err:winecoreaudio:wodHelper_BeginWaveHdr AudioOutputUnitStop return %c%c%c%c\n",
+                        (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
+        }
         return;
     }
+
+    if (wwo->state == WINE_WS_STOPPED)
+    {
+        status = AudioOutputUnitStart(wwo->audioUnit);
+        if (status) {
+            fprintf(stderr, "err:winecoreaudio:AudioOutputUnitStart return %c%c%c%c\n",
+                    (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
+        }
+        else wwo->state = WINE_WS_PLAYING;
+    }
     
     if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)
     {
@@ -968,8 +969,10 @@ static DWORD wodHelper_NotifyCompletions
 *
 * Resets current output stream.
 */
-static  void  wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset)
+static  DWORD  wodHelper_Reset(WINE_WAVEOUT* wwo, BOOL reset)
 {
+    OSStatus status;
+
     FIXME("\n");
    
     /* updates current notify list */
@@ -1017,7 +1020,17 @@ static  void  wodHelper_Reset(WINE_WAVEO
         wwo->state = WINE_WS_PAUSED;
     }
 
+    status = AudioOutputUnitStop(wwo->audioUnit);
+
     pthread_mutex_unlock(&wwo->lock);
+
+    if (status) {
+        ERR( "AudioOutputUnitStop return %c%c%c%c\n",
+             (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
+        return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */
+    }
+
+    return MMSYSERR_NOERROR;
 }
 
 
@@ -1065,8 +1078,6 @@ static DWORD wodWrite(WORD wDevID, LPWAV
     
     if (!wwo->lpPlayPtr)
         wodHelper_BeginWaveHdr(wwo,lpWaveHdr);
-    if (wwo->state == WINE_WS_STOPPED)
-        wwo->state = WINE_WS_PLAYING;
     pthread_mutex_unlock(&wwo->lock);
     
     return MMSYSERR_NOERROR;
@@ -1077,6 +1088,8 @@ static DWORD wodWrite(WORD wDevID, LPWAV
 */
 static DWORD wodPause(WORD wDevID)
 {
+    OSStatus status;
+
     TRACE("(%u);!\n", wDevID);
     
     if (wDevID >= MAX_WAVEOUTDRV)
@@ -1085,12 +1098,19 @@ static DWORD wodPause(WORD wDevID)
         return MMSYSERR_BADDEVICEID;
     }
     
-    if (WOutDev[wDevID].state == WINE_WS_PLAYING)
+    pthread_mutex_lock(&WOutDev[wDevID].lock);
+    if (WOutDev[wDevID].state == WINE_WS_PLAYING || WOutDev[wDevID].state == WINE_WS_STOPPED)
     {
-        pthread_mutex_lock(&WOutDev[wDevID].lock);
         WOutDev[wDevID].state = WINE_WS_PAUSED;
-        pthread_mutex_unlock(&WOutDev[wDevID].lock);
+        status = AudioOutputUnitStop(WOutDev[wDevID].audioUnit);
+        if (status) {
+            ERR( "AudioOutputUnitStop return %c%c%c%c\n",
+                 (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
+            pthread_mutex_unlock(&WOutDev[wDevID].lock);
+            return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */
+        }
     }
+    pthread_mutex_unlock(&WOutDev[wDevID].lock);
     
     return MMSYSERR_NOERROR;
 }
@@ -1108,12 +1128,24 @@ static DWORD wodRestart(WORD wDevID)
         return MMSYSERR_BADDEVICEID;
     }
     
+    pthread_mutex_lock(&WOutDev[wDevID].lock);
     if (WOutDev[wDevID].state == WINE_WS_PAUSED)
     {
-        pthread_mutex_lock(&WOutDev[wDevID].lock);
-        WOutDev[wDevID].state = WINE_WS_PLAYING;
-        pthread_mutex_unlock(&WOutDev[wDevID].lock);
+        if (WOutDev[wDevID].lpPlayPtr)
+        {
+            OSStatus status = AudioOutputUnitStart(WOutDev[wDevID].audioUnit);
+            if (status) {
+                ERR("AudioOutputUnitStart return %c%c%c%c\n",
+                    (char) (status >> 24), (char) (status >> 16), (char) (status >> 8), (char) status);
+                pthread_mutex_unlock(&WOutDev[wDevID].lock);
+                return MMSYSERR_ERROR; /* FIXME return an error based on the OSStatus */
+            }
+            WOutDev[wDevID].state = WINE_WS_PLAYING;
+        }
+        else
+            WOutDev[wDevID].state = WINE_WS_STOPPED;
     }
+    pthread_mutex_unlock(&WOutDev[wDevID].lock);
     
     return MMSYSERR_NOERROR;
 }
@@ -1131,9 +1163,7 @@ static DWORD wodReset(WORD wDevID)
         return MMSYSERR_BADDEVICEID;
     }
     
-    wodHelper_Reset(&WOutDev[wDevID], TRUE);
-    
-    return MMSYSERR_NOERROR;
+    return wodHelper_Reset(&WOutDev[wDevID], TRUE);
 }
 
 /**************************************************************************




More information about the wine-cvs mailing list