Fix for the i810+Alsa+DSound combination
Francois Gouget
fgouget at codeweavers.com
Thu Jan 9 18:43:43 CST 2003
As explained on wine-devel by Ove, the problem with this combination is
that Alsa claims to support a lot of sound formats and does the format
conversion to the one format supported by i810 in software. However in
that case Alsa does not allow mmaping the sound device for obvious
reasons. This caused DirectSound's mmap to fail and DirectSound just
deadlocked.
Instead of deadlocking DirectSound should have just used its HEL
compatibility mode. But that mode did not work because:
1. the wineoss driver would only create the wineoss thread in the
non-direct sound case. However when in HEL mode DSound needs a fully
functional wineoss, and thus that thread.
2. DSound would only initialize the pwave array if the sound driver
(here wineoss) did not support DirectSound. However it would then try to
use it whenever it was unable to obtain a hardware buffer (i.e. whenever
the mmap failed in wineoss's case).
I fixed 1 by always starting the wineoss thread. If the mmap succeeds
then we will not use that thread but that should not be a big issue. In
any case it's not wodOpen's place to decide whether that thread will be
needed or not (this may mean the thread should be created elsewhere e.g.
only when a wineoss call requires this thread to exist).
To fix 2 I moved the pwave initialization around so that we allocate the
pwaves whenever we don't have a hardware buffer and are thus going to be
using them.
Changelog:
* dlls/dsound/dsound_main.c,
dlls/dsound/primary.c,
dlls/winmm/wineoss/audio.c
Initialize the pwave array whenever we don't have a hardware buffer.
Always create the wineoss thread.
Change the mmap ERR into a TRACE: there are normal circumstances
where mmap will fail and we can deal with them.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/dsound/dsound_main.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_main.c,v
retrieving revision 1.69
diff -u -r1.69 dsound_main.c
--- dlls/dsound/dsound_main.c 7 Jan 2003 19:43:18 -0000 1.69
+++ dlls/dsound/dsound_main.c 9 Jan 2003 08:18:26 -0000
@@ -468,10 +469,6 @@
DeleteCriticalSection(&This->mixlock);
if (This->driver) {
IDsDriver_Close(This->driver);
- } else {
- unsigned c;
- for (c=0; c<DS_HEL_FRAGS; c++)
- HeapFree(GetProcessHeap(),0,This->pwave[c]);
}
if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) {
waveOutClose(This->hwo);
@@ -682,28 +683,11 @@
if (drv) {
IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
} else {
- unsigned c;
-
/* FIXME: We should check the device capabilities */
(*ippDS)->drvcaps.dwFlags =
DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO;
if (ds_emuldriver)
(*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
-
- /* Allocate memory for HEL buffer headers */
- for (c=0; c<DS_HEL_FRAGS; c++) {
- (*ippDS)->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
- if (!(*ippDS)->pwave[c]) {
- /* Argh, out of memory */
- while (c--) {
- HeapFree(GetProcessHeap(),0,(*ippDS)->pwave[c]);
- waveOutClose((*ippDS)->hwo);
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return DSERR_OUTOFMEMORY;
- }
- }
- }
}
DSOUND_RecalcVolPan(&((*ippDS)->volpan));
Index: dlls/dsound/primary.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/primary.c,v
retrieving revision 1.4
diff -u -r1.4 primary.c
--- dlls/dsound/primary.c 13 Dec 2002 20:26:23 -0000 1.4
+++ dlls/dsound/primary.c 9 Jan 2003 08:18:27 -0000
@@ -176,6 +180,21 @@
&(This->buflen),&(This->buffer),
(LPVOID*)&(This->hwbuf));
}
+ if (!This->hwbuf) {
+ /* Allocate memory for HEL buffer headers */
+ unsigned c;
+ for (c=0; c<DS_HEL_FRAGS; c++) {
+ This->pwave[c] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
+ if (!This->pwave[c]) {
+ /* Argh, out of memory */
+ while (c--) {
+ HeapFree(GetProcessHeap(),0,This->pwave[c]);
+ }
+ err=DSERR_OUTOFMEMORY;
+ break;
+ }
+ }
+ }
if (err == DS_OK)
err = DSOUND_PrimaryOpen(This);
if (err != DS_OK)
@@ -191,6 +210,11 @@
DSOUND_PrimaryClose(This);
if (This->hwbuf) {
IDsDriverBuffer_Release(This->hwbuf);
+ } else {
+ unsigned c;
+ for (c=0; c<DS_HEL_FRAGS; c++) {
+ HeapFree(GetProcessHeap(),0,This->pwave[c]);
+ }
}
return DS_OK;
}
Index: dlls/winmm/wineoss/audio.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/wineoss/audio.c,v
retrieving revision 1.70
diff -u -r1.70 audio.c
--- dlls/winmm/wineoss/audio.c 7 Jan 2003 23:08:05 -0000 1.70
+++ dlls/winmm/wineoss/audio.c 9 Jan 2003 20:25:47 -0000
@@ -1383,15 +1431,10 @@
OSS_InitRingMessage(&wwo->msgRing);
- if (!(dwFlags & WAVE_DIRECTSOUND)) {
- wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
- wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD)wDevID, 0, &(wwo->dwThreadID));
- WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
- CloseHandle(wwo->hStartUpEvent);
- } else {
- wwo->hThread = INVALID_HANDLE_VALUE;
- wwo->dwThreadID = 0;
- }
+ wwo->hStartUpEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
+ wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)(DWORD)wDevID, 0, &(wwo->dwThreadID));
+ WaitForSingleObject(wwo->hStartUpEvent, INFINITE);
+ CloseHandle(wwo->hStartUpEvent);
wwo->hStartUpEvent = INVALID_HANDLE_VALUE;
TRACE("fd=%d fragmentSize=%ld\n",
@@ -1794,7 +1837,7 @@
wwo->mapping = mmap(NULL, wwo->maplen, PROT_WRITE, MAP_SHARED,
wwo->ossdev->fd, 0);
if (wwo->mapping == (LPBYTE)-1) {
- ERR("(%p): Could not map sound device for direct access (%s)\n", dsdb, strerror(errno));
+ TRACE("(%p): Could not map sound device for direct access (%s)\n", dsdb, strerror(errno));
return DSERR_GENERIC;
}
TRACE("(%p): sound device has been mapped for direct access at %p, size=%ld\n", dsdb, wwo->mapping, wwo->maplen);
More information about the wine-patches
mailing list