The returned result of some audio functions on windows may be inconsistent because a driver may actually supply the returned value.

This presents a problem for the wine regression tests because a buggy driver may return an unexpected result which causes the test to fail. One way around this is to accept known failures as OK but that reduces the usefulness of the test for wine because it may allow wine bugs to slip in. I'm proposing the we determine if we are running on wine by defining a wine manufactures id and checking for that id in the test. If a wine driver is found, don't accept a failure as OK. The returned result should be well defined and any failure is unacceptable. However, if the driver is not a wine driver and there are known buggy windows drivers that return specific errors, we can check for that and not fail the test. This should be easier than maintaining a database of known broken drivers and black listing them.

I am concerned that requiring 100% wine regression test success on windows is not practical when there are broken windows drivers out there. Accepting the failures as success is not good for wine because it may allow buggy wine drivers to also pass. I think we should hold wine audio drivers to higher standards than the typical audio card manufacture.

I am suppling a minimal patch to the alsa driver and a single wave test to illustrate this concept. I hope this allows valid tests to remain in spite of buggy windows drivers.
diff --git a/dlls/winealsa.drv/alsa.h b/dlls/winealsa.drv/alsa.h
index 4cd2cf5..8433c12 100644
--- a/dlls/winealsa.drv/alsa.h
+++ b/dlls/winealsa.drv/alsa.h
@@ -51,6 +51,8 @@ #include "ks.h"
 #include "ksmedia.h"
 #include "ksguid.h"
 
+#define MM_WINE_ALSA_VERSION   0x0100  // driver version
+
 /* state diagram for waveOut writing:
  *
  * +---------+-------------+---------------+---------------------------------+
diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
index 3e791d5..8ac0363 100644
--- a/dlls/winealsa.drv/midi.c
+++ b/dlls/winealsa.drv/midi.c
@@ -1134,10 +1134,10 @@ static void ALSA_AddMidiPort(snd_seq_cli
         * Does not seem to be a problem, because in mmsystem.h only
         * Microsoft's ID is listed.
         */
-       MidiOutDev[MODM_NumDevs].caps.wMid = 0x00FF;
-       MidiOutDev[MODM_NumDevs].caps.wPid = 0x0001;    /* FIXME Product ID  */
-       /* Product Version. We simply say "1" */
-       MidiOutDev[MODM_NumDevs].caps.vDriverVersion = 0x001;
+       MidiOutDev[MODM_NumDevs].caps.wMid = MM_WINE;
+       MidiOutDev[MODM_NumDevs].caps.wPid = MM_WINE_ALSA;      /* Product ID */
+       /* Product Version. */
+       MidiOutDev[MODM_NumDevs].caps.vDriverVersion = MM_WINE_ALSA_VERSION;
        MidiOutDev[MODM_NumDevs].caps.wChannelMask   = 0xFFFF;
 
        /* FIXME Do we have this information?
@@ -1190,10 +1190,10 @@ static void ALSA_AddMidiPort(snd_seq_cli
         * Does not seem to be a problem, because in mmsystem.h only
         * Microsoft's ID is listed.
         */
