Commit 021019ff authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

dsound: Add an option to mix sound buffers in the mixer again.

parent 5f6ce2de
...@@ -296,7 +296,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency( ...@@ -296,7 +296,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec; This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec;
This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign; This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
DSOUND_RecalcFormat(This); DSOUND_RecalcFormat(This);
DSOUND_MixToTemporary(This, 0, This->buflen); DSOUND_MixToTemporary(This, 0, This->buflen, FALSE);
} }
RtlReleaseResource(&This->lock); RtlReleaseResource(&This->lock);
...@@ -733,9 +733,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock( ...@@ -733,9 +733,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
{ {
RtlAcquireResourceShared(&iter->lock, TRUE); RtlAcquireResourceShared(&iter->lock, TRUE);
if (x1) if (x1)
DSOUND_MixToTemporary(iter, (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory, x1); DSOUND_MixToTemporary(iter, (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory, x1, FALSE);
if (x2) if (x2)
DSOUND_MixToTemporary(iter, 0, x2); DSOUND_MixToTemporary(iter, 0, x2, FALSE);
RtlReleaseResource(&iter->lock); RtlReleaseResource(&iter->lock);
} }
RtlReleaseResource(&This->device->buffer_list_lock); RtlReleaseResource(&This->device->buffer_list_lock);
...@@ -1223,7 +1223,7 @@ HRESULT IDirectSoundBufferImpl_Duplicate( ...@@ -1223,7 +1223,7 @@ HRESULT IDirectSoundBufferImpl_Duplicate(
dsb->secondary = NULL; dsb->secondary = NULL;
dsb->tmp_buffer = NULL; dsb->tmp_buffer = NULL;
DSOUND_RecalcFormat(dsb); DSOUND_RecalcFormat(dsb);
DSOUND_MixToTemporary(dsb, 0, dsb->buflen); DSOUND_MixToTemporary(dsb, 0, dsb->buflen, FALSE);
/* variable sized struct so calculate size based on format */ /* variable sized struct so calculate size based on format */
size = sizeof(WAVEFORMATEX) + pdsb->pwfx->cbSize; size = sizeof(WAVEFORMATEX) + pdsb->pwfx->cbSize;
......
...@@ -57,10 +57,6 @@ ...@@ -57,10 +57,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(dsound); WINE_DEFAULT_DEBUG_CHANNEL(dsound);
#define DS_HEL_BUFLEN 0x8000 /* HEL: The buffer length of the emulated buffer */
#define DS_SND_QUEUE_MAX 10 /* max number of fragments to prebuffer, each fragment is approximately 10 ms long */
#define DS_SND_QUEUE_MIN 6 /* If the minimum of prebuffered fragments go below this, forcibly take all locks to prevent underruns */
DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS]; DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
...@@ -92,10 +88,12 @@ HRESULT mmErr(UINT err) ...@@ -92,10 +88,12 @@ HRESULT mmErr(UINT err)
} }
} }
/* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
int ds_emuldriver = 0; int ds_emuldriver = 0;
int ds_hel_buflen = DS_HEL_BUFLEN; int ds_hel_buflen = 32768;
int ds_snd_queue_max = DS_SND_QUEUE_MAX; int ds_snd_queue_max = 10;
int ds_snd_queue_min = DS_SND_QUEUE_MIN; int ds_snd_queue_min = 6;
int ds_snd_shadow_maxsize = 2;
int ds_hw_accel = DS_HW_ACCEL_FULL; int ds_hw_accel = DS_HW_ACCEL_FULL;
int ds_default_playback = 0; int ds_default_playback = 0;
int ds_default_capture = 0; int ds_default_capture = 0;
...@@ -173,43 +171,38 @@ void setup_dsound_options(void) ...@@ -173,43 +171,38 @@ void setup_dsound_options(void)
} }
if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH )) if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
ds_default_playback = atoi(buffer); ds_default_playback = atoi(buffer);
if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH ))
ds_snd_shadow_maxsize = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH )) if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
ds_default_capture = atoi(buffer); ds_default_capture = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH )) if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
ds_default_sample_rate = atoi(buffer); ds_default_sample_rate = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH )) if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
ds_default_bits_per_sample = atoi(buffer); ds_default_bits_per_sample = atoi(buffer);
if (appkey) RegCloseKey( appkey ); if (appkey) RegCloseKey( appkey );
if (hkey) RegCloseKey( hkey ); if (hkey) RegCloseKey( hkey );
if (ds_emuldriver) TRACE("ds_emuldriver = %d\n", ds_emuldriver);
WARN("ds_emuldriver = %d (default=0)\n",ds_emuldriver); TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
if (ds_hel_buflen != DS_HEL_BUFLEN) TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max);
WARN("ds_hel_buflen = %d (default=%d)\n",ds_hel_buflen ,DS_HEL_BUFLEN); TRACE("ds_snd_queue_min = %d\n", ds_snd_queue_min);
if (ds_snd_queue_max != DS_SND_QUEUE_MAX) TRACE("ds_hw_accel = %s\n",
WARN("ds_snd_queue_max = %d (default=%d)\n",ds_snd_queue_max ,DS_SND_QUEUE_MAX); ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
if (ds_snd_queue_min != DS_SND_QUEUE_MIN) ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
WARN("ds_snd_queue_min = %d (default=%d)\n",ds_snd_queue_min ,DS_SND_QUEUE_MIN); ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
if (ds_hw_accel != DS_HW_ACCEL_FULL) ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
WARN("ds_hw_accel = %s (default=Full)\n", "Unknown");
ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" : TRACE("ds_default_playback = %d\n", ds_default_playback);
ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" : TRACE("ds_default_capture = %d\n", ds_default_playback);
ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" : TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate);
ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" : TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample);
"Unknown"); TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize);
if (ds_default_playback != 0)
WARN("ds_default_playback = %d (default=0)\n",ds_default_playback);
if (ds_default_capture != 0)
WARN("ds_default_capture = %d (default=0)\n",ds_default_playback);
if (ds_default_sample_rate != 44100)
WARN("ds_default_sample_rate = %d (default=44100)\n",ds_default_sample_rate);
if (ds_default_bits_per_sample != 16)
WARN("ds_default_bits_per_sample = %d (default=16)\n",ds_default_bits_per_sample);
} }
static const char * get_device_id(LPCGUID pGuid) static const char * get_device_id(LPCGUID pGuid)
......
...@@ -35,6 +35,7 @@ extern int ds_emuldriver; ...@@ -35,6 +35,7 @@ extern int ds_emuldriver;
extern int ds_hel_buflen; extern int ds_hel_buflen;
extern int ds_snd_queue_max; extern int ds_snd_queue_max;
extern int ds_snd_queue_min; extern int ds_snd_queue_min;
extern int ds_snd_shadow_maxsize;
extern int ds_hw_accel; extern int ds_hw_accel;
extern int ds_default_playback; extern int ds_default_playback;
extern int ds_default_capture; extern int ds_default_capture;
...@@ -181,7 +182,7 @@ struct IDirectSoundBufferImpl ...@@ -181,7 +182,7 @@ struct IDirectSoundBufferImpl
DSVOLUMEPAN volpan; DSVOLUMEPAN volpan;
DSBUFFERDESC dsbd; DSBUFFERDESC dsbd;
/* used for frequency conversion (PerfectPitch) */ /* used for frequency conversion (PerfectPitch) */
ULONG freqneeded, freqAdjust, freqAcc, freqAccNext; ULONG freqneeded, freqAdjust, freqAcc, freqAccNext, resampleinmixer;
/* used for mixing */ /* used for mixing */
DWORD primary_mixpos, buf_mixpos, sec_mixpos; DWORD primary_mixpos, buf_mixpos, sec_mixpos;
...@@ -449,7 +450,7 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len ...@@ -449,7 +450,7 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan); void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan); void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb); void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen); void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer);
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot); DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot);
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2); void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
......
...@@ -193,6 +193,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) ...@@ -193,6 +193,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1]; dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1];
dsb->resampleinmixer = FALSE;
if (needremix) if (needremix)
{ {
if (needresample) if (needresample)
...@@ -200,8 +202,12 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) ...@@ -200,8 +202,12 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
else else
dsb->tmp_buffer_len = dsb->buflen / bAlign * pAlign; dsb->tmp_buffer_len = dsb->buflen / bAlign * pAlign;
dsb->max_buffer_len = dsb->tmp_buffer_len; dsb->max_buffer_len = dsb->tmp_buffer_len;
dsb->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, dsb->max_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)
FillMemory(dsb->tmp_buffer, dsb->tmp_buffer_len, dsb->device->pwfx->wBitsPerSample == 8 ? 128 : 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->max_buffer_len = dsb->tmp_buffer_len = dsb->buflen;
dsb->buf_mixpos = DSOUND_secpos_to_bufpos(dsb, dsb->sec_mixpos, 0, NULL); dsb->buf_mixpos = DSOUND_secpos_to_bufpos(dsb, dsb->sec_mixpos, 0, NULL);
...@@ -313,41 +319,52 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2) ...@@ -313,41 +319,52 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
* writepos = Starting position of changed buffer * writepos = Starting position of changed buffer
* len = number of bytes to resample from writepos * len = number of bytes to resample from writepos
* *
* NOTE: writepos + len <= buflen, This function doesn't loop! * NOTE: writepos + len <= buflen. When called by mixer, MixOne makes sure of this.
*/ */
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len) void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len, BOOL inmixer)
{ {
INT i, size; INT i, size;
BYTE *ibp, *obp, *ibp_begin, *obp_begin; BYTE *ibp, *obp, *ibp_begin, *obp_begin;
INT iAdvance = dsb->pwfx->nBlockAlign; INT iAdvance = dsb->pwfx->nBlockAlign;
INT oAdvance = dsb->device->pwfx->nBlockAlign; INT oAdvance = dsb->device->pwfx->nBlockAlign;
DWORD freqAcc, target_writepos, overshot; DWORD freqAcc, target_writepos = 0, overshot, maxlen;
if (!dsb->tmp_buffer) /* We resample only when needed */
/* Nothing to do, already ideal format */ if ((dsb->tmp_buffer && inmixer) || (!dsb->tmp_buffer && !inmixer) || dsb->resampleinmixer != inmixer)
return; return;
assert(writepos + len <= dsb->buflen);
if (inmixer && writepos + len < dsb->buflen)
len += dsb->pwfx->nBlockAlign;
maxlen = DSOUND_secpos_to_bufpos(dsb, len, 0, NULL);
ibp = dsb->buffer->memory + writepos; ibp = dsb->buffer->memory + writepos;
ibp_begin = dsb->buffer->memory; ibp_begin = dsb->buffer->memory;
obp_begin = dsb->tmp_buffer; if (!inmixer)
obp_begin = dsb->tmp_buffer;
else if (dsb->device->tmp_buffer_len < maxlen || !dsb->device->tmp_buffer)
{
dsb->device->tmp_buffer_len = maxlen;
if (dsb->device->tmp_buffer)
dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, maxlen);
else
dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, maxlen);
obp_begin = dsb->device->tmp_buffer;
}
else
obp_begin = dsb->device->tmp_buffer;
TRACE("(%p, %p)\n", dsb, ibp); TRACE("(%p, %p)\n", dsb, ibp);
/* Check for the best case */
if ((dsb->freq == dsb->device->pwfx->nSamplesPerSec) &&
(dsb->pwfx->wBitsPerSample == dsb->device->pwfx->wBitsPerSample) &&
(dsb->pwfx->nChannels == dsb->device->pwfx->nChannels)) {
obp = dsb->tmp_buffer + writepos;
/* Why would we need a temporary buffer if we do best case? */
FIXME("(%p) Why do we resample for best case??? Bad!!\n", dsb);
CopyMemory(obp, ibp, len);
return;
}
/* Check for same sample rate */ /* Check for same sample rate */
if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) { if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) {
TRACE("(%p) Same sample rate %d = primary %d\n", dsb, TRACE("(%p) Same sample rate %d = primary %d\n", dsb,
dsb->freq, dsb->device->pwfx->nSamplesPerSec); dsb->freq, dsb->device->pwfx->nSamplesPerSec);
obp = dsb->tmp_buffer + writepos/iAdvance*oAdvance; obp = obp_begin;
if (!inmixer)
obp += writepos/iAdvance*oAdvance;
for (i = 0; i < len; i += iAdvance) { for (i = 0; i < len; i += iAdvance) {
cp_fields(dsb, ibp, obp); cp_fields(dsb, ibp, obp);
ibp += iAdvance; ibp += iAdvance;
...@@ -375,7 +392,10 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW ...@@ -375,7 +392,10 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
TRACE("Overshot: %d, freqAcc: %04x\n", overshot, freqAcc); TRACE("Overshot: %d, freqAcc: %04x\n", overshot, freqAcc);
} }
obp = dsb->tmp_buffer + target_writepos; if (!inmixer)
obp = obp_begin + target_writepos;
else 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 */ /* FIXME: Small problem here when we're overwriting buf_mixpos, it then STILL uses old freqAcc, not sure if it matters or not */
while (size > 0) { while (size > 0) {
cp_fields(dsb, ibp, obp); cp_fields(dsb, ibp, obp);
...@@ -393,14 +413,17 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW ...@@ -393,14 +413,17 @@ void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DW
/** Apply volume to the given soundbuffer from (primary) position writepos and length len /** Apply volume to the given soundbuffer from (primary) position writepos and length len
* Returns: NULL if no volume needs to be applied * Returns: NULL if no volume needs to be applied
* or else a memory handle that holds 'len' volume adjusted buffer */ * or else a memory handle that holds 'len' volume adjusted buffer */
static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, DWORD writepos, INT len) static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len)
{ {
INT i; INT i;
BYTE *bpc; BYTE *bpc;
INT16 *bps, *mems; INT16 *bps, *mems;
DWORD vLeft, vRight; DWORD vLeft, vRight;
INT nChannels = dsb->device->pwfx->nChannels; INT nChannels = dsb->device->pwfx->nChannels;
LPBYTE mem = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory)+writepos; LPBYTE mem = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory) + dsb->buf_mixpos;
if (dsb->resampleinmixer)
mem = dsb->device->tmp_buffer;
TRACE("(%p,%d)\n",dsb,len); TRACE("(%p,%d)\n",dsb,len);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor, TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor,
...@@ -425,12 +448,15 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, DWORD writepos, ...@@ -425,12 +448,15 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, DWORD writepos,
if (dsb->device->tmp_buffer_len < len || !dsb->device->tmp_buffer) 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; dsb->device->tmp_buffer_len = len;
if (dsb->device->tmp_buffer) if (dsb->device->tmp_buffer)
dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, len); dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, len);
else else
dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, len); dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, len);
} }
bpc = dsb->device->tmp_buffer; bpc = dsb->device->tmp_buffer;
bps = (INT16 *)bpc; bps = (INT16 *)bpc;
mems = (INT16 *)mem; mems = (INT16 *)mem;
...@@ -494,8 +520,13 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO ...@@ -494,8 +520,13 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
len -= len % nBlockAlign; /* data alignment */ len -= len % nBlockAlign; /* data alignment */
} }
/* 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;
/* Apply volume if needed */ /* Apply volume if needed */
volbuf = DSOUND_MixerVol(dsb, dsb->buf_mixpos, len); volbuf = DSOUND_MixerVol(dsb, len);
if (volbuf) if (volbuf)
ibuf = volbuf; ibuf = volbuf;
......
...@@ -547,7 +547,7 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, ...@@ -547,7 +547,7 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex,
(*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec; (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
DSOUND_RecalcFormat((*dsb)); DSOUND_RecalcFormat((*dsb));
DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen); DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
(*dsb)->primary_mixpos = 0; (*dsb)->primary_mixpos = 0;
RtlReleaseResource(&(*dsb)->lock); RtlReleaseResource(&(*dsb)->lock);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment