From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/dsound/capture.c | 25 +++++++++++++--- dlls/dsound/dsound.c | 56 +++++++++++++++++++++--------------- dlls/dsound/dsound_private.h | 7 +++-- dlls/dsound/primary.c | 34 +++++++++++++++++----- 4 files changed, 85 insertions(+), 37 deletions(-)
diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index e9012600cfa..54cd59f7be6 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -712,6 +712,7 @@ static HRESULT IDirectSoundCaptureBufferImpl_Create( HRESULT err = DS_OK; LPBYTE newbuf; DWORD buflen; + IWineAudioClient *wine_audio_client;
This->numIfaces = 0; This->ref = 0; @@ -743,9 +744,19 @@ static HRESULT IDirectSoundCaptureBufferImpl_Create( return err; }
- err = IAudioClient_Initialize(device->client, - AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - 200 * 100000, 0, device->pwfx, NULL); + if (FAILED(IAudioClient_QueryInterface(device->client, &IID_IWineAudioClient, (void**)&wine_audio_client))) + wine_audio_client = NULL; + + if (wine_audio_client) { + err = IWineAudioClient_InitializeWine(wine_audio_client, FALSE, + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + 200 * 100000, 0, device->pwfx, NULL); + IWineAudioClient_Release(wine_audio_client); + } else { + err = IAudioClient_Initialize(device->client, + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + 200 * 100000, 0, device->pwfx, NULL); + } if(FAILED(err)){ WARN("Initialize failed: %08lx\n", err); IAudioClient_Release(device->client); @@ -1004,6 +1015,7 @@ static HRESULT DirectSoundCaptureDevice_Initialize( struct _TestFormat *fmt; DirectSoundCaptureDevice *device; IAudioClient *client; + IWineAudioClient *wine_audio_client;
TRACE("(%p, %s)\n", ppDevice, debugstr_guid(lpcGUID));
@@ -1047,13 +1059,18 @@ static HRESULT DirectSoundCaptureDevice_Initialize( return DSERR_NODRIVER; }
+ if (FAILED(IAudioClient_QueryInterface(client, &IID_IWineAudioClient, (void**)&wine_audio_client))) + wine_audio_client = NULL; + for(fmt = formats_to_test; fmt->flag; ++fmt){ - if(DSOUND_check_supported(client, fmt->rate, fmt->depth, fmt->channels)){ + if(DSOUND_check_supported(client, wine_audio_client, fmt->rate, fmt->depth, fmt->channels)){ device->drvcaps.dwFormats |= fmt->flag; if(fmt->channels > device->drvcaps.dwChannels) device->drvcaps.dwChannels = fmt->channels; } } + if (wine_audio_client) + IWineAudioClient_Release(wine_audio_client); IAudioClient_Release(client);
*ppDevice = device; diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index 7629810db50..6042c612957 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -247,8 +247,8 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) return ref; }
-BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, - DWORD depth, WORD channels) +BOOL DSOUND_check_supported(IAudioClient *client, IWineAudioClient *wine_audio_client, + DWORD rate, DWORD depth, WORD channels) { WAVEFORMATEX fmt, *junk; HRESULT hr; @@ -261,7 +261,10 @@ BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, fmt.nAvgBytesPerSec = rate * fmt.nBlockAlign; fmt.cbSize = 0;
- hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &fmt, &junk); + if (wine_audio_client) + hr = IWineAudioClient_IsFormatSupportedWine(wine_audio_client, FALSE, AUDCLNT_SHAREMODE_SHARED, &fmt, &junk); + else + hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &fmt, &junk); if(SUCCEEDED(hr)) CoTaskMemFree(junk);
@@ -274,6 +277,7 @@ static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGU GUID devGUID; DirectSoundDevice *device; IMMDevice *mmdevice; + IWineAudioClient *wine_audio_client;
TRACE("(%p,%s)\n",ppDevice,debugstr_guid(lpcGUID));
@@ -338,34 +342,40 @@ static HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGU
ZeroMemory(&device->drvcaps, sizeof(device->drvcaps));
- if(DSOUND_check_supported(device->client, 11025, 8, 1) || - DSOUND_check_supported(device->client, 22050, 8, 1) || - DSOUND_check_supported(device->client, 44100, 8, 1) || - DSOUND_check_supported(device->client, 48000, 8, 1) || - DSOUND_check_supported(device->client, 96000, 8, 1)) + if (FAILED(IAudioClient_QueryInterface(device->client, &IID_IWineAudioClient, (void**)&wine_audio_client))) + wine_audio_client = NULL; + + if(DSOUND_check_supported(device->client, wine_audio_client, 11025, 8, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 22050, 8, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 44100, 8, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 48000, 8, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 96000, 8, 1)) device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT | DSCAPS_PRIMARYMONO;
- if(DSOUND_check_supported(device->client, 11025, 16, 1) || - DSOUND_check_supported(device->client, 22050, 16, 1) || - DSOUND_check_supported(device->client, 44100, 16, 1) || - DSOUND_check_supported(device->client, 48000, 16, 1) || - DSOUND_check_supported(device->client, 96000, 16, 1)) + if(DSOUND_check_supported(device->client, wine_audio_client, 11025, 16, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 22050, 16, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 44100, 16, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 48000, 16, 1) || + DSOUND_check_supported(device->client, wine_audio_client, 96000, 16, 1)) device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYMONO;
- if(DSOUND_check_supported(device->client, 11025, 8, 2) || - DSOUND_check_supported(device->client, 22050, 8, 2) || - DSOUND_check_supported(device->client, 44100, 8, 2) || - DSOUND_check_supported(device->client, 48000, 8, 2) || - DSOUND_check_supported(device->client, 96000, 8, 2)) + if(DSOUND_check_supported(device->client, wine_audio_client, 11025, 8, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 22050, 8, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 44100, 8, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 48000, 8, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 96000, 8, 2)) device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT | DSCAPS_PRIMARYSTEREO;
- if(DSOUND_check_supported(device->client, 11025, 16, 2) || - DSOUND_check_supported(device->client, 22050, 16, 2) || - DSOUND_check_supported(device->client, 44100, 16, 2) || - DSOUND_check_supported(device->client, 48000, 16, 2) || - DSOUND_check_supported(device->client, 96000, 16, 2)) + if(DSOUND_check_supported(device->client, wine_audio_client, 11025, 16, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 22050, 16, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 44100, 16, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 48000, 16, 2) || + DSOUND_check_supported(device->client, wine_audio_client, 96000, 16, 2)) device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO;
+ if (wine_audio_client) + IWineAudioClient_Release(wine_audio_client); + /* the dsound mixer supports all of the following */ device->drvcaps.dwFlags |= DSCAPS_SECONDARY8BIT | DSCAPS_SECONDARY16BIT; device->drvcaps.dwFlags |= DSCAPS_SECONDARYMONO | DSCAPS_SECONDARYSTEREO; diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 28bba6cd64e..6f718440de9 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -31,6 +31,7 @@ #include "uuids.h"
#include "wine/list.h" +#include "wine/winemmdevapi.h"
#define DS_MAX_CHANNELS 6
@@ -242,7 +243,7 @@ DWORD CALLBACK DSOUND_mixthread(void *ptr); void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
/* capture.c */ - + HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppv); HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppv); HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_dsc8); @@ -265,7 +266,7 @@ void setup_dsound_options(void);
HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device);
-BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, - DWORD depth, WORD channels); +BOOL DSOUND_check_supported(IAudioClient *client, IWineAudioClient *wine_audio_client, + DWORD rate, DWORD depth, WORD channels); HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, LPDSENUMCALLBACKW cb, void *user); diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 2073a32240c..0e3fdaebbc6 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -108,7 +108,7 @@ static DWORD DSOUND_FindSpeakerConfig(IMMDevice *mmdevice, int channels) }
static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client, - BOOL forcewave, WAVEFORMATEX **wfx) + IWineAudioClient *wine_audio_client, BOOL forcewave, WAVEFORMATEX **wfx) { WAVEFORMATEXTENSIBLE *retwfe = NULL; WAVEFORMATEX *w; @@ -139,7 +139,12 @@ static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client testwfe.Format.nBlockAlign = testwfe.Format.nChannels * testwfe.Format.wBitsPerSample / 8; testwfe.Format.nAvgBytesPerSec = testwfe.Format.nSamplesPerSec * testwfe.Format.nBlockAlign;
- if (FAILED(IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &testwfe.Format, (WAVEFORMATEX**)&retwfe))) + if (wine_audio_client) + hr = IWineAudioClient_IsFormatSupportedWine(wine_audio_client, FALSE, AUDCLNT_SHAREMODE_SHARED, &testwfe.Format, (WAVEFORMATEX**)&retwfe); + else + hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &testwfe.Format, (WAVEFORMATEX**)&retwfe); + + if (FAILED(hr)) w = DSOUND_CopyFormat(&mixwfe->Format); else if (retwfe) w = DSOUND_CopyFormat(&retwfe->Format); @@ -180,7 +185,10 @@ static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client if (!w) return DSERR_OUTOFMEMORY;
- hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, w, (WAVEFORMATEX**)&retwfe); + if (wine_audio_client) + hr = IWineAudioClient_IsFormatSupportedWine(wine_audio_client, FALSE, AUDCLNT_SHAREMODE_SHARED, w, (WAVEFORMATEX**)&retwfe); + else + hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, w, (WAVEFORMATEX**)&retwfe); if (retwfe) { memcpy(w, retwfe, sizeof(WAVEFORMATEX) + retwfe->Format.cbSize); CoTaskMemFree(retwfe); @@ -288,6 +296,7 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DWORD frag_frames; WAVEFORMATEX *wfx = NULL; DWORD oldspeakerconfig = device->speaker_config; + IWineAudioClient *wine_audio_client;
TRACE("(%p, %d)\n", device, forcewave);
@@ -298,15 +307,26 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) return hres; }
- hres = DSOUND_WaveFormat(device, client, forcewave, &wfx); + if (FAILED(IAudioClient_QueryInterface(client, &IID_IWineAudioClient, (void**)&wine_audio_client))) + wine_audio_client = NULL; + + hres = DSOUND_WaveFormat(device, client, wine_audio_client, forcewave, &wfx); if (FAILED(hres)) { + IWineAudioClient_Release(wine_audio_client); IAudioClient_Release(client); return hres; }
- hres = IAudioClient_Initialize(client, - AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 800000, 0, wfx, NULL); + if (wine_audio_client) { + hres = IWineAudioClient_InitializeWine(wine_audio_client, FALSE, + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | + AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 800000, 0, wfx, NULL); + IWineAudioClient_Release(wine_audio_client); + } else { + hres = IAudioClient_Initialize(client, + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | + AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 800000, 0, wfx, NULL); + } if(FAILED(hres)){ IAudioClient_Release(client); ERR("Initialize failed: %08lx\n", hres);