-       MidiInDev[MIDM_NumDevs].caps.wMid = 0x00FF;
-       MidiInDev[MIDM_NumDevs].caps.wPid = 0x0001;     /* FIXME Product ID  */
-       /* Product Version. We simply say "1" */
-       MidiInDev[MIDM_NumDevs].caps.vDriverVersion = 0x001;
+       MidiInDev[MIDM_NumDevs].caps.wMid = MM_WINE;
+       MidiInDev[MIDM_NumDevs].caps.wPid = MM_WINE_ALSA;       /* Product ID */
+       /* Product Version. */
+       MidiInDev[MIDM_NumDevs].caps.vDriverVersion = MM_WINE_ALSA_VERSION;
 
        /* FIXME Do we have this information?
         * Assuming the soundcards can handle
diff --git a/dlls/winealsa.drv/mixer.c b/dlls/winealsa.drv/mixer.c
index cc38f8f..68d09c6 100644
--- a/dlls/winealsa.drv/mixer.c
+++ b/dlls/winealsa.drv/mixer.c
@@ -54,10 +54,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mixer);
 
 #ifdef HAVE_ALSA
 
-#define        WINE_MIXER_MANUF_ID      0xAA
-#define        WINE_MIXER_PRODUCT_ID    0x55
-#define        WINE_MIXER_VERSION       0x0100
-
 /* Generic notes:
  * In windows it seems to be required for all controls to have a volume switch
  * In alsa that's optional
@@ -797,9 +793,9 @@ static DWORD MIX_GetDevCaps(UINT wDevID,
 
     memset(&capsW, 0, sizeof(MIXERCAPS2W));
 
-    capsW.wMid = WINE_MIXER_MANUF_ID;
-    capsW.wPid = WINE_MIXER_PRODUCT_ID;
-    capsW.vDriverVersion = WINE_MIXER_VERSION;
+    capsW.wMid = MM_WINE;
+    capsW.wPid = MM_WINE_ALSA;
+    capsW.vDriverVersion = MM_WINE_ALSA_VERSION;
 
     lstrcpynW(capsW.szPname, mmixer->mixername, 
sizeof(capsW.szPname)/sizeof(WCHAR));
     capsW.cDestinations = mmixer->dests;
@@ -1421,9 +1417,9 @@ static DWORD MIX_GetLineInfo(UINT wDevID
     else
         Ml->Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;
     Ml->Target.dwDeviceID = 0xFFFFFFFF;
-    Ml->Target.wMid = WINE_MIXER_MANUF_ID;
-    Ml->Target.wPid = WINE_MIXER_PRODUCT_ID;
-    Ml->Target.vDriverVersion = WINE_MIXER_VERSION;
+    Ml->Target.wMid = MM_WINE;
+    Ml->Target.wPid = MM_WINE_ALSA;
+    Ml->Target.vDriverVersion = MM_WINE_ALSA_VERSION;
     lstrcpynW(Ml->Target.szPname, mmixer->mixername, 
sizeof(Ml->Target.szPname)/sizeof(WCHAR));
     return MMSYSERR_NOERROR;
 }
diff --git a/dlls/winealsa.drv/waveinit.c b/dlls/winealsa.drv/waveinit.c
index 1516aa6..8663d47 100644
--- a/dlls/winealsa.drv/waveinit.c
+++ b/dlls/winealsa.drv/waveinit.c
@@ -494,9 +494,9 @@ static int ALSA_AddPlaybackDevice(snd_ct
                         wwo.outcaps.szPname, 
sizeof(wwo.outcaps.szPname)/sizeof(WCHAR));
     wwo.outcaps.szPname[sizeof(wwo.outcaps.szPname)/sizeof(WCHAR) - 1] = '\0';
 
-    wwo.outcaps.wMid = MM_CREATIVE;
-    wwo.outcaps.wPid = MM_CREATIVE_SBP16_WAVEOUT;
-    wwo.outcaps.vDriverVersion = 0x0100;
+    wwo.outcaps.wMid = MM_WINE;
+    wwo.outcaps.wPid = MM_WINA_ALSA;
+    wwo.outcaps.vDriverVersion = MM_WINE_ALSA_VERSION;
 
     rc = ALSA_ComputeCaps(ctl, pcm, &wwo.outcaps.wChannels, 
&wwo.ds_caps.dwFlags,
             &wwo.outcaps.dwFormats, &wwo.outcaps.dwSupport);
@@ -534,9 +534,9 @@ static int ALSA_AddCaptureDevice(snd_ctl
                         wwi.incaps.szPname, sizeof(wwi.incaps.szPname) / 
sizeof(WCHAR));
     wwi.incaps.szPname[sizeof(wwi.incaps.szPname)/sizeof(WCHAR) - 1] = '\0';
 
-    wwi.incaps.wMid = MM_CREATIVE;
-    wwi.incaps.wPid = MM_CREATIVE_SBP16_WAVEOUT;
-    wwi.incaps.vDriverVersion = 0x0100;
+    wwi.incaps.wMid = MM_WINE;
+    wwi.incaps.wPid = MM_WINE_ALSA;
+    wwi.incaps.vDriverVersion = MM_WINE_ALSA_VERSION;
 
     rc = ALSA_ComputeCaps(ctl, pcm, &wwi.incaps.wChannels, 
&wwi.ds_caps.dwFlags,
             &wwi.incaps.dwFormats, &wwi.dwSupport);
diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c
index 2844be4..d902a4a 100644
--- a/dlls/winmm/tests/wave.c
+++ b/dlls/winmm/tests/wave.c
@@ -812,6 +812,7 @@ static void wave_out_test_device(int dev
     SYSTEM_INFO sSysInfo;
     DWORD flOldProtect;
     BOOL res;
+    BOOL wine = FALSE;
 
     GetSystemInfo(&sSysInfo);
     dwPageSize = sSysInfo.dwPageSize;
@@ -821,9 +822,13 @@ static void wave_out_test_device(int dev
        rc==MMSYSERR_NODRIVER,
        "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
        dev_name(device),wave_out_error(rc));
-    if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER)
+    if (rc!=MMSYSERR_NOERROR)
         return;
 
+    /* check for wine manufactures id */
+    if (capsA.wMid == MM_WINE)
+        wine = TRUE;
+
     rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW));
     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
        "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
