some more OSS fixes

Eric Pouech eric.pouech at wanadoo.fr
Wed Oct 9 14:11:58 CDT 2002


this comes on top of Alexandre fixes (it deals mainly with multi sound
card support and error detection)

A+
-------------- next part --------------
Name:          oss_audio
ChangeLog:     fixed some multi-sound card related bugs
improved error reporting
License:       X11
GenDate:       2002/10/09 19:09:05 UTC
ModifiedFiles: dlls/winmm/wineoss/audio.c
AddedFiles:    
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.63
diff -u -u -r1.63 audio.c
--- dlls/winmm/wineoss/audio.c	9 Oct 2002 18:15:05 -0000	1.63
+++ dlls/winmm/wineoss/audio.c	9 Oct 2002 19:03:11 -0000
@@ -157,6 +157,7 @@
     unsigned                    format;
     unsigned                    audio_fragment;
     BOOL                        full_duplex;
+    BOOL                        bTriggerSupport;
 } OSS_DEVICE;
 
 static OSS_DEVICE   OSS_Devices[MAX_WAVEDRV];
@@ -202,7 +203,6 @@
     PCMWAVEFORMAT		format;
     LPWAVEHDR			lpQueuePtr;
     DWORD			dwTotalRecorded;
-    BOOL                        bTriggerSupport;
 
     /* synchronization stuff */
     HANDLE			hThread;
@@ -238,14 +238,14 @@
  *
  * Low level device opening (from values stored in ossdev)
  */
-static int      OSS_RawOpenDevice(OSS_DEVICE* ossdev, int* frag)
+static DWORD      OSS_RawOpenDevice(OSS_DEVICE* ossdev, int* frag)
 {
     int fd, val;
 
     if ((fd = open(ossdev->dev_name, ossdev->open_access|O_NDELAY, 0)) == -1)
     {
-        WARN("Couldn't open out %s (%s)\n", ossdev->dev_name, strerror(errno));
-        return -1;
+        WARN("Couldn't open %s (%s)\n", ossdev->dev_name, strerror(errno));
+        return (errno == EBUSY) ? MMSYSERR_ALLOCATED : MMSYSERR_ERROR;
     }
     fcntl(fd, F_SETFD, 1); /* set close on exec flag */
     /* turn full duplex on if it has been requested */
@@ -279,7 +279,8 @@
         if (!NEAR_MATCH(val, ossdev->sample_rate))
             ERR("Can't set sample_rate to %u (%d)\n", ossdev->sample_rate, val);
     }
-    return fd;
+    ossdev->fd = fd;
+    return MMSYSERR_NOERROR;
 }
 
 /******************************************************************
@@ -292,6 +293,8 @@
 static DWORD	OSS_OpenDevice(OSS_DEVICE* ossdev, unsigned req_access,
                                int* frag, int sample_rate, int stereo, int fmt)
 {
+    DWORD       ret;
+
     if (ossdev->full_duplex && (req_access == O_RDONLY || req_access == O_WRONLY))
         req_access = O_RDWR;
 
@@ -307,8 +310,7 @@
         ossdev->open_access = req_access;
         ossdev->owner_tid = GetCurrentThreadId();
 
-        if ((ossdev->fd = OSS_RawOpenDevice(ossdev, frag)) == -1)
-            return MMSYSERR_ERROR;
+        if ((ret = OSS_RawOpenDevice(ossdev, frag)) != MMSYSERR_NOERROR) return ret;
     }
     else
     {
@@ -364,8 +366,10 @@
  * after a SNDCTL_DSP_RESET ioctl call... this function implements
  * this behavior...
  */
-static int     OSS_ResetDevice(OSS_DEVICE* ossdev)
+static DWORD     OSS_ResetDevice(OSS_DEVICE* ossdev)
 {
+    DWORD       ret;
+
     if (ioctl(ossdev->fd, SNDCTL_DSP_RESET, NULL) == -1) 
     {
 	perror("ioctl SNDCTL_DSP_RESET");
@@ -373,9 +377,9 @@
     }
     TRACE("Changing fd from %d to ", ossdev->fd);
     close(ossdev->fd);
-    ossdev->fd = OSS_RawOpenDevice(ossdev, &ossdev->audio_fragment);
+    ret = OSS_RawOpenDevice(ossdev, &ossdev->audio_fragment);
     TRACE("%d\n", ossdev->fd);
-    return ossdev->fd;
+    return ret;
 }
 
 /******************************************************************
@@ -383,7 +387,7 @@
  *
  *
  */
