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