@@ -854,14 +859,23 @@ static void wave_out_test_device(int dev
     }
 
     rc=waveOutGetDevCapsA(device,&capsA,4);
-    ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM,
-       "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR or MMSYSERR_INVALPARAM "
-       "expected, got %s\n", dev_name(device),wave_out_error(rc));
+    if (wine)  // we really care that wine drivers do the right thing
+        ok(rc==MMSYSERR_NOERROR, "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR "
+           "expected, got %s\n", dev_name(device),wave_out_error(rc));
+    else       // broken Windows drivers may fail so accept known failures
+        ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM,
+           "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR or MMSYSERR_INVALPARAM "
+           "expected, got %s\n", dev_name(device),wave_out_error(rc));
 
     rc=waveOutGetDevCapsW(device,&capsW,4);
-    ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
-       "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
-       "expected, got %s\n",dev_name(device),wave_out_error(rc));
+    if (wine)  // we really care that wine drivers do the right thing
+        ok(rc==MMSYSERR_NOERROR, "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR "
+           "expected, got %s\n",dev_name(device),wave_out_error(rc));
+    else       // broken Windows drivers may fail so accept known failures
+        ok(rc==MMSYSERR_NOERROR || rc== MMSYSERR_INVALPARAM ||
+           rc==MMSYSERR_NOTSUPPORTED, "waveOutGetDevCapsW(%s): " 
+           "MMSYSERR_NOERROR or MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
+           "expected, got %s\n",dev_name(device),wave_out_error(rc));
 
     nameA=NULL;
     rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACESIZE,
diff --git a/include/mmsystem.h b/include/mmsystem.h
index bb13cfd..e232856 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -243,6 +243,7 @@ typedef void (CALLBACK *LPDRVCALLBACK)(H
 
 #define MM_MICROSOFT            1       /* Microsoft Corp. */
 #define MM_CREATIVE             2       /* Creative labs   */
+#define MM_WINE                        255     /* Wine */
 
 #define MM_MIDI_MAPPER          1       /* MIDI Mapper */
 #define MM_WAVE_MAPPER          2       /* Wave Mapper */
@@ -262,6 +263,14 @@ #define MM_PC_JOYSTICK          12      
 
 #define MM_CREATIVE_SBP16_WAVEOUT   104 
 
+#define MM_WINE_ALSA           1
+#define MM_WINE_AUDIOIO                2
+#define MM_WINE_COREAUDIO      3
+#define MM_WINE_ESD            4
+#define MM_WINE_JACK           5
+#define MM_WINE_NAS            6
+#define MM_WINE_OSS            7
+
 UINT           WINAPI  mmsystemGetVersion(void);
 BOOL           WINAPI  sndPlaySoundA(LPCSTR lpszSound, UINT fuSound);
 BOOL           WINAPI  sndPlaySoundW(LPCWSTR lpszSound, UINT fuSound);


Reply via email to