From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/audiosessionmanager.c | 6 ++ dlls/mmdevapi/client.c | 101 ++++++++++++++++++++ dlls/winealsa.drv/mmdevdrv.c | 2 +- dlls/winecoreaudio.drv/mmdevdrv.c | 2 +- dlls/wineoss.drv/mmdevdrv.c | 2 +- dlls/winepulse.drv/mmdevdrv.c | 138 +--------------------------- 6 files changed, 114 insertions(+), 137 deletions(-)
diff --git a/dlls/mmdevapi/audiosessionmanager.c b/dlls/mmdevapi/audiosessionmanager.c index 71799590e5e..dc0c5f609b7 100644 --- a/dlls/mmdevapi/audiosessionmanager.c +++ b/dlls/mmdevapi/audiosessionmanager.c @@ -47,6 +47,12 @@ void sessions_unlock(void) LeaveCriticalSection(&g_sessions_lock); }
+HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, + struct audio_session **out) +{ + return E_NOTIMPL; +} + static inline struct session_mgr *impl_from_IAudioSessionManager2(IAudioSessionManager2 *iface) { return CONTAINING_RECORD(iface, struct session_mgr, IAudioSessionManager2_iface); diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 5d807776ff0..bc0d342e3f6 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -44,6 +44,8 @@ typedef struct tagLANGANDCODEPAGE extern void sessions_lock(void) DECLSPEC_HIDDEN; extern void sessions_unlock(void) DECLSPEC_HIDDEN;
+extern HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, + struct audio_session **out) DECLSPEC_HIDDEN; extern struct audio_session_wrapper *session_wrapper_create(struct audio_client *client) DECLSPEC_HIDDEN;
static HANDLE main_loop_thread; @@ -404,6 +406,105 @@ const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl = capture_GetNextPacketSize };
+HRESULT WINAPI client_Initialize(IAudioClient3 *iface, AUDCLNT_SHAREMODE mode, DWORD flags, + REFERENCE_TIME duration, REFERENCE_TIME period, + const WAVEFORMATEX *fmt, const GUID *sessionguid) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct create_stream_params params; + unsigned int i, channel_count; + stream_handle stream; + WCHAR *name; + HRESULT hr; + + TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration), + wine_dbgstr_longlong(period), fmt, + debugstr_guid(sessionguid)); + + if (!fmt) + return E_POINTER; + + dump_fmt(fmt); + + if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) + return E_INVALIDARG; + + if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS | + AUDCLNT_STREAMFLAGS_LOOPBACK | + AUDCLNT_STREAMFLAGS_EVENTCALLBACK | + AUDCLNT_STREAMFLAGS_NOPERSIST | + AUDCLNT_STREAMFLAGS_RATEADJUST | + AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED | + AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE | + AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED | + AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY | + AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) { + FIXME("Unknown flags: %08lx\n", flags); + return E_INVALIDARG; + } + + sessions_lock(); + + if (This->stream) { + sessions_unlock(); + return AUDCLNT_E_ALREADY_INITIALIZED; + } + + if (FAILED(hr = main_loop_start())) { + sessions_unlock(); + return hr; + } + + channel_count = fmt->nChannels; + + params.name = name = get_application_name(); + params.device = This->device_name; + params.flow = This->dataflow; + params.share = mode; + params.flags = flags; + params.duration = duration; + params.period = period; + params.fmt = fmt; + params.channel_count = &channel_count; + params.stream = &stream; + + WINE_UNIX_CALL(create_stream, ¶ms); + + free(name); + + if (FAILED(hr = params.result)) { + sessions_unlock(); + return hr; + } + + if (!(This->vols = malloc(channel_count * sizeof(*This->vols)))) { + stream_release(stream, NULL); + sessions_unlock(); + return E_OUTOFMEMORY; + } + + for (i = 0; i < channel_count; i++) + This->vols[i] = 1.f; + + hr = get_audio_session(sessionguid, This->parent, channel_count, &This->session); + if (FAILED(hr)) { + free(This->vols); + This->vols = NULL; + sessions_unlock(); + stream_release(stream, NULL); + return E_OUTOFMEMORY; + } + + This->stream = stream; + This->channel_count = channel_count; + list_add_tail(&This->session->clients, &This->entry); + set_stream_volumes(This); + + sessions_unlock(); + + return S_OK; +} + HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out) { struct audio_client *This = impl_from_IAudioClient3(iface); diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 43a44b0569d..b6d80d5aabe 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -510,7 +510,7 @@ static AudioSession *create_session(const GUID *guid, IMMDevice *device,
/* if channels == 0, then this will return or create a session with * matching dataflow and GUID. otherwise, channels must also match */ -static HRESULT get_audio_session(const GUID *sessionguid, +HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, AudioSession **out) { AudioSession *session; diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index fc011021d68..106f8dd1d66 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -505,7 +505,7 @@ static AudioSession *create_session(const GUID *guid, IMMDevice *device,
/* if channels == 0, then this will return or create a session with * matching dataflow and GUID. otherwise, channels must also match */ -static HRESULT get_audio_session(const GUID *sessionguid, +HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, AudioSession **out) { AudioSession *session; diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index bacf22a9029..53f3f38908a 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -487,7 +487,7 @@ static AudioSession *create_session(const GUID *guid, IMMDevice *device,
/* if channels == 0, then this will return or create a session with * matching dataflow and GUID. otherwise, channels must also match */ -static HRESULT get_audio_session(const GUID *sessionguid, +HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, AudioSession **out) { AudioSession *session; diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index c932652f2e9..4631c5ab60e 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -128,17 +128,11 @@ extern const IAudioClockVtbl AudioClock_Vtbl; extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
-extern HRESULT main_loop_start(void) DECLSPEC_HIDDEN; - extern struct audio_session_wrapper *session_wrapper_create( struct audio_client *client) DECLSPEC_HIDDEN;
extern HRESULT stream_release(stream_handle stream, HANDLE timer_thread);
-extern WCHAR *get_application_name(void); - -extern void set_stream_volumes(struct audio_client *This); - static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface) { return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface); @@ -443,40 +437,6 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface) return ref; }
-static void dump_fmt(const WAVEFORMATEX *fmt) -{ - TRACE("wFormatTag: 0x%x (", fmt->wFormatTag); - switch(fmt->wFormatTag) { - case WAVE_FORMAT_PCM: - TRACE("WAVE_FORMAT_PCM"); - break; - case WAVE_FORMAT_IEEE_FLOAT: - TRACE("WAVE_FORMAT_IEEE_FLOAT"); - break; - case WAVE_FORMAT_EXTENSIBLE: - TRACE("WAVE_FORMAT_EXTENSIBLE"); - break; - default: - TRACE("Unknown"); - break; - } - TRACE(")\n"); - - TRACE("nChannels: %u\n", fmt->nChannels); - TRACE("nSamplesPerSec: %lu\n", fmt->nSamplesPerSec); - TRACE("nAvgBytesPerSec: %lu\n", fmt->nAvgBytesPerSec); - TRACE("nBlockAlign: %u\n", fmt->nBlockAlign); - TRACE("wBitsPerSample: %u\n", fmt->wBitsPerSample); - TRACE("cbSize: %u\n", fmt->cbSize); - - if (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - WAVEFORMATEXTENSIBLE *fmtex = (void*)fmt; - TRACE("dwChannelMask: %08lx\n", fmtex->dwChannelMask); - TRACE("Samples: %04x\n", fmtex->Samples.wReserved); - TRACE("SubFormat: %s\n", wine_dbgstr_guid(&fmtex->SubFormat)); - } -} - static void session_init_vols(AudioSession *session, UINT channels) { if (session->channel_count < channels) { @@ -524,7 +484,7 @@ static AudioSession *create_session(const GUID *guid, IMMDevice *device,
/* if channels == 0, then this will return or create a session with * matching dataflow and GUID. otherwise, channels must also match */ -static HRESULT get_audio_session(const GUID *sessionguid, +HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, UINT channels, AudioSession **out) { AudioSession *session; @@ -556,100 +516,10 @@ static HRESULT get_audio_session(const GUID *sessionguid, return S_OK; }
-static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, +extern HRESULT WINAPI client_Initialize(IAudioClient3 *iface, AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration, REFERENCE_TIME period, const WAVEFORMATEX *fmt, - const GUID *sessionguid) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct create_stream_params params; - unsigned int i, channel_count; - stream_handle stream; - WCHAR *name; - HRESULT hr; - - TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, - wine_dbgstr_longlong(duration), wine_dbgstr_longlong(period), fmt, debugstr_guid(sessionguid)); - - if (!fmt) - return E_POINTER; - dump_fmt(fmt); - - if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) - return E_INVALIDARG; - - if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS | - AUDCLNT_STREAMFLAGS_LOOPBACK | - AUDCLNT_STREAMFLAGS_EVENTCALLBACK | - AUDCLNT_STREAMFLAGS_NOPERSIST | - AUDCLNT_STREAMFLAGS_RATEADJUST | - AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED | - AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE | - AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED | - AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY | - AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) { - FIXME("Unknown flags: %08lx\n", flags); - return E_INVALIDARG; - } - - sessions_lock(); - - if (This->stream) { - sessions_unlock(); - return AUDCLNT_E_ALREADY_INITIALIZED; - } - - if (FAILED(hr = main_loop_start())) - { - sessions_unlock(); - return hr; - } - - params.name = name = get_application_name(); - params.device = This->device_name; - params.flow = This->dataflow; - params.share = mode; - params.flags = flags; - params.duration = duration; - params.period = period; - params.fmt = fmt; - params.stream = &stream; - params.channel_count = &channel_count; - pulse_call(create_stream, ¶ms); - free(name); - if (FAILED(hr = params.result)) - { - sessions_unlock(); - return hr; - } - - if (!(This->vols = malloc(channel_count * sizeof(*This->vols)))) - { - stream_release(stream, NULL); - sessions_unlock(); - return E_OUTOFMEMORY; - } - for (i = 0; i < channel_count; i++) - This->vols[i] = 1.f; - - hr = get_audio_session(sessionguid, This->parent, channel_count, &This->session); - if (FAILED(hr)) - { - free(This->vols); - This->vols = NULL; - sessions_unlock(); - stream_release(stream, NULL); - return E_OUTOFMEMORY; - } - - This->stream = stream; - This->channel_count = channel_count; - list_add_tail(&This->session->clients, &This->entry); - set_stream_volumes(This); - - sessions_unlock(); - return S_OK; -} + const GUID *sessionguid);
extern HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out); @@ -708,7 +578,7 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_QueryInterface, AudioClient_AddRef, AudioClient_Release, - AudioClient_Initialize, + client_Initialize, client_GetBufferSize, client_GetStreamLatency, client_GetCurrentPadding,