Cleanup OSS_WaveFullDuplexInit()

Francois Gouget fgouget at codeweavers.com
Tue Jun 15 13:54:22 CDT 2004


OSS_WaveFullDuplexInit() loops on the known formats and makes ioctls to 
set the device formats accordingly. However the only point of these 
loops is to print out traces of the ioctls results. If tracing is off, 
these loops have no effect whatsoever. So this patch moves the loops 
inside the WINE_TRACE_ON(wave) test.

OSS_WaveFullDuplexInit() also checks for SNDCTL_DSP_GETCAPS but it does 
so after the loops. There are two problems with that:
  * since ossdev->full_duplex is not set the OSS_OpenDevice() call will 
open the device in half-duplex mode. So the loops will not test the 
duplex mode at all (they will merely duplicate what OSS_WaveOutInit() 
already did).
  * the OSS documentation states that one must call SNDCTL_SETDUPLEX 
*before* checking for SNDCTL_DSP_GETCAPS. Otherwise the driver may tell 
us that it does not support full-duplex because it's already set up for 
half-duplex mode. So we may fail to detect the full-duplex capabilities. 
In fact we must do SNDCTL_SETDUPLEX ioctl even before setting the 
fragment size so that only OSS_RawOpenDevice is in a position to do it. 
So this patch sets full_duplex=1 speculatively and adjusts it right after.


Changelog:

  * dlls/winmm/wineoss/audio.c

    Francois Gouget <fgouget at codeweavers.com>
    Fix the check for SNDCTL_DSP_GETCAPS so that it is compliant with 
the OSS specification.
    Only test the different formats if tracing is on.

-- 
Francois Gouget
fgouget at codeweavers.com

-------------- next part --------------
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /var/cvs/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.130
diff -u -r1.130 audio.c
--- a/dlls/winmm/wineoss/audio.c	1 Jun 2004 20:22:11 -0000	1.130
+++ b/dlls/winmm/wineoss/audio.c	15 Jun 2004 18:38:30 -0000
@@ -869,7 +870,7 @@
     ossdev->dsc_caps.dwFormats = 0x00000000;
     ossdev->dsc_caps.dwChannels = 1;
 
-    /* See the comment in OSS_WaveOutInit */
+    /* See the comment in OSS_WaveOutInit for the loop order */
     for (f=0;f<2;f++) {
         arg=win_std_oss_fmts[f];
         rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
@@ -933,46 +934,57 @@
     int caps;
     TRACE("(%p) %s\n", ossdev, ossdev->dev_name);
 
-    if (OSS_OpenDevice(ossdev, O_RDWR, NULL, 0,-1,-1,-1) != 0)
+    /* The OSS documentation says we must call SNDCTL_SETDUPLEX
+     * *before* checking for SNDCTL_DSP_GETCAPS otherwise we may
+     * get the wrong result. This ioctl must even be done before
+     * setting the fragment size so that only OSS_RawOpenDevice is
+     * in a position to do it. So we set full_duplex speculatively
+     * and adjust right after.
+     */
+    ossdev->full_duplex=1;
+    rc=OSS_OpenDevice(ossdev, O_RDWR, NULL, 0,-1,-1,-1);
+    ossdev->full_duplex=0;
+    if (rc != 0)
         return;
 
     ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
-
     TRACE("%s\n", ossdev->ds_desc.szDesc);
 
+
+    if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0)
+        ossdev->full_duplex = (caps & DSP_CAP_DUPLEX);
+
     if (WINE_TRACE_ON(wave))
+    {
         OSS_Info(ossdev->fd);
 
-    /* See the comment in OSS_WaveOutInit */
-    for (f=0;f<2;f++) {
-        arg=win_std_oss_fmts[f];
-        rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
-        if (rc!=0 || arg!=win_std_oss_fmts[f]) {
-            TRACE("DSP_SAMPLESIZE: rc=%d returned 0x%x for 0x%x\n",
-                  rc,arg,win_std_oss_fmts[f]);
-            continue;
-        }
-
-        for (c=0;c<2;c++) {
-            arg=c;
-            rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg);
-            if (rc!=0 || arg!=c) {
-                TRACE("DSP_STEREO: rc=%d returned %d for %d\n",rc,arg,c);
+        /* See the comment in OSS_WaveOutInit for the loop order */
+        for (f=0;f<2;f++) {
+            arg=win_std_oss_fmts[f];
+            rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
+            if (rc!=0 || arg!=win_std_oss_fmts[f]) {
+                TRACE("DSP_SAMPLESIZE: rc=%d returned 0x%x for 0x%x\n",
+                      rc,arg,win_std_oss_fmts[f]);
                 continue;
             }
 
-            for (r=0;r<sizeof(win_std_rates)/sizeof(*win_std_rates);r++) {
-                arg=win_std_rates[r];
-                rc=ioctl(ossdev->fd, SNDCTL_DSP_SPEED, &arg);
-                TRACE("DSP_SPEED: rc=%d returned %d for %dx%dx%d\n",
-                      rc,arg,win_std_rates[r],win_std_oss_fmts[f],c+1);
+            for (c=0;c<2;c++) {
+                arg=c;
+                rc=ioctl(ossdev->fd, SNDCTL_DSP_STEREO, &arg);
+                if (rc!=0 || arg!=c) {
+                    TRACE("DSP_STEREO: rc=%d returned %d for %d\n",rc,arg,c);
+                    continue;
+                }
+
+                for (r=0;r<sizeof(win_std_rates)/sizeof(*win_std_rates);r++) {
+                    arg=win_std_rates[r];
+                    rc=ioctl(ossdev->fd, SNDCTL_DSP_SPEED, &arg);
+                    TRACE("DSP_SPEED: rc=%d returned %d for %dx%dx%d\n",
+                          rc,arg,win_std_rates[r],win_std_oss_fmts[f],c+1);
+                }
             }
         }
     }
-
-    if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0)
-        ossdev->full_duplex = (caps & DSP_CAP_DUPLEX);
-
     OSS_CloseDevice(ossdev);
 }
 


More information about the wine-patches mailing list