-static void     OSS_WaveOutInit(unsigned devID, OSS_DEVICE* ossdev)
+static BOOL     OSS_WaveOutInit(OSS_DEVICE* ossdev)
 {
     int	                smplrate;
     int	                samplesize = 16;
@@ -392,12 +396,9 @@
     int                 caps;
     int                 mask;
 
-    WOutDev[devID].state = WINE_WS_CLOSED;
-    WOutDev[devID].ossdev = ossdev;
-    memset(&ossdev->out_caps, 0, sizeof(ossdev->out_caps));
+    if (OSS_OpenDevice(ossdev, O_WRONLY, NULL, 0, 0, 0) != 0) return FALSE;
 
-    if (OSS_OpenDevice(WOutDev[devID].ossdev, O_WRONLY, NULL, 0, 0, 0) != 0) return;
-    numOutDev++;
+    memset(&ossdev->out_caps, 0, sizeof(ossdev->out_caps));
 
     ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
 
@@ -480,7 +481,7 @@
     OSS_CloseDevice(ossdev);
     TRACE("out dwFormats = %08lX, dwSupport = %08lX\n",
 	  ossdev->out_caps.dwFormats, ossdev->out_caps.dwSupport);
-
+    return TRUE;
 }
 
 /******************************************************************
@@ -488,7 +489,7 @@
  *
  *
  */
-static void OSS_WaveInInit(unsigned devID, OSS_DEVICE* ossdev)
+static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
 {
     int	                smplrate;
     int	                samplesize = 16;
@@ -497,17 +498,10 @@
     int                 caps;
     int                 mask;
 
-    samplesize = 16;
-    dsp_stereo = 1;
-
-    WInDev[devID].state = WINE_WS_CLOSED;
-    WInDev[devID].ossdev = ossdev;
+    if (OSS_OpenDevice(ossdev, O_RDONLY, NULL, 0, 0, 0) != 0) return FALSE;
 
     memset(&ossdev->in_caps, 0, sizeof(ossdev->in_caps));
 
-    if (OSS_OpenDevice(WInDev[devID].ossdev, O_RDONLY, NULL, 0, 0, 0) != 0) return;
-    numInDev++;
-
     ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
 
 #ifdef EMULATE_SB16
@@ -522,11 +516,11 @@
     ossdev->in_caps.dwFormats = 0x00000000;
     ossdev->in_caps.wChannels = (ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &dsp_stereo) != 0) ? 1 : 2;
 
-    WInDev[devID].bTriggerSupport = FALSE;
+    ossdev->bTriggerSupport = FALSE;
     if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0) {
 	TRACE("OSS dsp in caps=%08X\n", caps);
 	if (caps & DSP_CAP_TRIGGER)
-            WInDev[devID].bTriggerSupport = TRUE;
+            ossdev->bTriggerSupport = TRUE;
     }
 
     ioctl(ossdev->fd, SNDCTL_DSP_GETFMTS, &mask);
@@ -574,6 +568,7 @@
     }
     OSS_CloseDevice(ossdev);
     TRACE("in dwFormats = %08lX\n", ossdev->in_caps.dwFormats);
+    return TRUE;
 }
 
 /******************************************************************
@@ -617,11 +612,25 @@
 
     /* start with output device */
     for (i = 0; i < MAX_WAVEDRV; ++i)
-        OSS_WaveOutInit(i, &OSS_Devices[i]);
+    {
+        if (OSS_WaveOutInit(&OSS_Devices[i]))
+        {
+            WOutDev[numOutDev].state = WINE_WS_CLOSED;
+            WOutDev[numOutDev].ossdev = &OSS_Devices[i];
+            numOutDev++;
+        }
+    }
 
     /* then do input device */
     for (i = 0; i < MAX_WAVEDRV; ++i)
-        OSS_WaveInInit(i, &OSS_Devices[i]);
+    {
+        if (OSS_WaveInInit(&OSS_Devices[i]))
+        {
+            WInDev[numInDev].state = WINE_WS_CLOSED;
+            WInDev[numInDev].ossdev = &OSS_Devices[i];
+            numInDev++;
+        }
+    }
 
     /* finish with the full duplex bits */
     for (i = 0; i < MAX_WAVEDRV; i++)
@@ -948,8 +957,9 @@
      * - we hit the beginning of a running loop
      * - we hit a wavehdr which hasn't finished playing
      */
