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