wineoss mixer patch

Robert Reif reif at earthlink.net
Thu Aug 19 17:45:23 CDT 2004


Change step size from 0 to 1 for volume controls to stop divide by zero 
in app.
Change debug channel to mixer.
Add more tracing and errors.

-------------- next part --------------
Index: dlls/winmm/wineoss/mixer.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/wineoss/mixer.c,v
retrieving revision 1.23
diff -u -r1.23 mixer.c
--- dlls/winmm/wineoss/mixer.c	11 Aug 2004 18:48:46 -0000	1.23
+++ dlls/winmm/wineoss/mixer.c	19 Aug 2004 22:40:39 -0000
@@ -45,10 +45,12 @@
 #include "oss.h"
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
+WINE_DEFAULT_DEBUG_CHANNEL(mixer);
 
 #ifdef HAVE_OSS
 
+#define MAX_MIXERDRV     (6)
+
 #define	WINE_MIXER_MANUF_ID		0xAA
 #define	WINE_MIXER_PRODUCT_ID		0x55
 #define	WINE_MIXER_VERSION		0x0100
@@ -96,7 +98,7 @@
 #define LINEID_RECORD	0x0001
 
 static int		MIX_NumMixers;
-static struct mixer	MIX_Mixers[1];
+static struct mixer	MIX_Mixers[MAX_MIXERDRV];
 
 /**************************************************************************
  * 				MIX_FillLineControls		[internal]
@@ -106,6 +108,8 @@
     struct mixerCtrl* 	mc = &mix->ctrl[c];
     int			j;
 
+    TRACE("(%p, %d, %ld, %08lx)\n", mix, c, lineID, dwType);
+
     mc->dwLineID = lineID;
     mc->ctrl.cbStruct = sizeof(MIXERCONTROLA);
     mc->ctrl.dwControlID = c + 1;
@@ -127,6 +131,7 @@
 	mc->ctrl.Bounds.s1.dwMinimum = 0;
 	mc->ctrl.Bounds.s1.dwMaximum = 65535;
 	memset(&mc->ctrl.Metrics, 0, sizeof(mc->ctrl.Metrics));
+        mc->ctrl.Metrics.cSteps = 1;
 	break;
     case MIXERCONTROL_CONTROLTYPE_MUTE:
     case MIXERCONTROL_CONTROLTYPE_ONOFF:
@@ -165,7 +170,11 @@
  */
 static struct mixer*	MIX_Get(WORD wDevID)
 {
-    if (wDevID >= MIX_NumMixers || MIX_Mixers[wDevID].name == NULL) return NULL;
+    TRACE("(%04x)\n", wDevID);
+
+    if (wDevID >= MIX_NumMixers || MIX_Mixers[wDevID].name == NULL)
+        return NULL;
+
     return &MIX_Mixers[wDevID];
 }
 
@@ -187,13 +196,17 @@
      * messages to it... it seems to be linked to all the equivalent of mixer identification
      * (with a reference to a wave, midi.. handle
      */
-    if (!(mix = MIX_Get(wDevID))) return MMSYSERR_BADDEVICEID;
+    if (!(mix = MIX_Get(wDevID))) {
+        WARN("bad device ID\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     if ((mixer = open(mix->name, O_RDWR)) < 0)
     {
 	if (errno == ENODEV || errno == ENXIO)
 	{
 	    /* no driver present */
+            WARN("no driver\n");
 	    return MMSYSERR_NODRIVER;
 	}
 	return MMSYSERR_ERROR;
@@ -201,20 +214,24 @@
 
     if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mix->devMask) == -1)
     {
-	perror("ioctl mixer SOUND_MIXER_DEVMASK");
+	ERR("ioctl(%s, SOUND_MIXER_DEVMASK) failed (%s)\n",
+            mix->name, strerror(errno));
 	ret = MMSYSERR_ERROR;
 	goto error;
     }
+
     mix->devMask &= WINE_MIXER_MASK_SPEAKER;
     if (mix->devMask == 0)
     {
+        WARN("no driver\n");
 	ret = MMSYSERR_NODRIVER;
 	goto error;
     }
 
     if (ioctl(mixer, SOUND_MIXER_READ_STEREODEVS, &mix->stereoMask) == -1)
     {
-	perror("ioctl mixer SOUND_MIXER_STEREODEVS");
+	ERR("ioctl(%s, SOUND_MIXER_STEREODEVS) failed (%s)\n",
+            mix->name, strerror(errno));
 	ret = MMSYSERR_ERROR;
 	goto error;
     }
@@ -222,7 +239,8 @@
 
     if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &mix->recMask) == -1)
     {
-	perror("ioctl mixer SOUND_MIXER_RECMASK");
+	ERR("ioctl(%s, SOUND_MIXER_RECMASK) failed (%s)\n",
+            mix->name, strerror(errno));
 	ret = MMSYSERR_ERROR;
 	goto error;
     }
