winearts patch

Eric Pouech pouech-eric at
Wed Jan 7 14:22:33 CST 2004

Jeremy Shaw a écrit :
> Hello,
> This message is largely for Chris Morgan's review, but I thought I
> should open it to any interested parties.
> I have added wave-in support for arts. I also fixed some bugs in the
> waveout code, and made some "improvements". This code seems to work
> really well for me. If no one sees any problems I will submit the
> patch to the patches mailing list.
> Here is a brief description of the changes I made:
> (1) In ARTS_CloseDevice() (now named ARTS_CloseWaveOutDevice()) and
>     wodPlayer_NotifyWait()
> I added 'wwo->sound_buffer = 0' after the HeapFree(). Without it,
> HeapFree() was being called twice on the same buffer, and would crash
> the second time.
Well, I think the bug isn't here but rather in wodPlayer_WriteMaxFrags.
If the buffer is too small:
- we shouldn't destroy the current buffer (and hopefully create a new 
one) but realloc the buffer...
- moreover, destroying the buffer without setting the sound_buffer field 
to NULL is calling for dangling pointers...

> (2) ARTS_AddRingMessage()
> Added the same fix I submitted earlier for wineoss in regards to ring
> buffer resizing.
> (3) wodPlayer_WriteMaxFrags()
> DWORD *bytes, points to the number of bytes the winearts driver thinks
> it should be able to write. However, arts sometimes lies, and says it
> has (for example) 512 bytes available, but when you call arts_write()
> it returns zero bytes written. 
> In that case, I update *bytes to point to 0, otherwise
> wodPlayer_WriteMaxFrags() will keep being called in vain.
correct. It should even be done as soon as we write less bytes than 
expected (content of *byte at upon entry of wodPlayer_WriteMaxFrags)

> (4a) wodPlayer_FeedDSP()
> The old code had the following checks:
>     /* input queue empty and output buffer with no space */
>    if (!wwo->lpPlayPtr && availInQ) {
>          TRACE("Run out of wavehdr:s... flushing\n");
>          wwo->dwPlayedTotal = wwo->dwWrittenTotal;
>          return INFINITE;
>    }
>    if(!availInQ)
>      {
>  	TRACE("no more room, no need to try to feed\n");
> 	return wodPlayer_DSPWait(wwo);
>      }
> I could not understand the purpose of the '&& availInQ' in the first
> check. It seems that if we are out of wavehdrs, then it does not
> matter if there is space in the availInQ or not, because we don't have
> anything to write. So I removed the && availInQ part.
The purpose of the test is to try to always keep the input queue full:
- therefore if we no longer have wave headers to feed the queue with, and
> Looking at it now, I realize that maybe I need to add 'if (!availInQ)'
> before 'wwo->dwPlayedTotal = wwo->dwWrittenTotal'?

IMO, the wwo->dwPlayedTotal = wwo->dwWrittenTotal is wrong in all cases.
If we have no data to write, just way for some new headers to arrive.

> (4b) wodPlayer_FeedDSP()
> In the while loop, I could not figure out the purpose of 'availInQ >
> SPACE_THRESHOLD', so I changed it to 'availInQ'. In reality, the
> SPACE_THRESHOLD check could probably be left in, I am not sure what
> the purpose was in the first place.
Dunno either. Reading Chris response, we need this on OSS (because 
sounds is processed by fragments of fixed size). I don't know how arts 
behaves here... Thrashing it altogether could also work.


More information about the wine-devel mailing list