[WINMM] more wave callback tests
Robert Reif
reif at earthlink.net
Sun May 7 16:06:04 CDT 2006
This patch adds tests for CALLBACK_FUNCTION and CALLBACK_THREAD. The
only callback type not tested now is CALLBACK_WINDOW.
The wave tests run without error in the interactive mode (full test)
with RH9 and a Sound Blaster Live! using the OSS driver. However they
produce a large number of errors and play bad sounds with the esd driver
and produce a large number of errors with the jack driver. Other
drivers are untested.
Could we please have people run these tests in interactive mode to track
down problems in the sound card drivers?
cd to dlls/winmm/tests and run the test:
WINETEST_INTERACTIVE=1 wine winmm_test.exe.so wave
to determine which drivers, os versions and hardware combinations are
having problems.
These tests can take a long time to run so there is little point in
running them to completion unless you are getting little or no errors.
However, we should make it a goal to get these tests running to
completion in interactive mode with no errors with all drivers someday
(before 1.0?).
Only OSS and ALSA support hardware acceleration in Direct Sound and ALSA
doesn't even do that very well so most non-OSS driver users will be
using the the wave emulation mode of Direct Sound so wave output must be
stable for Direct Sound to work properly.
-------------- next part --------------
Index: dlls/winmm/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/winmm/tests/Makefile.in,v
retrieving revision 1.5
diff -p -u -r1.5 Makefile.in
--- dlls/winmm/tests/Makefile.in 16 Sep 2005 19:40:28 -0000 1.5
+++ dlls/winmm/tests/Makefile.in 7 May 2006 20:32:31 -0000
@@ -3,7 +3,7 @@ TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = winmm.dll
-IMPORTS = winmm kernel32
+IMPORTS = winmm kernel32 user32
CTESTS = \
capture.c \
Index: dlls/winmm/tests/wave.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/tests/wave.c,v
retrieving revision 1.53
diff -p -u -r1.53 wave.c
--- dlls/winmm/tests/wave.c 31 Oct 2005 10:03:25 -0000 1.53
+++ dlls/winmm/tests/wave.c 7 May 2006 20:32:32 -0000
@@ -26,6 +26,7 @@
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
+#include "winuser.h"
#include "winnls.h"
#include "mmsystem.h"
#define NOBITMAP
@@ -286,6 +287,45 @@ const char * wave_open_flags(DWORD flags
return msg;
}
+const char * wave_header_flags(DWORD flags)
+{
+#define WHDR_MASK (WHDR_BEGINLOOP|WHDR_DONE|WHDR_ENDLOOP|WHDR_INQUEUE|WHDR_PREPARED)
+ static char msg[1024];
+ int first = TRUE;
+ msg[0] = 0;
+ if (flags & WHDR_BEGINLOOP) {
+ strcat(msg, "WHDR_BEGINLOOP");
+ first = FALSE;
+ }
+ if (flags & WHDR_DONE) {
+ if (!first) strcat(msg, " ");
+ strcat(msg, "WHDR_DONE");
+ first = FALSE;
+ }
+ if (flags & WHDR_ENDLOOP) {
+ if (!first) strcat(msg, " ");
+ strcat(msg, "WHDR_ENDLOOP");
+ first = FALSE;
+ }
+ if (flags & WHDR_INQUEUE) {
+ if (!first) strcat(msg, " ");
+ strcat(msg, "WHDR_INQUEUE");
+ first = FALSE;
+ }
+ if (flags & WHDR_PREPARED) {
+ if (!first) strcat(msg, " ");
+ strcat(msg, "WHDR_PREPARED");
+ first = FALSE;
+ }
+ if (flags & ~WHDR_MASK) {
+ char temp[32];
+ sprintf(temp, "UNKNOWN(0x%08lx)", flags & ~WHDR_MASK);
+ if (!first) strcat(msg, " ");
+ strcat(msg, temp);
+ }
+ return msg;
+}
+
static const char * wave_out_caps(DWORD dwSupport)
{
#define ADD_FLAG(f) if (dwSupport & f) strcat(msg, " " #f)
@@ -482,6 +522,23 @@ static void check_position(int device, H
dev_name(device));
}
+static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg,
+ DWORD_PTR dwInstance,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ SetEvent((HANDLE)dwInstance);
+}
+
+static DWORD WINAPI callback_thread(LPVOID lpParameter)
+{
+ MSG msg;
+
+ while (GetMessage(&msg, 0, 0, 0))
+ SetEvent((HANDLE)lpParameter);
+
+ return 0;
+}
+
static void wave_out_test_deviceOut(int device, double duration,
LPWAVEFORMATEX pwfx, DWORD format,
DWORD flags, LPWAVEOUTCAPS pcaps,
@@ -498,14 +555,43 @@ static void wave_out_test_deviceOut(int
BOOL has_volume = pcaps->dwSupport & WAVECAPS_VOLUME;
double paused = 0.0;
double actual;
+ DWORD callback = 0;
+ DWORD callback_instance = 0;
+ HANDLE thread = 0;
hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
ok(hevent!=NULL,"CreateEvent(): error=%ld\n",GetLastError());
if (hevent==NULL)
return;
+ if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) {
+ callback = (DWORD)hevent;
+ callback_instance = 0;
+ } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
+ callback = (DWORD)callback_func;
+ callback_instance = (DWORD)hevent;
+ } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
+ DWORD thread_id;
+ thread = CreateThread(NULL, 0, callback_thread, hevent, 0, &thread_id);
+ if (thread) {
+ callback = thread_id;
+ callback_instance = 0;
+ } else {
+ trace("CreateThread() failed\n");
+ return;
+ }
+ } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
+ trace("CALLBACK_THREAD not implemented\n");
+ return;
+ } else if (flags && CALLBACK_TYPEMASK) {
+ trace("Undefined callback type!\n");
+ return;
+ } else {
+ trace("CALLBACK_NULL not implemented\n");
+ return;
+ }
wout=NULL;
- rc=waveOutOpen(&wout,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
+ rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags);
/* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
/* It is acceptable to fail on formats that are not specified to work */
ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
@@ -533,6 +619,8 @@ static void wave_out_test_deviceOut(int
flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
if (rc!=MMSYSERR_NOERROR) {
+ if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD)
+ TerminateThread(thread, 0);
CloseHandle(hevent);
return;
}
@@ -566,8 +654,7 @@ static void wave_out_test_deviceOut(int
sine ? "440Hz tone" : "silence",pwfx->nSamplesPerSec,
pwfx->wBitsPerSample,pwfx->nChannels,
get_format_str(pwfx->wFormatTag),
- flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
- flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
+ wave_open_flags(flags));
if (sine && !volume)
trace("*** Warning the sound is muted, you will not hear the test\n");
@@ -588,6 +675,19 @@ static void wave_out_test_deviceOut(int
ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
dev_name(device),wave_out_error(rc));
+ ok(frag.dwFlags==(WHDR_PREPARED|WHDR_INQUEUE),
+ "WHDR_INQUEUE WHDR_PREPARED expected, got= %s\n",
+ wave_header_flags(frag.dwFlags));
+
+ rc=waveOutWrite(wout, &frag, sizeof(frag));
+ ok(rc==WAVERR_STILLPLAYING,
+ "waveOutWrite(%s): WAVE_STILLPLAYING expected, got %s\n",
+ dev_name(device),wave_out_error(rc));
+
+ ok(frag.dwFlags==(WHDR_PREPARED|WHDR_INQUEUE),
+ "WHDR_INQUEUE WHDR_PREPARED expected, got %s\n",
+ wave_header_flags(frag.dwFlags));
+
if (pause) {
paused = duration / 2;
Sleep(paused * 1000);
@@ -612,7 +712,9 @@ static void wave_out_test_deviceOut(int
(actual < (1.1 * (duration+paused))),
"The sound played for %g ms instead of %g ms\n",
1000*actual,1000*(duration+paused));
-
+ ok(frag.dwFlags=(WHDR_DONE|WHDR_PREPARED),
+ "WHDR_DONE WHDR_PREPARED expected, got %s\n",
+ wave_header_flags(frag.dwFlags));
check_position(device, wout, frag.dwBufferLength, pwfx);
}
@@ -626,6 +728,8 @@ static void wave_out_test_deviceOut(int
rc=waveOutClose(wout);
ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
wave_out_error(rc));
+ if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD)
+ TerminateThread(thread, 0);
}
static void wave_out_test_device(int device)
@@ -740,8 +844,12 @@ static void wave_out_test_device(int dev
format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
format.cbSize=0;
- wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,0,&capsA,
- TRUE,TRUE,FALSE);
+ wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE);
+ wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_FUNCTION,&capsA,TRUE,TRUE,FALSE);
+ wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_THREAD,&capsA,TRUE,TRUE,FALSE);
} else {
format.wFormatTag=WAVE_FORMAT_PCM;
format.nChannels=1;
@@ -750,10 +858,18 @@ static void wave_out_test_device(int dev
format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
format.cbSize=0;
- wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,0,&capsA,
- TRUE,FALSE,FALSE);
- wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,0,&capsA,
- TRUE,FALSE,TRUE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_EVENT,&capsA,TRUE,FALSE,TRUE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_FUNCTION,&capsA,TRUE,FALSE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_FUNCTION,&capsA,TRUE,FALSE,TRUE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_THREAD,&capsA,TRUE,FALSE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,
+ CALLBACK_THREAD,&capsA,TRUE,FALSE,TRUE);
}
for (f=0;f<NB_WIN_FORMATS;f++) {
@@ -765,18 +881,45 @@ static void wave_out_test_device(int dev
format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
format.cbSize=0;
wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
- 0,&capsA,winetest_interactive,TRUE,FALSE);
- if (winetest_interactive)
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_FUNCTION,&capsA,winetest_interactive,
+ TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_THREAD,&capsA,winetest_interactive,
+ TRUE,FALSE);
+ if (winetest_interactive) {
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,TRUE);
wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
- 0,&capsA,winetest_interactive,TRUE,TRUE);
+ CALLBACK_FUNCTION,&capsA,winetest_interactive,
+ TRUE,TRUE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_THREAD,&capsA,winetest_interactive,
+ TRUE,TRUE);
+ }
if (device != WAVE_MAPPER)
{
wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
- WAVE_FORMAT_DIRECT,&capsA,winetest_interactive,
- TRUE,FALSE);
+ CALLBACK_EVENT|WAVE_FORMAT_DIRECT,&capsA,
+ winetest_interactive,TRUE,FALSE);
wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
- WAVE_MAPPED,&capsA,winetest_interactive,
- TRUE,FALSE);
+ CALLBACK_EVENT|WAVE_MAPPED,&capsA,
+ winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_FUNCTION|WAVE_FORMAT_DIRECT,&capsA,
+ winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_FUNCTION|WAVE_MAPPED,&capsA,
+ winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_THREAD|WAVE_FORMAT_DIRECT,&capsA,
+ winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
+ CALLBACK_THREAD|WAVE_MAPPED,&capsA,
+ winetest_interactive,TRUE,FALSE);
}
}
@@ -798,16 +941,17 @@ static void wave_out_test_device(int dev
pwfx->nSamplesPerSec=22050;
pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
- wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
if (device != WAVE_MAPPER)
{
wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
- WAVE_FORMAT_DIRECT,&capsA,
- winetest_interactive,TRUE,FALSE);
+ CALLBACK_EVENT|WAVE_FORMAT_DIRECT,
+ &capsA,winetest_interactive,TRUE,FALSE);
wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
- WAVE_MAPPED,&capsA,winetest_interactive,
- TRUE,FALSE);
+ CALLBACK_EVENT|WAVE_MAPPED,&capsA,
+ winetest_interactive,TRUE,FALSE);
}
}
VirtualFree(twoPages, 0, MEM_RELEASE);
@@ -874,7 +1018,7 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&format,0,0,
+ wave_out_test_deviceOut(device,1.0,&format,0,CALLBACK_EVENT,
&capsA,winetest_interactive,TRUE,FALSE);
} else
trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
@@ -894,7 +1038,7 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&format,0,0,
+ wave_out_test_deviceOut(device,1.0,&format,0,CALLBACK_EVENT,
&capsA,winetest_interactive,TRUE,FALSE);
} else
trace("waveOutOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
@@ -919,8 +1063,9 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
} else
trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
dev_name(device));
@@ -944,7 +1089,7 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,0,0,
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,0,CALLBACK_EVENT,
&capsA,winetest_interactive,TRUE,FALSE);
} else
trace("waveOutOpen(%s): 4 channels not supported\n",
@@ -969,8 +1114,9 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
} else
trace("waveOutOpen(%s): 6 channels not supported\n",
dev_name(device));
@@ -995,8 +1141,9 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
} else
trace("waveOutOpen(%s): 24 bit samples not supported\n",
dev_name(device));
@@ -1021,8 +1168,9 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
} else
trace("waveOutOpen(%s): 32 bit samples not supported\n",
dev_name(device));
@@ -1046,8 +1194,9 @@ static void wave_out_test_device(int dev
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
if (rc==MMSYSERR_NOERROR) {
waveOutClose(wout);
- wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
- &capsA,winetest_interactive,TRUE,FALSE);
+ wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,
+ CALLBACK_EVENT,&capsA,winetest_interactive,
+ TRUE,FALSE);
} else
trace("waveOutOpen(%s): 32 bit float samples not supported\n",
dev_name(device));
More information about the wine-patches
mailing list