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@codeweavers.com
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);