http://bugs.winehq.org/show_bug.cgi?id=14717
--- Comment #118 from Krzysztof Nikiel zzdz2@yahoo.pl 2011-01-02 12:58:22 CST --- (In reply to comment #117)
(In reply to comment #116)
The new patch works fine for both foobar2000 and the dsound8 testcase. However, it removes the "documented 10ms lead", and I am not so comfortable with that. I.e. this needs attention from an expert, but can be done later.
Do you have any idea where the "documented 10ms lead" came from? I think the patch does it the right way.
I think I found it. I'm not sure if it's a good idea to cite the windows docs but let me try:
"The write cursor indicates the position at which it is safe to write new data to the buffer. The write cursor always leads the play cursor, typically by about 15 milliseconds' worth of audio data. For more information, see DirectSound in the Graphics and Multimedia guide."
So, it doesn't look like something defined, rather some tip about the expected behavior.
Anyway, I have realized that it can be done better and simpler. Try this fix:
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 3148502..e1e5428 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -422,7 +422,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition( }
if (playpos) - *playpos = pos; + { + *playpos = pos - This->firdelay; + if ((INT)*playpos < 0) + *playpos += This->buflen; + } + if (writepos) *writepos = pos; } @@ -542,10 +547,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock( return DSERR_INVALIDPARAM; }
- writebytes -= This->firdelay; - if ((INT)writebytes < 0) - writebytes = 0; - /* **** */ RtlAcquireResourceShared(&This->lock, TRUE);
diff --git a/dlls/dsound/resample.c b/dlls/dsound/resample.c index d2bbda2..7738dd4 100644 --- a/dlls/dsound/resample.c +++ b/dlls/dsound/resample.c @@ -1,7 +1,7 @@ /* DirectSound * * Resample core - * Copyright 2010 Krzysztof Nikiel + * Copyright 2010, 2011 Krzysztof Nikiel * * Initially based on resample: * http://www-ccrma.stanford.edu/~jos/resample/ @@ -47,7 +47,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); #define SAMPLE24(p) (*((BYTE*)p)|*((BYTE*)p+1)<<8|*((CHAR*)p+2)<<16) #ifdef WORDS_BIGENDIAN #define SAMPLE16(p) (*((BYTE*)p)|*((CHAR*)p+1)<<8) -#define PUT16(p) (*((BYTE*)p)|*((CHAR*)p+1)<<8) +#define PUT16(p,s) *((BYTE*)p)=s;*((BYTE*)p+1)=(s>>8) #else #define SAMPLE16(p) (*((SHORT*)p)) #define PUT16(p,s) *((SHORT*)p)=s @@ -346,8 +346,6 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl * dsb) dsb->outfreq = dsb->device->pwfx->nSamplesPerSec; dsb->outfreq_1 = 1.0 / dsb->outfreq;
- dsb->inpos = dsb->infrac = 0; /* reset resampler pointer */ - dsb->firstep = g_fir[dsb->quality]->step; if (dsb->outfreq < dsb->freq) { @@ -364,13 +362,15 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl * dsb) if (dsb->freq == dsb->outfreq) { dsb->firstep = 1; - dsb->firdelay = 0; + dsb->firdelay = 1; } else - { dsb->firdelay = (2 * g_fir[dsb->quality]->size / dsb->firstep) + 1; - dsb->firdelay *= dsb->pwfx->nBlockAlign; - } + + dsb->firdelay *= dsb->pwfx->nBlockAlign; + + dsb->infrac = 0; + dsb->inpos = dsb->firdelay;
TRACE("resample quality: %d\n", dsb->quality); TRACE("resample firstep %d\n", dsb->firstep);