WINEALSA: comment on unexpected shrinking of mmap-buffer
(resend)
Alex Villacís Lasso
a_villacis at palosanto.com
Thu Sep 1 11:11:32 CDT 2005
Robert Reif wrote:
> Alex Villacís Lasso wrote:
>
>> Robert Reif wrote:
>>
>>> Fix the wine ALSA driver rather than the test unless you can prove
>>> that the test fails on Windows.
>>>
> Hers is a real quick hack that fixes the problem. This should give
> you someplace to start.
>
>------------------------------------------------------------------------
>
>? audio.c.test
>? audio.diff
>Index: audio.c
>===================================================================
>RCS file: /home/wine/wine/dlls/winmm/winealsa/audio.c,v
>retrieving revision 1.96
>diff -p -u -r1.96 audio.c
>--- audio.c 12 Aug 2005 11:17:54 -0000 1.96
>+++ audio.c 31 Aug 2005 00:59:33 -0000
>@@ -2527,14 +2527,16 @@ static DWORD wodOpen(WORD wDevID, LPWAVE
> getFormat(wwo->format.Format.wFormatTag));
>
> dir=0;
>- EXIT_ON_ERROR( snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_time, &dir), MMSYSERR_INVALPARAM, "unable to set buffer time");
>+// EXIT_ON_ERROR( snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_time, &dir), MMSYSERR_INVALPARAM, "unable to set buffer time");
>+ buffer_size = 0x10000;
>+ EXIT_ON_ERROR( snd_pcm_hw_params_set_buffer_size_near(pcm, hw_params, &buffer_size), MMSYSERR_INVALPARAM, "unable to set buffer size");
> dir=0;
> EXIT_ON_ERROR( snd_pcm_hw_params_set_period_time_near(pcm, hw_params, &period_time, &dir), MMSYSERR_INVALPARAM, "unable to set period time");
>
> EXIT_ON_ERROR( snd_pcm_hw_params(pcm, hw_params), MMSYSERR_INVALPARAM, "unable to set hw params for playback");
>
> err = snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
>- err = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
>+// err = snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
>
> snd_pcm_sw_params_current(pcm, sw_params);
> EXIT_ON_ERROR( snd_pcm_sw_params_set_start_threshold(pcm, sw_params, dwFlags & WAVE_DIRECTSOUND ? INT_MAX : 1 ), MMSYSERR_ERROR, "unable to set start threshold");
>
>
From what I could see from the patch, it tries to set a buffer size
instead of a buffer time. However, the patch did not solve the problems
as it is.
First, the patch supplies a constant value for
snd_pcm_hw_params_set_buffer_size_near(). However, the ALSA
documentation states that the parameter for buffer_size for this
function is given in *frames*, not bytes. Since a frame (nChannels *
bitsPerSample / 8) can be from 1 to 4 bytes depending on the requested
format, this patch only fixes the frame length, not the byte length. So
the attached patch divides the required buffer size (in bytes) by the
frame size to arrive to the buffer size in frames.
Second, even after the division, the ALSA API is unable to honor the
exact value required (at least in my hardware). For most formats the
upper limit on the byte size is 30104 bytes, but for the reference tone
it changes to 15052 bytes. So it triggers the buffer resize all over
again. The attached patch hardcodes the value of 15052 bytes (0x3acc) as
the required buffer size, and then the ALSA API doesn't resize the
buffer. But obviously, this is a machine-dependent value that might be
different in everybody else's machine. Any other value greater than
15052 triggers the buffer resize, and other values below it cause awful
buzzings and silences on the games I have tested. Even the chosen value
of 15052 bytes, though it works in the tested games, causes buzzings
instead of the proper tone on some 8000Hz and 11050Hz tests (the tests
where the playtime is around 100-300 ms instead of 1000 ms in the
attached trace).
Third (but this is no longer a winealsa issue), I still get the critical
section timeouts on invalid threads in aprox. 1 in 5 runs of the
interactive dsound test, even on an idle CPU. This proves that the
timeout bug is not because of CPU load, and should be investigated further.
All of this leads me to think that the winealsa driver should give up on
trying to provide access to the direct mmap buffer, and revert to
providing a fixed-size buffer that is then used to feed the actual ALSA
buffer. This would a) hide the buffer resizes from the tests and the
games, and b) remove the need of the undocumented hardware pointer
function. In fact, I do not remember what was the rationale behind
switching from the old model to the current one. In addition, I have
tested a few games
Any comments on this are welcome.
Alex Villacís Lasso
-------------- next part --------------
A non-text attachment was scrubbed...
Name: audio_modified.diff
Type: text/x-patch
Size: 1938 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20050901/9918d68a/audio_modified.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: winealsa_dsound.trace.gz
Type: application/x-gzip
Size: 1693 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20050901/9918d68a/winealsa_dsound.trace.bin
More information about the wine-devel
mailing list