@@ -236,7 +254,8 @@
     }
     if (ioctl(mixer, SOUND_MIXER_READ_CAPS, &caps) == -1)
     {
-	perror("ioctl mixer SOUND_MIXER_READ_CAPS");
+	ERR("ioctl(%s, SOUND_MIXER_READ_CAPS) failed (%s)\n",
+            mix->name, strerror(errno));
 	ret = MMSYSERR_ERROR;
 	goto error;
     }
@@ -258,7 +277,7 @@
 	    mix->numCtrl += 2; /* volume & onoff */
 
     }
-    if (!(mix->ctrl = HeapAlloc(GetProcessHeap(), 0, sizeof(mix->ctrl[0]) * mix->numCtrl)))
+    if (!(mix->ctrl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(mix->ctrl[0]) * mix->numCtrl)))
     {
 	ret = MMSYSERR_NOMEM;
 	goto error;
@@ -305,6 +324,8 @@
     int		mixer;
     BOOL	ret = FALSE;
 
+    TRACE("(%p, %d, %p\n", mix, chn, val);
+
     if ((mixer = open(mix->name, O_RDWR)) < 0)
     {
 	/* FIXME: ENXIO => no mixer installed */
@@ -330,7 +351,7 @@
     int		mixer;
     BOOL	ret = FALSE;
 
-    TRACE("Writing volume %x on %d\n", val, chn);
+    TRACE("(%p, %d, %x\n", mix, chn, val);
 
     if ((mixer = open(mix->name, O_RDWR)) < 0)
     {
@@ -358,6 +379,8 @@
     int		mixer;
     BOOL	ret = FALSE;
 
+    TRACE("(%p, %p)\n", mix, mask);
+
     if ((mixer = open(mix->name, O_RDWR)) >= 0)
     {
 	if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &mask) >= 0) ret = TRUE;
@@ -376,6 +399,8 @@
     int		mixer;
     BOOL	ret = FALSE;
 
+    TRACE("(%p, %08x)\n", mix, mask);
+
     if ((mixer = open(mix->name, O_RDWR)) >= 0)
     {
 	if (ioctl(mixer, SOUND_MIXER_WRITE_RECSRC, &mask) < 0)
@@ -399,8 +424,15 @@
 
     TRACE("(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
 
-    if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
-    if (!(mix = MIX_Get(wDevID))) return MMSYSERR_BADDEVICEID;
+    if (lpCaps == NULL) {
+        WARN("invalid parameter: lpCaps == NULL\n");
+        return MMSYSERR_INVALPARAM;
+    }
+
+    if (!(mix = MIX_Get(wDevID))) {
+        WARN("bad device ID\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     capsA.wMid = WINE_MIXER_MANUF_ID;
     capsA.wPid = WINE_MIXER_PRODUCT_ID;
@@ -423,6 +455,8 @@
     unsigned mask;
     int	j;
 
+    TRACE("(%p, %p, %08lx)\n", mix, lpMl, dst);
+
     lpMl->dwDestination = dst;
     switch (dst)
     {
@@ -469,6 +503,8 @@
     int		i, j;
     unsigned	mask = (dst) ? mix->recMask : mix->devMask;
 
+    TRACE("(%p, %p, %ld, %08lx)\n", mix, lpMl, idx, dst);
+
     strcpy(lpMl->szShortName, MIX_Labels[idx]);
     strcpy(lpMl->szName, MIX_Names[idx]);
     lpMl->dwLineID = MAKELONG(dst, idx);
@@ -529,6 +565,8 @@
  */
 static BOOL MIX_CheckLine(DWORD lineID)
 {
+    TRACE("(%08lx)\n",lineID);
+
     return ((HIWORD(lineID) < SOUND_MIXER_NRDEVICES && LOWORD(lineID) < 2) ||
 	    (HIWORD(lineID) == LINEID_DST && LOWORD(lineID) < SOUND_MIXER_NRDEVICES));
 }
@@ -545,9 +583,15 @@
 
     TRACE("(%04X, %p, %lu);\n", wDevID, lpMl, fdwInfo);
 
-    if (lpMl == NULL || lpMl->cbStruct != sizeof(*lpMl))
+    if (lpMl == NULL || lpMl->cbStruct != sizeof(*lpMl)) {
+        WARN("invalid parameter\n");
 	return MMSYSERR_INVALPARAM;
-    if ((mix = MIX_Get(wDevID)) == NULL) return MMSYSERR_BADDEVICEID;
+    }
+
+    if ((mix = MIX_Get(wDevID)) == NULL) {
+        WARN("bad device ID\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     /* FIXME: set all the variables correctly... the lines below
      * are very wrong...
@@ -559,8 +603,10 @@
     {
     case MIXER_GETLINEINFOF_DESTINATION:
 	TRACE("DESTINATION (%08lx)\n", lpMl->dwDestination);
-	if (lpMl->dwDestination >= 2)
+	if (lpMl->dwDestination >= 2) {
+            WARN("invalid parameter\n");
 	    return MMSYSERR_INVALPARAM;
+        }
 	if ((ret = MIX_GetLineInfoDst(mix, lpMl, lpMl->dwDestination)) != MMSYSERR_NOERROR)
 	    return ret;
 	break;
@@ -570,7 +616,9 @@
 	{
 	case 0: mask = mix->devMask; break;
 	case 1: mask = mix->recMask; break;
-	default: return MMSYSERR_INVALPARAM;
+	default: 
+            WARN("invalid parameter\n");
+            return MMSYSERR_INVALPARAM;
 	}
 	i = lpMl->dwSource;
 	for (j = 0; j < SOUND_MIXER_NRDEVICES; j++)
@@ -578,16 +626,20 @@
 	    if (WINE_CHN_SUPPORTS(mask, j) && (i-- == 0))
 		break;
 	}
-	if (j >= SOUND_MIXER_NRDEVICES)
+	if (j >= SOUND_MIXER_NRDEVICES) {
+            WARN("invalid line\n");
 	    return MIXERR_INVALLINE;
+        }
 	if ((ret = MIX_GetLineInfoSrc(mix, lpMl, j, lpMl->dwDestination)) != MMSYSERR_NOERROR)
 	    return ret;
 	break;
     case MIXER_GETLINEINFOF_LINEID:
 	TRACE("LINEID (%08lx)\n", lpMl->dwLineID);
 
-	if (!MIX_CheckLine(lpMl->dwLineID))
+	if (!MIX_CheckLine(lpMl->dwLineID)) {
+            WARN("invalid line\n");
 	    return MIXERR_INVALLINE;
+        }
 	if (HIWORD(lpMl->dwLineID) == LINEID_DST)
 	    ret = MIX_GetLineInfoDst(mix, lpMl, LOWORD(lpMl->dwLineID));
 	else
@@ -658,18 +710,29 @@
 /**************************************************************************
  * 				MIX_GetLineControls		[internal]
  */
-static	DWORD	MIX_GetLineControls(WORD wDevID, LPMIXERLINECONTROLSA lpMlc, DWORD flags)
+static	DWORD	MIX_GetLineControls(WORD wDevID, LPMIXERLINECONTROLSA lpMlc,
+                                    DWORD flags)
 {
     DWORD		dwRet = MMSYSERR_NOERROR;
     struct mixer*	mix;
 
     TRACE("(%04X, %p, %lu);\n", wDevID, lpMlc, flags);
 
-    if (lpMlc == NULL) return MMSYSERR_INVALPARAM;
+    if (lpMlc == NULL) {
+        WARN("invalid parameter: lpMlc == NULL\n");
+        return MMSYSERR_INVALPARAM;
+    }
+
     if (lpMlc->cbStruct < sizeof(*lpMlc) ||
-	lpMlc->cbmxctrl < sizeof(MIXERCONTROLA))
+	lpMlc->cbmxctrl < sizeof(MIXERCONTROLA)) {
+        WARN("invalid parameter: lpMlc\n");
 	return MMSYSERR_INVALPARAM;
-    if ((mix = MIX_Get(wDevID)) == NULL) return MMSYSERR_BADDEVICEID;
+    }
+
+    if ((mix = MIX_Get(wDevID)) == NULL) {
+        WARN("bad device id\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     switch (flags & MIXER_GETLINECONTROLSF_QUERYMASK)
     {
@@ -677,22 +740,28 @@
         {
 	    int		i, j;
 
-	    TRACE("line=%08lx GLCF_ALL (%ld)\n", lpMlc->dwLineID, lpMlc->cControls);
+	    TRACE("line=%08lx GLCF_ALL (%ld)\n", lpMlc->dwLineID,
+                  lpMlc->cControls);
 
 	    for (i = j = 0; i < mix->numCtrl; i++)
 	    {
 		if (mix->ctrl[i].dwLineID == lpMlc->dwLineID)
 		    j++;
 	    }
-	    if (!j || lpMlc->cControls != j)		dwRet = MMSYSERR_INVALPARAM;
-	    else if (!MIX_CheckLine(lpMlc->dwLineID))	dwRet = MIXERR_INVALLINE;
-	    else
-	    {
+
+	    if (!j || lpMlc->cControls != j) {
+                WARN("invalid parameter\n");
+                dwRet = MMSYSERR_INVALPARAM;
+	    } else if (!MIX_CheckLine(lpMlc->dwLineID)) {
+                WARN("invalid line\n");
+                dwRet = MIXERR_INVALLINE;
+	    } else {
 		for (i = j = 0; i < mix->numCtrl; i++)
 		{
 		    if (mix->ctrl[i].dwLineID == lpMlc->dwLineID)
 		    {
-			TRACE("[%d] => [%2d]: typ=%08lx\n", j, i + 1, mix->ctrl[i].ctrl.dwControlType);
+			TRACE("[%d] => [%2d]: typ=%08lx\n", j, i + 1,
+                              mix->ctrl[i].ctrl.dwControlType);
 			lpMlc->pamxctrl[j++] = mix->ctrl[i].ctrl;
 		    }
 		}
@@ -700,32 +769,38 @@
 	}
 	break;
     case MIXER_GETLINECONTROLSF_ONEBYID:
-	TRACE("line=%08lx GLCF_ONEBYID (%lx)\n", lpMlc->dwLineID, lpMlc->u.dwControlID);
+	TRACE("line=%08lx GLCF_ONEBYID (%lx)\n", lpMlc->dwLineID,
+              lpMlc->u.dwControlID);
 
 	if (!MIX_CheckControl(mix, lpMlc->u.dwControlID) ||
-	    mix->ctrl[lpMlc->u.dwControlID - 1].dwLineID != lpMlc->dwLineID)
+	    mix->ctrl[lpMlc->u.dwControlID - 1].dwLineID != lpMlc->dwLineID) {
+            WARN("invalid parameter\n");
 	    dwRet = MMSYSERR_INVALPARAM;
-	else
+	} else
 	    lpMlc->pamxctrl[0] = mix->ctrl[lpMlc->u.dwControlID - 1].ctrl;
 	break;
     case MIXER_GETLINECONTROLSF_ONEBYTYPE:
-	TRACE("line=%08lx GLCF_ONEBYTYPE (%lx)\n", lpMlc->dwLineID, lpMlc->u.dwControlType);
-	if (!MIX_CheckLine(lpMlc->dwLineID))	dwRet = MIXERR_INVALLINE;
-	else
-	{
-	    int		i;
-	    DWORD	ct = lpMlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK;
-
-	    for (i = 0; i < mix->numCtrl; i++)
-	    {
+	TRACE("line=%08lx GLCF_ONEBYTYPE (%lx)\n", lpMlc->dwLineID,
+              lpMlc->u.dwControlType);
+	if (!MIX_CheckLine(lpMlc->dwLineID)) {
+            WARN("invalid line\n");
+            dwRet = MIXERR_INVALLINE;
+	} else {
+	    int	  i;
+	    DWORD ct = lpMlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK;
+	    for (i = 0; i < mix->numCtrl; i++) {
 		if (mix->ctrl[i].dwLineID == lpMlc->dwLineID &&
-		    ct == (mix->ctrl[i].ctrl.dwControlType & MIXERCONTROL_CT_CLASS_MASK))
-		{
+		    ct == (mix->ctrl[i].ctrl.dwControlType &
+                    MIXERCONTROL_CT_CLASS_MASK)) {
 		    lpMlc->pamxctrl[0] = mix->ctrl[i].ctrl;
 		    break;
 		}
 	    }
-	    if (i == mix->numCtrl) dwRet = MMSYSERR_INVALPARAM;
+
+	    if (i == mix->numCtrl) {
+                WARN("invalid parameter\n");
+                dwRet = MMSYSERR_INVALPARAM;
+            }
 	}
 	break;
     default:
@@ -747,8 +822,15 @@
 
     TRACE("(%04X, %p, %lu);\n", wDevID, lpmcd, fdwDetails);
 
-    if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
-    if ((mix = MIX_Get(wDevID)) == NULL) return MMSYSERR_BADDEVICEID;
+    if (lpmcd == NULL) {
+        WARN("invalid parameter: lpmcd == NULL\n");
+        return MMSYSERR_INVALPARAM;
+    }
+
+    if ((mix = MIX_Get(wDevID)) == NULL) {
+        WARN("bad device ID\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK)
     {
@@ -895,8 +977,15 @@
 
     TRACE("(%04X, %p, %lu);\n", wDevID, lpmcd, fdwDetails);
 
-    if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
-    if ((mix = MIX_Get(wDevID)) == NULL) return MMSYSERR_BADDEVICEID;
+    if (lpmcd == NULL) {
+        TRACE("invalid parameter: lpmcd == NULL\n");
+        return MMSYSERR_INVALPARAM;
+    }
+
+    if ((mix = MIX_Get(wDevID)) == NULL) {
+        WARN("bad device ID\n");
+        return MMSYSERR_BADDEVICEID;
+    }
 
     switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK)
     {
@@ -1025,12 +1114,15 @@
 {
     int	mixer;
 
+    TRACE("()\n");
+
 #define MIXER_DEV "/dev/mixer"
     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
     {
 	if (errno == ENODEV || errno == ENXIO)
 	{
 	    /* no driver present */
+            WARN("no driver\n");
 	    return MMSYSERR_NODRIVER;
 	}
 	MIX_NumMixers = 0;
@@ -1049,6 +1141,8 @@
  */
 static	DWORD	MIX_GetNumDevs(void)
 {
+    TRACE("()\n");
+
     return MIX_NumMixers;
 }
 
@@ -1060,7 +1154,7 @@
 DWORD WINAPI OSS_mxdMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
 			    DWORD dwParam1, DWORD dwParam2)
 {
-/* TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2); */
+    TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
 
 #ifdef HAVE_OSS
     switch (wMsg)


More information about the wine-patches mailing list