>From 4b8a552dd57d92dbad490dd1090ac1f8f77f826f Mon Sep 17 00:00:00 2001 From: Alexander E. Patrakov Date: Fri, 4 Nov 2011 12:02:23 +0600 Subject: [PATCH 1/9] dsound: Always resample buffers in mixer thread --- dlls/dsound/buffer.c | 10 ------ dlls/dsound/dsound_main.c | 4 -- dlls/dsound/dsound_private.h | 6 +-- dlls/dsound/mixer.c | 67 +++++++++--------------------------------- dlls/dsound/primary.c | 1 - dlls/dsound/sound3d.c | 1 - 6 files changed, 16 insertions(+), 73 deletions(-) diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 50fe7c9..e2f2cc2 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -296,7 +296,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec; This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign; DSOUND_RecalcFormat(This); - DSOUND_MixToTemporary(This, 0, This->buflen, FALSE); } RtlReleaseResource(&This->lock); @@ -577,7 +576,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition(IDirectSoundBuff /* position HW buffer if applicable, else just start mixing from new location instead */ if (oldpos != newpos) - /* FIXME: Perhaps add a call to DSOUND_MixToTemporary here? Not sure it's needed */ This->buf_mixpos = DSOUND_secpos_to_bufpos(This, newpos, 0, NULL); RtlReleaseResource(&This->lock); @@ -667,11 +665,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(IDirectSoundBuffer8 *iface, { if(x1 + (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory > iter->buflen) hres = DSERR_INVALIDPARAM; - else - DSOUND_MixToTemporary(iter, (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory, x1, FALSE); } - if (x2) - DSOUND_MixToTemporary(iter, 0, x2, FALSE); RtlReleaseResource(&iter->lock); } RtlReleaseResource(&This->device->buffer_list_lock); @@ -1034,7 +1028,6 @@ void secondarybuffer_destroy(IDirectSoundBufferImpl *This) HeapFree(GetProcessHeap(), 0, This->buffer); } - HeapFree(GetProcessHeap(), 0, This->tmp_buffer); HeapFree(GetProcessHeap(), 0, This->notifies); HeapFree(GetProcessHeap(), 0, This->pwfx); HeapFree(GetProcessHeap(), 0, This); @@ -1110,9 +1103,7 @@ HRESULT IDirectSoundBufferImpl_Duplicate( dsb->device = device; dsb->ds3db = NULL; dsb->iks = NULL; /* FIXME? */ - dsb->tmp_buffer = NULL; DSOUND_RecalcFormat(dsb); - DSOUND_MixToTemporary(dsb, 0, dsb->buflen, FALSE); RtlInitializeResource(&dsb->lock); @@ -1120,7 +1111,6 @@ HRESULT IDirectSoundBufferImpl_Duplicate( hres = DirectSoundDevice_AddBuffer(device, dsb); if (hres != DS_OK) { RtlDeleteResource(&dsb->lock); - HeapFree(GetProcessHeap(),0,dsb->tmp_buffer); list_remove(&dsb->entry); dsb->buffer->ref--; HeapFree(GetProcessHeap(),0,dsb->pwfx); diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c index 8bbfb7c..cc9f44c 100644 --- a/dlls/dsound/dsound_main.c +++ b/dlls/dsound/dsound_main.c @@ -104,7 +104,6 @@ WCHAR wine_vxd_drv[] = { 'w','i','n','e','m','m','.','v','x','d', 0 }; /* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */ int ds_hel_buflen = 32768 * 2; int ds_snd_queue_max = 10; -int ds_snd_shadow_maxsize = 2; int ds_default_sample_rate = 44100; int ds_default_bits_per_sample = 16; static HINSTANCE instance; @@ -162,8 +161,6 @@ void setup_dsound_options(void) if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH )) ds_snd_queue_max = atoi(buffer); - if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH )) - ds_snd_shadow_maxsize = atoi(buffer); if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH )) ds_default_sample_rate = atoi(buffer); @@ -178,7 +175,6 @@ void setup_dsound_options(void) TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max); TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate); TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample); - TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize); } static const char * get_device_id(LPCGUID pGuid) diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 77dcf9a..8192e6c 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -175,15 +175,14 @@ struct IDirectSoundBufferImpl RTL_RWLOCK lock; PWAVEFORMATEX pwfx; BufferMemory* buffer; - LPBYTE tmp_buffer; DWORD playflags,state,leadin; DWORD writelead,buflen; DWORD nAvgBytesPerSec; - DWORD freq, tmp_buffer_len, max_buffer_len; + DWORD freq, tmp_buffer_len; DSVOLUMEPAN volpan; DSBUFFERDESC dsbd; /* used for frequency conversion (PerfectPitch) */ - ULONG freqneeded, freqAdjust, freqAcc, freqAccNext, resampleinmixer; + ULONG freqneeded, freqAdjust, freqAcc, freqAccNext; /* used for mixing */ DWORD primary_mixpos, buf_mixpos, sec_mixpos; @@ -351,7 +350,6 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN; -void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN; DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot) DECLSPEC_HIDDEN; void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index df6da13..d3b5fd8 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -174,9 +174,6 @@ static void DSOUND_RecalcFreqAcc(IDirectSoundBufferImpl *dsb) * Should be called when one of the following things occur: * - Primary buffer format is changed * - This buffer format (frequency) is changed - * - * After this, DSOUND_MixToTemporary(dsb, 0, dsb->buflen) should - * be called to refill the temporary buffer with data. */ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) { @@ -199,9 +196,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) if ((dsb->pwfx->wBitsPerSample == dsb->device->pwfx->wBitsPerSample) && (dsb->pwfx->nChannels == dsb->device->pwfx->nChannels) && !needresample && !ieee) needremix = FALSE; - HeapFree(GetProcessHeap(), 0, dsb->tmp_buffer); - dsb->tmp_buffer = NULL; - dsb->max_buffer_len = dsb->freqAcc = dsb->freqAccNext = 0; + dsb->freqAcc = dsb->freqAccNext = 0; dsb->freqneeded = needresample; if (ieee) @@ -209,23 +204,14 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) else dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1]; - dsb->resampleinmixer = FALSE; - if (needremix) { if (needresample) DSOUND_RecalcFreqAcc(dsb); else dsb->tmp_buffer_len = dsb->buflen / bAlign * pAlign; - dsb->max_buffer_len = dsb->tmp_buffer_len; - if ((dsb->max_buffer_len <= dsb->device->buflen || dsb->max_buffer_len < ds_snd_shadow_maxsize * 1024 * 1024) && ds_snd_shadow_maxsize >= 0) - dsb->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, dsb->max_buffer_len); - if (dsb->tmp_buffer) - FillMemory(dsb->tmp_buffer, dsb->tmp_buffer_len, dsb->device->pwfx->wBitsPerSample == 8 ? 128 : 0); - else - dsb->resampleinmixer = TRUE; } - else dsb->max_buffer_len = dsb->tmp_buffer_len = dsb->buflen; + else dsb->tmp_buffer_len = dsb->buflen; dsb->buf_mixpos = DSOUND_secpos_to_bufpos(dsb, dsb->sec_mixpos, 0, NULL); } @@ -348,28 +334,22 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2) * * NOTE: writepos + len <= buflen. When called by mixer, MixOne makes sure of this. */ -void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len, BOOL inmixer) +static void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len) { INT size; BYTE *ibp, *obp, *obp_begin; INT iAdvance = dsb->pwfx->nBlockAlign; INT oAdvance = dsb->device->pwfx->nBlockAlign; - DWORD freqAcc, target_writepos = 0, overshot, maxlen; - - /* We resample only when needed */ - if ((dsb->tmp_buffer && inmixer) || (!dsb->tmp_buffer && !inmixer) || dsb->resampleinmixer != inmixer) - return; + DWORD freqAcc, overshot, maxlen; assert(writepos + len <= dsb->buflen); - if (inmixer && writepos + len < dsb->buflen) + if (writepos + len < dsb->buflen) len += dsb->pwfx->nBlockAlign; maxlen = DSOUND_secpos_to_bufpos(dsb, len, 0, NULL); ibp = dsb->buffer->memory + writepos; - if (!inmixer) - obp_begin = dsb->tmp_buffer; - else if (dsb->device->tmp_buffer_len < maxlen || !dsb->device->tmp_buffer) + if (dsb->device->tmp_buffer_len < maxlen || !dsb->device->tmp_buffer) { dsb->device->tmp_buffer_len = maxlen; if (dsb->device->tmp_buffer) @@ -389,8 +369,6 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW TRACE("(%p) Same sample rate %d = primary %d\n", dsb, dsb->freq, dsb->device->pwfx->nSamplesPerSec); obp = obp_begin; - if (!inmixer) - obp += writepos/iAdvance*oAdvance; cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, 0, 1 << DSOUND_FREQSHIFT); return; @@ -399,7 +377,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW /* Mix in different sample rates */ TRACE("(%p) Adjusting frequency: %d -> %d\n", dsb, dsb->freq, dsb->device->pwfx->nSamplesPerSec); - target_writepos = DSOUND_secpos_to_bufpos(dsb, writepos, dsb->sec_mixpos, &freqAcc); + DSOUND_secpos_to_bufpos(dsb, writepos, dsb->sec_mixpos, &freqAcc); overshot = freqAcc >> DSOUND_FREQSHIFT; if (overshot) { @@ -414,9 +392,7 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW TRACE("Overshot: %d, freqAcc: %04x\n", overshot, freqAcc); } - if (!inmixer) - obp = obp_begin + target_writepos; - else obp = obp_begin; + obp = obp_begin; /* FIXME: Small problem here when we're overwriting buf_mixpos, it then STILL uses old freqAcc, not sure if it matters or not */ cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, freqAcc, dsb->freqAdjust); @@ -432,10 +408,7 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len) INT16 *bps, *mems; DWORD vLeft, vRight; INT nChannels = dsb->device->pwfx->nChannels; - LPBYTE mem = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory) + dsb->buf_mixpos; - - if (dsb->resampleinmixer) - mem = dsb->device->tmp_buffer; + LPBYTE mem = dsb->device->tmp_buffer; TRACE("(%p,%d)\n",dsb,len); TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor, @@ -458,16 +431,7 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len) return NULL; } - if (dsb->device->tmp_buffer_len < len || !dsb->device->tmp_buffer) - { - /* If we just resampled in DSOUND_MixToTemporary, we shouldn't need to resize here */ - assert(!dsb->resampleinmixer); - dsb->device->tmp_buffer_len = len; - if (dsb->device->tmp_buffer) - dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, len); - else - dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, len); - } + assert(dsb->device->tmp_buffer_len >= len && dsb->device->tmp_buffer); bpc = dsb->device->tmp_buffer; bps = (INT16 *)bpc; @@ -518,7 +482,7 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len) static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen) { INT len = fraglen, ilen; - BYTE *ibuf = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory) + dsb->buf_mixpos, *volbuf; + BYTE *ibuf = dsb->buffer->memory + dsb->buf_mixpos, *volbuf; DWORD oldpos, mixbufpos; TRACE("buf_mixpos=%d/%d sec_mixpos=%d/%d\n", dsb->buf_mixpos, dsb->tmp_buffer_len, dsb->sec_mixpos, dsb->buflen); @@ -533,9 +497,8 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO } /* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */ - DSOUND_MixToTemporary(dsb, dsb->sec_mixpos, DSOUND_bufpos_to_secpos(dsb, dsb->buf_mixpos+len) - dsb->sec_mixpos, TRUE); - if (dsb->resampleinmixer) - ibuf = dsb->device->tmp_buffer; + DSOUND_MixToTemporary(dsb, dsb->sec_mixpos, DSOUND_bufpos_to_secpos(dsb, dsb->buf_mixpos+len) - dsb->sec_mixpos); + ibuf = dsb->device->tmp_buffer; /* Apply volume if needed */ volbuf = DSOUND_MixerVol(dsb, len); @@ -557,11 +520,9 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO dsb->buf_mixpos += len; if (dsb->buf_mixpos >= dsb->tmp_buffer_len) { - if (dsb->buf_mixpos > dsb->tmp_buffer_len) - ERR("Mixpos (%u) past buflen (%u), capping...\n", dsb->buf_mixpos, dsb->tmp_buffer_len); if (dsb->playflags & DSBPLAY_LOOPING) { dsb->buf_mixpos -= dsb->tmp_buffer_len; - } else if (dsb->buf_mixpos >= dsb->tmp_buffer_len) { + } else { dsb->buf_mixpos = dsb->sec_mixpos = 0; dsb->state = STATE_STOPPED; } diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 1cc59e5..a726ec8 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -511,7 +511,6 @@ opened: (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec; DSOUND_RecalcFormat((*dsb)); - DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE); (*dsb)->primary_mixpos = 0; RtlReleaseResource(&(*dsb)->lock); diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c index f4c182f..f131b56 100644 --- a/dlls/dsound/sound3d.c +++ b/dlls/dsound/sound3d.c @@ -287,7 +287,6 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) /* FIXME: replace following line with correct frequency setting ! */ dsb->freq = flFreq; DSOUND_RecalcFormat(dsb); - DSOUND_MixToTemporary(dsb, 0, dsb->buflen); } #endif -- 1.7.3.4