[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    Re: [PATCH v4] dsound: create a primary_pwfx separately from pwfx
From:       Andrew Eikum <aeikum () codeweavers ! com>
Date:       2012-11-21 17:30:21
Message-ID: 20121121173021.GS4615 () foghorn ! codeweavers ! com
[Download RAW message or body]

Yeah, that fixes the problem. This patch looks good to me now.

Andrew

On Fri, Nov 16, 2012 at 08:35:51PM +0100, Maarten Lankhorst wrote:
> I promised I would never touch it, but then I wanted to play skyrim
> 
> V2: Limit channels to 2 in primary if not in writeprimary mode
> V3: Split off DSOUND_WaveFormat to its own function sooner.
> V4: Fix accidental revert of device->buflen increase. It was supposed to wait until \
>                 rework in patch 3.
> ---
> diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
> index e5b0e3c..ac85ba2 100644
> --- a/dlls/dsound/dsound.c
> +++ b/dlls/dsound/dsound.c
> @@ -305,21 +305,36 @@ static HRESULT WINAPI \
> IDirectSound8Impl_SetCooperativeLevel(IDirectSound8 *iface DWORD level)
> {
> IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
> +    DirectSoundDevice *device = This->device;
> +    DWORD oldlevel;
> +    HRESULT hr = S_OK;
> 
> TRACE("(%p,%p,%s)\n", This, hwnd, dumpCooperativeLevel(level));
> 
> -    if (!This->device) {
> +    if (!device) {
> WARN("not initialized\n");
> return DSERR_UNINITIALIZED;
> }
> 
> if (level == DSSCL_PRIORITY || level == DSSCL_EXCLUSIVE) {
> WARN("level=%s not fully supported\n",
> -                level == DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
> +             level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
> }
> 
> -    This->device->priolevel = level;
> -    return DS_OK;
> +    RtlAcquireResourceExclusive(&device->buffer_list_lock, TRUE);
> +    EnterCriticalSection(&device->mixlock);
> +    oldlevel = device->priolevel;
> +    device->priolevel = level;
> +    if ((level == DSSCL_WRITEPRIMARY) != (oldlevel == DSSCL_WRITEPRIMARY)) {
> +        hr = DSOUND_ReopenDevice(device, level == DSSCL_WRITEPRIMARY);
> +        if (FAILED(hr))
> +            device->priolevel = oldlevel;
> +        else
> +            DSOUND_PrimaryOpen(device);
> +    }
> +    LeaveCriticalSection(&device->mixlock);
> +    RtlReleaseResource(&device->buffer_list_lock);
> +    return hr;
> }
> 
> static HRESULT WINAPI IDirectSound8Impl_Compact(IDirectSound8 *iface)
> @@ -612,20 +627,24 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** \
> ppDevice) device->guid = GUID_NULL;
> 
> /* Set default wave format (may need it for waveOutOpen) */
> -    device->pwfx = \
>                 HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEX));
> -    if (device->pwfx == NULL) {
> +    device->pwfx = \
> HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE)); +    \
> device->primary_pwfx = \
> HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE)); +    if \
> (!device->pwfx || !device->primary_pwfx) { WARN("out of memory\n");
> +        HeapFree(GetProcessHeap(),0,device->primary_pwfx);
> +        HeapFree(GetProcessHeap(),0,device->pwfx);
> HeapFree(GetProcessHeap(),0,device);
> return DSERR_OUTOFMEMORY;
> }
> 
> device->pwfx->wFormatTag = WAVE_FORMAT_PCM;
> -    device->pwfx->nSamplesPerSec = ds_default_sample_rate;
> -    device->pwfx->wBitsPerSample = ds_default_bits_per_sample;
> +    device->pwfx->nSamplesPerSec = 22050;
> +    device->pwfx->wBitsPerSample = 8;
> device->pwfx->nChannels = 2;
> device->pwfx->nBlockAlign = device->pwfx->wBitsPerSample * device->pwfx->nChannels \
> / 8; device->pwfx->nAvgBytesPerSec = device->pwfx->nSamplesPerSec * \
> device->pwfx->nBlockAlign; device->pwfx->cbSize = 0;
> +    memcpy(device->primary_pwfx, device->pwfx, sizeof(*device->pwfx));
> 
> InitializeCriticalSection(&(device->mixlock));
> device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": \
>                 DirectSoundDevice.mixlock");
> diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c
> index 3fded64..3c47423 100644
> --- a/dlls/dsound/dsound_main.c
> +++ b/dlls/dsound/dsound_main.c
> @@ -93,8 +93,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_default_sample_rate = 44100;
> -int ds_default_bits_per_sample = 16;
> static HINSTANCE instance;
> 
> /*
> @@ -151,19 +149,11 @@ void setup_dsound_options(void)
> ds_snd_queue_max = atoi(buffer);
> 
> 
> -    if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
> -        ds_default_sample_rate = atoi(buffer);
> -
> -    if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
> -        ds_default_bits_per_sample = atoi(buffer);
> -
> if (appkey) RegCloseKey( appkey );
> if (hkey) RegCloseKey( hkey );
> 
> TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
> 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);
> }
> 
> static const char * get_device_id(LPCGUID pGuid)
> diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
> index 247f229..62656a5 100644
> --- a/dlls/dsound/dsound_private.h
> +++ b/dlls/dsound/dsound_private.h
> @@ -32,9 +32,6 @@
> 
> extern int ds_hel_buflen DECLSPEC_HIDDEN;
> extern int ds_snd_queue_max DECLSPEC_HIDDEN;
> -extern int ds_snd_shadow_maxsize DECLSPEC_HIDDEN;
> -extern int ds_default_sample_rate DECLSPEC_HIDDEN;
> -extern int ds_default_bits_per_sample DECLSPEC_HIDDEN;
> 
> /*****************************************************************************
> * Predeclare the interface implementation structures
> @@ -72,8 +69,8 @@ struct DirectSoundDevice
> GUID                        guid;
> DSCAPS                      drvcaps;
> DWORD                       priolevel;
> -    PWAVEFORMATEX               pwfx;
> -    UINT                        timerID, playing_offs_bytes, in_mmdev_bytes, \
> prebuf, helfrags; +    PWAVEFORMATEX               pwfx, primary_pwfx;
> +    UINT                        timerID, playing_offs_bytes, in_mmdev_bytes, \
> prebuf; DWORD                       fraglen;
> LPBYTE                      buffer;
> DWORD                       writelead, buflen, state, playpos, mixpos;
> @@ -211,6 +208,7 @@ HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) \
> DECLSPEC_HIDDEN; HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, \
> LPDWORD playpos, LPDWORD writepos) DECLSPEC_HIDDEN; LPWAVEFORMATEX \
> DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN; HRESULT \
> DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN; \
> +HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) DECLSPEC_HIDDEN; HRESULT \
> primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, \
> const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN; void \
>                 primarybuffer_destroy(IDirectSoundBufferImpl *This) \
>                 DECLSPEC_HIDDEN;
> diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
> index 264d64d..84e029b 100644
> --- a/dlls/dsound/mixer.c
> +++ b/dlls/dsound/mixer.c
> @@ -112,6 +112,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
> 	TRACE("(%p)\n",dsb);
> 
> 	pwfxe = (WAVEFORMATEXTENSIBLE *) dsb->pwfx;
> +	dsb->freqAdjust = (float)dsb->freq / dsb->device->pwfx->nSamplesPerSec;
> 
> 	if ((pwfxe->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) || \
>                 ((pwfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> 	    && (IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))))
> diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c
> index 8da12e2..bf76dec 100644
> --- a/dlls/dsound/primary.c
> +++ b/dlls/dsound/primary.c
> @@ -58,10 +58,99 @@ static DWORD DSOUND_fraglen(DirectSoundDevice *device)
> return ret;
> }
> 
> +static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client,
> +				 BOOL forcewave, WAVEFORMATEX **wfx)
> +{
> +    WAVEFORMATEXTENSIBLE *retwfe = NULL;
> +    WAVEFORMATEX *w;
> +    HRESULT hr;
> +
> +    if (!forcewave) {
> +        WAVEFORMATEXTENSIBLE *mixwfe;
> +        hr = IAudioClient_GetMixFormat(client, (WAVEFORMATEX**)&mixwfe);
> +
> +        if (FAILED(hr))
> +            return hr;
> +
> +        if (mixwfe->Format.nChannels > 2) {
> +            static int once;
> +            if (!once++)
> +                FIXME("Limiting channels to 2 due to lack of multichannel \
> support\n"); +
> +            mixwfe->Format.nChannels = 2;
> +            mixwfe->Format.nBlockAlign = mixwfe->Format.nChannels * \
> mixwfe->Format.wBitsPerSample / 8; +            mixwfe->Format.nAvgBytesPerSec = \
> mixwfe->Format.nSamplesPerSec * mixwfe->Format.nBlockAlign; +        }
> +
> +        if (!IsEqualGUID(&mixwfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
> +            WAVEFORMATEXTENSIBLE testwfe = *mixwfe;
> +
> +            testwfe.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
> +            testwfe.Format.wBitsPerSample = 32;
> +            testwfe.Format.nBlockAlign = testwfe.Format.nChannels * \
> testwfe.Format.wBitsPerSample / 8; +            testwfe.Format.nAvgBytesPerSec = \
> testwfe.Format.nSamplesPerSec * testwfe.Format.nBlockAlign; +            \
> testwfe.Samples.wValidBitsPerSample = 0; +
> +            if (FAILED(IAudioClient_IsFormatSupported(client, \
> AUDCLNT_SHAREMODE_SHARED, &testwfe.Format, (WAVEFORMATEX**)&retwfe))) +             \
> w = DSOUND_CopyFormat(&mixwfe->Format); +            else if (retwfe)
> +                w = DSOUND_CopyFormat(&retwfe->Format);
> +            else
> +                w = DSOUND_CopyFormat(&testwfe.Format);
> +            CoTaskMemFree(retwfe);
> +            retwfe = NULL;
> +        } else
> +            w = DSOUND_CopyFormat(&mixwfe->Format);
> +        CoTaskMemFree(mixwfe);
> +    } else if (device->primary_pwfx->wFormatTag == WAVE_FORMAT_PCM ||
> +               device->primary_pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
> +        WAVEFORMATEX *wi = device->primary_pwfx;
> +        WAVEFORMATEXTENSIBLE *wfe;
> +
> +        /* Convert to WAVEFORMATEXTENSIBLE */
> +        w = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEXTENSIBLE));
> +        wfe = (WAVEFORMATEXTENSIBLE*)w;
> +        if (!wfe)
> +            return DSERR_OUTOFMEMORY;
> +
> +        wfe->Format = *wi;
> +        w->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
> +        w->cbSize = sizeof(*wfe) - sizeof(*w);
> +        w->nBlockAlign = w->nChannels * w->wBitsPerSample / 8;
> +        w->nAvgBytesPerSec = w->nSamplesPerSec * w->nBlockAlign;
> +
> +        wfe->dwChannelMask = 0;
> +        wfe->Samples.wValidBitsPerSample = 0;
> +        if (wi->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
> +            w->wBitsPerSample = 32;
> +            wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
> +        } else
> +            wfe->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> +    } else
> +        w = DSOUND_CopyFormat(device->primary_pwfx);
> +
> +    if (!w)
> +        return DSERR_OUTOFMEMORY;
> +
> +    hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, w, \
> (WAVEFORMATEX**)&retwfe); +    if (retwfe) {
> +        memcpy(w, retwfe, sizeof(WAVEFORMATEX) + retwfe->Format.cbSize);
> +        CoTaskMemFree(retwfe);
> +    }
> +    if (FAILED(hr)) {
> +        WARN("IsFormatSupported failed: %08x\n", hr);
> +        HeapFree(GetProcessHeap(), 0, w);
> +        return hr;
> +    }
> +    *wfx = w;
> +    return S_OK;
> +}
> +
> HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
> {
> UINT prebuf_frames;
> REFERENCE_TIME prebuf_rt;
> +    WAVEFORMATEX *wfx = NULL;
> HRESULT hres;
> 
> TRACE("(%p, %d)\n", device, forcewave);
> @@ -85,11 +174,20 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL \
> forcewave) 
> hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient,
> CLSCTX_INPROC_SERVER, NULL, (void **)&device->client);
> -    if(FAILED(hres)){
> +    if(FAILED(hres)) {
> WARN("Activate failed: %08x\n", hres);
> return hres;
> }
> 
> +    hres = DSOUND_WaveFormat(device, device->client, forcewave, &wfx);
> +    if (FAILED(hres)) {
> +        IAudioClient_Release(device->client);
> +        device->client = NULL;
> +        return hres;
> +    }
> +    HeapFree(GetProcessHeap(), 0, device->pwfx);
> +    device->pwfx = wfx;
> +
> prebuf_frames = device->prebuf * DSOUND_fraglen(device) / \
> device->pwfx->nBlockAlign; prebuf_rt = (10000000 * (UINT64)prebuf_frames) / \
> device->pwfx->nSamplesPerSec; 
> @@ -139,9 +237,11 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL \
> forcewave) return S_OK;
> }
> 
> -static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
> +HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
> {
> +	IDirectSoundBufferImpl** dsb = device->buffers;
> 	LPBYTE newbuf;
> +	DWORD i;
> 
> 	TRACE("(%p)\n", device);
> 
> @@ -157,9 +257,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
> 		device->buflen -= device->buflen % device->pwfx->nBlockAlign;
> 	}
> 
> -	device->helfrags = device->buflen / device->fraglen;
> -
> -	device->mix_buffer_len = ((device->prebuf * device->fraglen) / \
> (device->pwfx->wBitsPerSample / 8)) * sizeof(float); +	HeapFree(GetProcessHeap(), \
> 0, device->mix_buffer); +	device->mix_buffer_len = (device->buflen / \
> (device->pwfx->wBitsPerSample / 8)) * sizeof(float);  device->mix_buffer = \
> HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device->mix_buffer_len);  if \
> (!device->mix_buffer)  return DSERR_OUTOFMEMORY;
> @@ -183,8 +282,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
> 
> device->buffer = newbuf;
> 
> -    TRACE("buflen: %u, fraglen: %u, helfrags: %u, mix_buffer_len: %u\n",
> -            device->buflen, device->fraglen, device->helfrags, \
> device->mix_buffer_len); +    TRACE("buflen: %u, fraglen: %u, mix_buffer_len: \
> %u\n", +            device->buflen, device->fraglen, device->mix_buffer_len);
> 
> if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
> (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
> @@ -196,8 +295,22 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
> 
> 	FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? \
> 128 : 0);  FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
> -	device->playing_offs_bytes = device->in_mmdev_bytes = device->playpos = \
>                 device->mixpos = 0;
> -	return DS_OK;
> +	device->playpos = 0;
> +
> +    if (device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
> +	 (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
> +	  IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, \
> &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))) +        device->normfunction = \
> normfunctions[4]; +    else
> +        device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
> +
> +    for (i = 0; i < device->nrofbuffers; i++) {
> +        RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE);
> +        DSOUND_RecalcFormat(dsb[i]);
> +        RtlReleaseResource(&dsb[i]->lock);
> +    }
> +
> +    return DS_OK;
> }
> 
> 
> @@ -249,6 +362,7 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device)
> 	HeapFree(GetProcessHeap(), 0, device->primary);
> 	device->primary = NULL;
> 
> +	HeapFree(GetProcessHeap(),0,device->primary_pwfx);
> 	HeapFree(GetProcessHeap(),0,device->pwfx);
> 	device->pwfx=NULL;
> 
> @@ -338,8 +452,7 @@ LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
> 
> HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX \
> passed_fmt) {
> -	HRESULT err = DSERR_BUFFERLOST;
> -	int i;
> +	HRESULT err = S_OK;
> 	WAVEFORMATEX *old_fmt;
> 	WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;
> 	BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);
> @@ -377,169 +490,68 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, \
> LPCWAVEFORMATEX passe  RtlAcquireResourceExclusive(&(device->buffer_list_lock), \
> TRUE);  EnterCriticalSection(&(device->mixlock));
> 
> -	old_fmt = device->pwfx;
> -	device->pwfx = DSOUND_CopyFormat(passed_fmt);
> -	fmtex = (WAVEFORMATEXTENSIBLE *)device->pwfx;
> -	if (device->pwfx == NULL) {
> -		device->pwfx = old_fmt;
> -		old_fmt = NULL;
> -		err = DSERR_OUTOFMEMORY;
> -		goto done;
> -	}
> +	if (device->priolevel == DSSCL_WRITEPRIMARY) {
> +		old_fmt = device->primary_pwfx;
> +		device->primary_pwfx = DSOUND_CopyFormat(passed_fmt);
> +		fmtex = (WAVEFORMATEXTENSIBLE *)device->primary_pwfx;
> +		if (device->primary_pwfx == NULL) {
> +			err = DSERR_OUTOFMEMORY;
> +			goto out;
> +		}
> 
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
> -		if(fmtex->Samples.wValidBitsPerSample == 0){
> +		if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
> +		    fmtex->Samples.wValidBitsPerSample == 0) {
> 			TRACE("Correcting 0 valid bits per sample\n");
> 			fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample;
> 		}
> -	}
> -
> -	DSOUND_PrimaryClose(device);
> -
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	/* requested format failed, so try others */
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT){
> -		device->pwfx->wFormatTag = WAVE_FORMAT_PCM;
> -		device->pwfx->wBitsPerSample = 32;
> -		device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -		device->pwfx->nBlockAlign = passed_fmt->nChannels * \
>                 (device->pwfx->wBitsPerSample / 8);
> -
> -		err = DSOUND_ReopenDevice(device, FALSE);
> -		if(SUCCEEDED(err))
> -			goto opened;
> -	}
> -
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
> -			 IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)){
> -		fmtex->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> -		device->pwfx->wBitsPerSample = 32;
> -		device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -		device->pwfx->nBlockAlign = passed_fmt->nChannels * \
>                 (device->pwfx->wBitsPerSample / 8);
> -
> -		err = DSOUND_ReopenDevice(device, FALSE);
> -		if(SUCCEEDED(err))
> -			goto opened;
> -	}
> 
> -	device->pwfx->wBitsPerSample = 32;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->wBitsPerSample = 16;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->wBitsPerSample = 8;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->nChannels = (passed_fmt->nChannels == 2) ? 1 : 2;
> -	device->pwfx->wBitsPerSample = passed_fmt->wBitsPerSample;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->wBitsPerSample = 32;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->wBitsPerSample = 16;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	device->pwfx->wBitsPerSample = 8;
> -	device->pwfx->nAvgBytesPerSec = passed_fmt->nSamplesPerSec * \
>                 device->pwfx->nBlockAlign;
> -	device->pwfx->nBlockAlign = passed_fmt->nChannels * (device->pwfx->wBitsPerSample \
>                 / 8);
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
> -		fmtex->Samples.wValidBitsPerSample = device->pwfx->wBitsPerSample;
> -	err = DSOUND_ReopenDevice(device, FALSE);
> -	if(SUCCEEDED(err))
> -		goto opened;
> -
> -	WARN("No formats could be opened\n");
> -	goto done;
> -
> -opened:
> -	err = DSOUND_PrimaryOpen(device);
> -	if (err != DS_OK) {
> -		WARN("DSOUND_PrimaryOpen failed\n");
> -		goto done;
> -	}
> -
> -	if (passed_fmt->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced \
>                 && device->buffer)
> -	{
> 		DSOUND_PrimaryClose(device);
> -		device->pwfx->nSamplesPerSec = passed_fmt->nSamplesPerSec;
> -		err = DSOUND_ReopenDevice(device, TRUE);
> -		if (FAILED(err))
> -			WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
> -		else if (FAILED((err = DSOUND_PrimaryOpen(device))))
> -			WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
> -	}
> -
> 
> -	if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
> -			(device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
> -			 IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
> -				 &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
> -		device->normfunction = normfunctions[4];
> -	else
> -		device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
> -
> -	if (old_fmt->nSamplesPerSec != device->pwfx->nSamplesPerSec ||
> -			old_fmt->wBitsPerSample != device->pwfx->wBitsPerSample ||
> -			old_fmt->nChannels != device->pwfx->nChannels) {
> -		IDirectSoundBufferImpl** dsb = device->buffers;
> -		for (i = 0; i < device->nrofbuffers; i++, dsb++) {
> -			/* **** */
> -			RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);
> +		err = DSOUND_ReopenDevice(device, forced);
> +		if (FAILED(err)) {
> +			ERR("No formats could be opened\n");
> +			goto done;
> +		}
> 
> -			(*dsb)->freqAdjust = (*dsb)->freq / (float)device->pwfx->nSamplesPerSec;
> -			DSOUND_RecalcFormat((*dsb));
> +		err = DSOUND_PrimaryOpen(device);
> +		if (err != DS_OK) {
> +			ERR("DSOUND_PrimaryOpen failed\n");
> +			goto done;
> +		}
> 
> -			RtlReleaseResource(&(*dsb)->lock);
> -			/* **** */
> +done:
> +		if (err != DS_OK)
> +			device->primary_pwfx = old_fmt;
> +		else
> +			HeapFree(GetProcessHeap(), 0, old_fmt);
> +	} else if (passed_fmt->wFormatTag == WAVE_FORMAT_PCM ||
> +		   passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
> +		/* Fill in "real" values to primary_pwfx */
> +		WAVEFORMATEX *fmt = device->primary_pwfx;
> +
> +		*fmt = *device->pwfx;
> +		fmtex = (void*)device->pwfx;
> +
> +		if (IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
> +		    passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
> +			fmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
> +		} else {
> +			fmt->wFormatTag = WAVE_FORMAT_PCM;
> +			fmt->wBitsPerSample = 16;
> 		}
> +		fmt->nBlockAlign = fmt->nChannels * fmt->wBitsPerSample / 8;
> +		fmt->nAvgBytesPerSec = fmt->nBlockAlign * fmt->nSamplesPerSec;
> +		fmt->cbSize = 0;
> +	} else {
> +		device->primary_pwfx = HeapReAlloc(GetProcessHeap(), 0, device->primary_pwfx, \
> sizeof(*fmtex)); +		memcpy(device->primary_pwfx, device->pwfx, sizeof(*fmtex));
> 	}
> 
> -done:
> +out:
> 	LeaveCriticalSection(&(device->mixlock));
> 	RtlReleaseResource(&(device->buffer_list_lock));
> 	/* **** */
> 
> -	HeapFree(GetProcessHeap(), 0, old_fmt);
> 	return err;
> }
> 
> @@ -834,11 +846,11 @@ static HRESULT WINAPI \
> PrimaryBufferImpl_GetFormat(IDirectSoundBuffer *iface, WAV DirectSoundDevice \
> *device = This->device; TRACE("(%p,%p,%d,%p)\n", iface, lpwf, wfsize, wfwritten);
> 
> -    size = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
> +    size = sizeof(WAVEFORMATEX) + device->primary_pwfx->cbSize;
> 
> if (lpwf) {	/* NULL is valid */
> if (wfsize >= size) {
> -            CopyMemory(lpwf,device->pwfx,size);
> +            CopyMemory(lpwf,device->primary_pwfx,size);
> if (wfwritten)
> *wfwritten = size;
> } else {
> @@ -849,7 +861,7 @@ static HRESULT WINAPI \
> PrimaryBufferImpl_GetFormat(IDirectSoundBuffer *iface, WAV }
> } else {
> if (wfwritten)
> -            *wfwritten = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
> +            *wfwritten = sizeof(WAVEFORMATEX) + device->primary_pwfx->cbSize;
> else {
> WARN("invalid parameter: wfwritten == NULL\n");
> return DSERR_INVALIDPARAM;
> 
> 
> 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic