Alex Villacís Lasso wrote:
For a long time, I have been annoyed by a faint crackling that can be
heard on the sound output of any DirectSound program when full
hardware acceleration is enabled on the ALSA driver. Even after a
patch I sent earlier (which corrected a bigger artifact), this
crackling remained. Last night, I finally set upon removing this
crackling, based on a comment in IDsDriverBufferImpl_GetPosition() in
dlls/winmm/winealsa/audio.c, line 3302:
//* /*FIXME*/: snd_pcm_mmap_hw_ptr() should not be accessed by a
user app. *//
//* It will NOT return what why want anyway. *//
hw_ptr = _snd_pcm_mmap_hw_ptr(wwo->pcm);
I thought, maybe it is not returning the correct information for
GetPosition, so that is why the crackling exists, since new samples
are off-position from what they should be in order to guarantee a
smooth sound. So I deduced, maybe the IDsDriverBufferImpl object can
keep a simulation of a hardware pointer and use that instead of the
(slightly incorrect) hardware pointer. My original intention was to
remove entirely the need to reference _snd_pcm_mmap_hw_ptr(), since
this is obviously an internal alsa-lib function and should not be used
from inside the app (as the comment rightly indicates). However, I
found out that the simulated hardware pointer tends to lag behind the
real hardware pointer, and horrible mixups happen if the difference
approaches or exceeds the length of the mmap buffer. So the simulated
pointer is loosely kept close to the hardware pointer in the supplied
patch.
The good news: the patch sort of works (in my setup, at least, with
Fedora Core 4). All the games I have (Japanese RPGs) now have smooth
sound, unless the CPU load is too high.
The bad news: the patch does nothing to make the dsound tests pass in
Wine (but they were already failing before the patch :-)
Alex Villacís Lasso
Changelog:
* Remove crackling in DirectSound/ALSA playback with full hardware
acceleration
Reading through my own previous explanation, I realized that the
original crackling problem lies in the fact that the hardware pointer is
ahead of the proper position for mixing. So, if the hardware pointer is
set back by a fixed amount before reporting in GetPosition, this
crackling could be fixed without resorting to the simulated pointer
hack. The attached patch does just this. It is an one-line fix, and
solves the problem just as well as the original patch, without being as
sensitive to CPU usage as the first patch. So please ignore the previous
patch and use this one instead.
Alex Villacís Lasso
Changelog:
* Remove crackling in DirectSound/ALSA playback with full hardware
acceleration
--- wine-20050725-cvs/dlls/winmm/winealsa/audio.c 2005-07-27 10:49:40.000000000 -0500
+++ wine-20050725-cvs-patch/dlls/winmm/winealsa/audio.c 2005-08-10 23:01:04.000000000 -0500
@@ -3302,6 +3302,7 @@
/* FIXME: snd_pcm_mmap_hw_ptr() should not be accessed by a user app. */
/* It will NOT return what why want anyway. */
hw_ptr = _snd_pcm_mmap_hw_ptr(wwo->pcm);
+ if (hw_ptr >= period_size) hw_ptr -= period_size; else hw_ptr = 0;
if (lpdwPlay)
*lpdwPlay = snd_pcm_frames_to_bytes(wwo->pcm, hw_ptr/ period_size * period_size) % This->mmap_buflen_bytes;
if (lpdwWrite)