-    while ((lpWaveHdr = wwo->lpQueuePtr) &&
-           (force ||
+#if 0
+    while ((lpWaveHdr = wwo->lpQueuePtr) && 
+           (force || 
             (lpWaveHdr != wwo->lpPlayPtr &&
              lpWaveHdr != wwo->lpLoopPtr &&
              lpWaveHdr->reserved <= wwo->dwPlayedTotal))) {
@@ -977,7 +1006,7 @@
     wodPlayer_NotifyCompletions(wwo, FALSE);
 
     /* flush all possible output */
-    if (OSS_ResetDevice(wwo->ossdev) == -1)
+    if (OSS_ResetDevice(wwo->ossdev) != MMSYSERR_NOERROR)
     {
 	wwo->hThread = 0;
 	wwo->state = WINE_WS_STOPPED;
@@ -1215,12 +1244,12 @@
 
     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
 
-    if (wDevID >= MAX_WAVEDRV) {
-	TRACE("MAX_WAVDRV reached !\n");
+    if (wDevID >= numOutDev) {
+	TRACE("numOutDev reached !\n");
 	return MMSYSERR_BADDEVICEID;
     }
 
-    memcpy(lpCaps, &OSS_Devices[wDevID].out_caps, min(dwSize, sizeof(*lpCaps)));
+    memcpy(lpCaps, &WOutDev[wDevID].ossdev->out_caps, min(dwSize, sizeof(*lpCaps)));
     return MMSYSERR_NOERROR;
 }
 
@@ -1239,7 +1268,7 @@
 	WARN("Invalid Parameter !\n");
 	return MMSYSERR_INVALPARAM;
     }
-    if (wDevID >= MAX_WAVEDRV) {
+    if (wDevID >= numOutDev) {
 	TRACE("MAX_WAVOUTDRV reached !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1263,12 +1292,13 @@
 
     wwo = &WOutDev[wDevID];
 
-    if ((dwFlags & WAVE_DIRECTSOUND) && !(OSS_Devices[wDevID].out_caps.dwSupport & WAVECAPS_DIRECTSOUND))
+    if ((dwFlags & WAVE_DIRECTSOUND) && 
+        !(wwo->ossdev->out_caps.dwSupport & WAVECAPS_DIRECTSOUND))
 	/* not supported, ignore it */
 	dwFlags &= ~WAVE_DIRECTSOUND;
 
     if (dwFlags & WAVE_DIRECTSOUND) {
-        if (OSS_Devices[wDevID].out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
+        if (wwo->ossdev->out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
 	    /* we have realtime DirectSound, fragments just waste our time,
 	     * but a large buffer is good, so choose 64KB (32 * 2^11) */
 	    audio_fragment = 0x0020000B;
@@ -1366,7 +1396,7 @@
 
     TRACE("(%u);\n", wDevID);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1403,7 +1433,7 @@
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 
     /* first, do the sanity checks... */
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
         WARN("bad dev ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1436,7 +1466,7 @@
 {
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 
-    if (wDevID >= MAX_WAVEDRV) {
+    if (wDevID >= numOutDev) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1456,7 +1486,7 @@
 {
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 
-    if (wDevID >= MAX_WAVEDRV) {
+    if (wDevID >= numOutDev) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1477,7 +1507,7 @@
 {
     TRACE("(%u);!\n", wDevID);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1494,7 +1524,7 @@
 {
     TRACE("(%u);\n", wDevID);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1516,7 +1546,7 @@
 {
     TRACE("(%u);\n", wDevID);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1537,7 +1567,7 @@
 
     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1597,7 +1627,7 @@
 {
     TRACE("(%u);\n", wDevID);
 
-    if (wDevID >= MAX_WAVEDRV || WOutDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numOutDev || WOutDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("bad device ID !\n");
 	return MMSYSERR_BADDEVICEID;
     }
@@ -1618,9 +1648,9 @@
 
     if (lpdwVol == NULL)
 	return MMSYSERR_NOTENABLED;
-    if (wDevID >= MAX_WAVEDRV) return MMSYSERR_INVALPARAM;
+    if (wDevID >= numOutDev) return MMSYSERR_INVALPARAM;
 
-    if ((mixer = open(OSS_Devices[wDevID].mixer_name, O_RDONLY|O_NDELAY)) < 0) {
+    if ((mixer = open(WOutDev[wDevID].ossdev->mixer_name, O_RDONLY|O_NDELAY)) < 0) {
 	WARN("mixer device not available !\n");
 	return MMSYSERR_NOTENABLED;
     }
@@ -1651,9 +1681,9 @@
     right = (HIWORD(dwParam) * 100) / 0xFFFFl;
     volume = left + (right << 8);
 
-    if (wDevID >= MAX_WAVEDRV) return MMSYSERR_INVALPARAM;
+    if (wDevID >= numOutDev) return MMSYSERR_INVALPARAM;
 
-    if ((mixer = open(OSS_Devices[wDevID].mixer_name, O_WRONLY|O_NDELAY)) < 0) {
+    if ((mixer = open(WOutDev[wDevID].ossdev->mixer_name, O_WRONLY|O_NDELAY)) < 0) {
 	WARN("mixer device not available !\n");
 	return MMSYSERR_NOTENABLED;
     }
@@ -1896,7 +1926,7 @@
     if (lpdwPlay) *lpdwPlay = ptr;
     if (lpdwWrite) {
 	/* add some safety margin (not strictly necessary, but...) */
-	if (OSS_Devices[This->drv->wDevID].out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
+	if (WOutDev[This->drv->wDevID].ossdev->out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
 	    *lpdwWrite = ptr + 32;
 	else
 	    *lpdwWrite = ptr + WOutDev[This->drv->wDevID].dwFragmentSize;
@@ -2133,7 +2163,7 @@
     IDsDriverImpl** idrv = (IDsDriverImpl**)drv;
 
     /* the HAL isn't much better than the HEL if we can't do mmap() */
-    if (!(OSS_Devices[wDevID].out_caps.dwSupport & WAVECAPS_DIRECTSOUND)) {
+    if (!(WOutDev[wDevID].ossdev->out_caps.dwSupport & WAVECAPS_DIRECTSOUND)) {
 	ERR("DirectSound flag not set\n");
 	MESSAGE("This sound card's driver does not support direct access\n");
 	MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
@@ -2190,12 +2220,12 @@
 
     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
 
-    if (wDevID >= MAX_WAVEDRV) {
-	TRACE("MAX_WAVDRV reached !\n");
+    if (wDevID >= numInDev) {
+	TRACE("numOutDev reached !\n");
 	return MMSYSERR_BADDEVICEID;
     }
 
-    memcpy(lpCaps, &OSS_Devices[wDevID].in_caps, min(dwSize, sizeof(*lpCaps)));
+    memcpy(lpCaps, &WInDev[wDevID].ossdev->in_caps, min(dwSize, sizeof(*lpCaps)));
     return MMSYSERR_NOERROR;
 }
 
@@ -2348,7 +2378,7 @@
                 int enable = PCM_ENABLE_INPUT;
 		wwi->state = WINE_WS_PLAYING;
 
-                if (wwi->bTriggerSupport)
+                if (wwi->ossdev->bTriggerSupport)
                 {
                     /* start the recording */
                     if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0)
@@ -2424,7 +2454,7 @@
 	WARN("Invalid Parameter !\n");
 	return MMSYSERR_INVALPARAM;
     }
-    if (wDevID >= MAX_WAVEDRV) return MMSYSERR_BADDEVICEID;
+    if (wDevID >= numInDev) return MMSYSERR_BADDEVICEID;
 
     /* only PCM format is supported so far... */
     if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM ||
@@ -2512,7 +2542,7 @@
     WINE_WAVEIN*	wwi;
 
     TRACE("(%u);\n", wDevID);
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't close !\n");
 	return MMSYSERR_INVALHANDLE;
     }
@@ -2539,7 +2569,7 @@
 {
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't do it !\n");
 	return MMSYSERR_INVALHANDLE;
     }
@@ -2568,7 +2598,7 @@
 {
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
 
-    if (wDevID >= MAX_WAVEDRV) return MMSYSERR_INVALHANDLE;
+    if (wDevID >= numInDev) return MMSYSERR_INVALHANDLE;
 
     if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
 	return WAVERR_STILLPLAYING;
@@ -2586,7 +2616,7 @@
 static DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
     TRACE("(%u, %p, %08lX);\n", wDevID, lpWaveHdr, dwSize);
-    if (wDevID >= MAX_WAVEDRV) return MMSYSERR_INVALHANDLE;
+    if (wDevID >= numInDev) return MMSYSERR_INVALHANDLE;
 
     if (lpWaveHdr->dwFlags & WHDR_INQUEUE)
 	return WAVERR_STILLPLAYING;
@@ -2603,7 +2633,7 @@
 static DWORD widStart(WORD wDevID)
 {
     TRACE("(%u);\n", wDevID);
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't start recording !\n");
 	return MMSYSERR_INVALHANDLE;
     }
@@ -2618,7 +2648,7 @@
 static DWORD widStop(WORD wDevID)
 {
     TRACE("(%u);\n", wDevID);
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't stop !\n");
 	return MMSYSERR_INVALHANDLE;
     }
@@ -2634,7 +2664,7 @@
 static DWORD widReset(WORD wDevID)
 {
     TRACE("(%u);\n", wDevID);
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't reset !\n");
 	return MMSYSERR_INVALHANDLE;
     }
@@ -2652,7 +2682,7 @@
 
     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
 
-    if (wDevID >= MAX_WAVEDRV || WInDev[wDevID].state == WINE_WS_CLOSED) {
+    if (wDevID >= numInDev || WInDev[wDevID].state == WINE_WS_CLOSED) {
 	WARN("can't get pos !\n");
 	return MMSYSERR_INVALHANDLE;
     }


More information about the wine-patches mailing list