From: Davide Beatrici git@davidebeatrici.dev
--- dlls/wineoss.drv/mmdevdrv.c | 671 +----------------------------------- dlls/wineoss.drv/oss.c | 101 +++++- 2 files changed, 97 insertions(+), 675 deletions(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 97320875ee1..0dcdd34855a 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -48,11 +48,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(oss);
-#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER) - -static const REFERENCE_TIME DefaultPeriod = 100000; -static const REFERENCE_TIME MinimumPeriod = 50000; - typedef struct _OSSDevice { struct list entry; EDataFlow flow; @@ -75,9 +70,7 @@ static CRITICAL_SECTION_DEBUG g_sessions_lock_debug = static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, 0 }; static struct list g_sessions = LIST_INIT(g_sessions);
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); - -static const IAudioClient3Vtbl AudioClient3_Vtbl; +extern const IAudioClient3Vtbl AudioClient3_Vtbl; extern const IAudioRenderClientVtbl AudioRenderClient_Vtbl; extern const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl; extern const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl; @@ -97,11 +90,6 @@ void DECLSPEC_HIDDEN sessions_unlock(void) LeaveCriticalSection(&g_sessions_lock); }
-static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface) -{ - return CONTAINING_RECORD(iface, ACImpl, IAudioClient3_iface); -} - BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved) { switch (reason) @@ -139,28 +127,6 @@ BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, void *reserved) return TRUE; }
-static HRESULT stream_release(stream_handle stream, HANDLE timer_thread) -{ - struct release_stream_params params; - - params.stream = stream; - params.timer_thread = timer_thread; - OSS_CALL(release_stream, ¶ms); - - return params.result; -} - -static DWORD WINAPI timer_thread(void *user) -{ - struct timer_loop_params params; - ACImpl *This = user; - - params.stream = This->stream; - OSS_CALL(timer_loop, ¶ms); - - return 0; -} - static void set_device_guid(EDataFlow flow, HKEY drv_key, const WCHAR *key_name, GUID *guid) { @@ -233,17 +199,6 @@ static void get_device_guid(EDataFlow flow, const char *device, GUID *guid) RegCloseKey(key); }
-static void set_stream_volumes(ACImpl *This) -{ - struct set_volumes_params params; - - params.stream = This->stream; - params.master_volume = (This->session->mute ? 0.0f : This->session->master_vol); - params.volumes = This->vols; - params.session_volumes = This->session->channel_vols; - OSS_CALL(set_volumes, ¶ms); -} - static const OSSDevice *get_ossdevice_from_guid(const GUID *guid) { OSSDevice *dev_item; @@ -376,97 +331,6 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, return S_OK; }
-static HRESULT WINAPI AudioClient_QueryInterface(IAudioClient3 *iface, - REFIID riid, void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - *ppv = NULL; - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IAudioClient) || - IsEqualIID(riid, &IID_IAudioClient2) || - IsEqualIID(riid, &IID_IAudioClient3)) - *ppv = iface; - else if(IsEqualIID(riid, &IID_IMarshal)) - return IUnknown_QueryInterface(This->marshal, riid, ppv); - if(*ppv){ - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; - } - WARN("Unknown interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - ULONG ref; - ref = InterlockedIncrement(&This->ref); - TRACE("(%p) Refcount now %lu\n", This, ref); - return ref; -} - -static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - ULONG ref; - - ref = InterlockedDecrement(&This->ref); - TRACE("(%p) Refcount now %lu\n", This, ref); - if(!ref){ - IAudioClient3_Stop(iface); - IMMDevice_Release(This->parent); - IUnknown_Release(This->marshal); - if(This->session){ - sessions_lock(); - list_remove(&This->entry); - sessions_unlock(); - } - HeapFree(GetProcessHeap(), 0, This->vols); - if(This->stream) - stream_release(This->stream, This->timer_thread); - HeapFree(GetProcessHeap(), 0, This); - } - 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){ @@ -546,539 +410,6 @@ HRESULT get_audio_session(const GUID *sessionguid, IMMDevice *device, return S_OK; }
-static HRESULT WINAPI AudioClient_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; - stream_handle stream; - unsigned int i; - - 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; - } - - if(mode == AUDCLNT_SHAREMODE_SHARED){ - period = DefaultPeriod; - if( duration < 3 * period) - duration = 3 * period; - }else{ - if(!period) - period = DefaultPeriod; /* not minimum */ - if(period < MinimumPeriod || period > 5000000) - return AUDCLNT_E_INVALID_DEVICE_PERIOD; - if(duration > 20000000) /* the smaller the period, the lower this limit */ - return AUDCLNT_E_BUFFER_SIZE_ERROR; - if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){ - if(duration != period) - return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; - FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); - return AUDCLNT_E_DEVICE_IN_USE; - }else{ - if( duration < 8 * period) - duration = 8 * period; /* may grow above 2s */ - } - } - - sessions_lock(); - - if(This->stream){ - sessions_unlock(); - return AUDCLNT_E_ALREADY_INITIALIZED; - } - - params.name = NULL; - 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 = NULL; - params.stream = &stream; - - OSS_CALL(create_stream, ¶ms); - if(FAILED(params.result)){ - sessions_unlock(); - return params.result; - } - - This->channel_count = fmt->nChannels; - This->vols = HeapAlloc(GetProcessHeap(), 0, This->channel_count * sizeof(float)); - if(!This->vols){ - params.result = E_OUTOFMEMORY; - goto exit; - } - for(i = 0; i < This->channel_count; ++i) - This->vols[i] = 1.f; - - params.result = get_audio_session(sessionguid, This->parent, This->channel_count, - &This->session); - -exit: - if(FAILED(params.result)){ - stream_release(stream, NULL); - HeapFree(GetProcessHeap(), 0, This->vols); - This->vols = NULL; - } else { - list_add_tail(&This->session->clients, &This->entry); - This->stream = stream; - set_stream_volumes(This); - } - - sessions_unlock(); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface, - UINT32 *frames) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_buffer_size_params params; - - TRACE("(%p)->(%p)\n", This, frames); - - if(!frames) - return E_POINTER; - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.frames = frames; - - OSS_CALL(get_buffer_size, ¶ms); - TRACE("buffer size: %u\n", *frames); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface, - REFERENCE_TIME *latency) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_latency_params params; - - TRACE("(%p)->(%p)\n", This, latency); - - if(!latency) - return E_POINTER; - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.latency = latency; - OSS_CALL(get_latency, ¶ms); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface, - UINT32 *numpad) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_current_padding_params params; - - TRACE("(%p)->(%p)\n", This, numpad); - - if(!numpad) - return E_POINTER; - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.padding = numpad; - OSS_CALL(get_current_padding, ¶ms); - TRACE("padding: %u\n", *numpad); - - return params.result; -} - -static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface, - AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *fmt, - WAVEFORMATEX **out) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct is_format_supported_params params; - - TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out); - if(fmt) dump_fmt(fmt); - - params.device = This->device_name; - params.flow = This->dataflow; - params.share = mode; - params.fmt_in = fmt; - params.fmt_out = NULL; - - if(out){ - *out = NULL; - if(mode == AUDCLNT_SHAREMODE_SHARED) - params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out)); - } - OSS_CALL(is_format_supported, ¶ms); - - if(params.result == S_FALSE) - *out = ¶ms.fmt_out->Format; - else - CoTaskMemFree(params.fmt_out); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, - WAVEFORMATEX **pwfx) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_mix_format_params params; - - TRACE("(%p)->(%p)\n", This, pwfx); - - if(!pwfx) - return E_POINTER; - *pwfx = NULL; - - params.device = This->device_name; - params.flow = This->dataflow; - params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); - if(!params.fmt) - return E_OUTOFMEMORY; - - OSS_CALL(get_mix_format, ¶ms); - - if(SUCCEEDED(params.result)){ - *pwfx = ¶ms.fmt->Format; - dump_fmt(*pwfx); - } else - CoTaskMemFree(params.fmt); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface, - REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod); - - if(!defperiod && !minperiod) - return E_POINTER; - - if(defperiod) - *defperiod = DefaultPeriod; - if(minperiod) - *minperiod = MinimumPeriod; - - return S_OK; -} - -static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct start_params params; - - TRACE("(%p)\n", This); - - sessions_lock(); - - if(!This->stream){ - sessions_unlock(); - return AUDCLNT_E_NOT_INITIALIZED; - } - - params.stream = This->stream; - OSS_CALL(start, ¶ms); - - if(SUCCEEDED(params.result) && !This->timer_thread){ - This->timer_thread = CreateThread(NULL, 0, timer_thread, This, 0, NULL); - SetThreadPriority(This->timer_thread, THREAD_PRIORITY_TIME_CRITICAL); - } - - sessions_unlock(); - - return params.result; -} - -static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct stop_params params; - - TRACE("(%p)\n", This); - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - OSS_CALL(stop, ¶ms); - - return params.result; -} - -static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct reset_params params; - - TRACE("(%p)\n", This); - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - OSS_CALL(reset, ¶ms); - - return params.result; -} - -static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface, - HANDLE event) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct set_event_handle_params params; - - TRACE("(%p)->(%p)\n", This, event); - - if(!event) - return E_INVALIDARG; - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.event = event; - OSS_CALL(set_event_handle, ¶ms); - - return params.result; -} - -static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, - void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - *ppv = NULL; - - sessions_lock(); - - if(!This->stream){ - sessions_unlock(); - return AUDCLNT_E_NOT_INITIALIZED; - } - - if(IsEqualIID(riid, &IID_IAudioRenderClient)){ - if(This->dataflow != eRender){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface); - *ppv = &This->IAudioRenderClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){ - if(This->dataflow != eCapture){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface); - *ppv = &This->IAudioCaptureClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioClock)){ - IAudioClock_AddRef(&This->IAudioClock_iface); - *ppv = &This->IAudioClock_iface; - }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){ - IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface); - *ppv = &This->IAudioStreamVolume_iface; - }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ - if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface); - - *ppv = &This->session_wrapper->IAudioSessionControl2_iface; - }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface); - - *ppv = &This->session_wrapper->IChannelAudioVolume_iface; - }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface); - - *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; - } - - if(*ppv){ - sessions_unlock(); - return S_OK; - } - - sessions_unlock(); - - FIXME("stub %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static HRESULT WINAPI AudioClient_IsOffloadCapable(IAudioClient3 *iface, - AUDIO_STREAM_CATEGORY category, BOOL *offload_capable) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - TRACE("(%p)->(0x%x, %p)\n", This, category, offload_capable); - - if(!offload_capable) - return E_INVALIDARG; - - *offload_capable = FALSE; - - return S_OK; -} - -static HRESULT WINAPI AudioClient_SetClientProperties(IAudioClient3 *iface, - const AudioClientProperties *prop) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - const Win8AudioClientProperties *legacy_prop = (const Win8AudioClientProperties *)prop; - - TRACE("(%p)->(%p)\n", This, prop); - - if(!legacy_prop) - return E_POINTER; - - if(legacy_prop->cbSize == sizeof(AudioClientProperties)){ - TRACE("{ bIsOffload: %u, eCategory: 0x%x, Options: 0x%x }\n", - legacy_prop->bIsOffload, - legacy_prop->eCategory, - prop->Options); - }else if(legacy_prop->cbSize == sizeof(Win8AudioClientProperties)){ - TRACE("{ bIsOffload: %u, eCategory: 0x%x }\n", - legacy_prop->bIsOffload, - legacy_prop->eCategory); - }else{ - WARN("Unsupported Size = %d\n", legacy_prop->cbSize); - return E_INVALIDARG; - } - - - if(legacy_prop->bIsOffload) - return AUDCLNT_E_ENDPOINT_OFFLOAD_NOT_CAPABLE; - - return S_OK; -} - -static HRESULT WINAPI AudioClient_GetBufferSizeLimits(IAudioClient3 *iface, - const WAVEFORMATEX *format, BOOL event_driven, REFERENCE_TIME *min_duration, - REFERENCE_TIME *max_duration) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - FIXME("(%p)->(%p, %u, %p, %p)\n", This, format, event_driven, min_duration, max_duration); - - return E_NOTIMPL; -} - -static HRESULT WINAPI AudioClient_GetSharedModeEnginePeriod(IAudioClient3 *iface, - const WAVEFORMATEX *format, UINT32 *default_period_frames, UINT32 *unit_period_frames, - UINT32 *min_period_frames, UINT32 *max_period_frames) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - FIXME("(%p)->(%p, %p, %p, %p, %p)\n", This, format, default_period_frames, unit_period_frames, - min_period_frames, max_period_frames); - - return E_NOTIMPL; -} - -static HRESULT WINAPI AudioClient_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface, - WAVEFORMATEX **cur_format, UINT32 *cur_period_frames) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - FIXME("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames); - - return E_NOTIMPL; -} - -static HRESULT WINAPI AudioClient_InitializeSharedAudioStream(IAudioClient3 *iface, - DWORD flags, UINT32 period_frames, const WAVEFORMATEX *format, - const GUID *session_guid) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - FIXME("(%p)->(0x%lx, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid)); - - return E_NOTIMPL; -} - -static const IAudioClient3Vtbl AudioClient3_Vtbl = -{ - AudioClient_QueryInterface, - AudioClient_AddRef, - AudioClient_Release, - AudioClient_Initialize, - AudioClient_GetBufferSize, - AudioClient_GetStreamLatency, - AudioClient_GetCurrentPadding, - AudioClient_IsFormatSupported, - AudioClient_GetMixFormat, - AudioClient_GetDevicePeriod, - AudioClient_Start, - AudioClient_Stop, - AudioClient_Reset, - AudioClient_SetEventHandle, - AudioClient_GetService, - AudioClient_IsOffloadCapable, - AudioClient_SetClientProperties, - AudioClient_GetBufferSizeLimits, - AudioClient_GetSharedModeEnginePeriod, - AudioClient_GetCurrentSharedModeEnginePeriod, - AudioClient_InitializeSharedAudioStream, -}; - static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) { AudioSessionWrapper *ret; diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c index d8225b65889..e9953c68eef 100644 --- a/dlls/wineoss.drv/oss.c +++ b/dlls/wineoss.drv/oss.c @@ -69,6 +69,9 @@ struct oss_stream
WINE_DEFAULT_DEBUG_CHANNEL(oss);
+static const REFERENCE_TIME g_def_period = 100000; +static const REFERENCE_TIME g_min_period = 50000; + static NTSTATUS oss_not_implemented(void *args) { return STATUS_SUCCESS; @@ -218,6 +221,13 @@ static void get_default_device(EDataFlow flow, char device[OSS_DEVNODE_SIZE]) return; }
+static NTSTATUS oss_main_loop(void *args) +{ + struct main_loop_params *params = args; + NtSetEvent(params->event, NULL); + return STATUS_SUCCESS; +} + static NTSTATUS oss_get_endpoint_ids(void *args) { struct get_endpoint_ids_params *params = args; @@ -552,11 +562,45 @@ static ULONG_PTR zero_bits(void) static NTSTATUS oss_create_stream(void *args) { struct create_stream_params *params = args; - WAVEFORMATEXTENSIBLE *fmtex; + WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE *)params->fmt; struct oss_stream *stream; oss_audioinfo ai; SIZE_T size;
+ if (params->share == AUDCLNT_SHAREMODE_SHARED) { + params->period = g_def_period; + if (params->duration < 3 * params->period) + params->duration = 3 * params->period; + } else { + if (!params->period) + params->period = g_def_period; /* not minimum */ + + if (params->period < g_min_period || params->period > 5000000) { + params->result = AUDCLNT_E_INVALID_DEVICE_PERIOD; + return STATUS_SUCCESS; + } + + if (params->duration > 20000000) { /* the smaller the period, the lower this limit */ + params->result = AUDCLNT_E_BUFFER_SIZE_ERROR; + return STATUS_SUCCESS; + } + + if (params->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) { + if (params->duration != params->period) { + params->result = AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; + return STATUS_SUCCESS; + } + + FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); + + params->result = AUDCLNT_E_DEVICE_IN_USE; + return STATUS_SUCCESS; + } else { + if (params->duration < 8 * params->period) + params->duration = 8 * params->period; /* may grow above 2s */ + } + } + stream = calloc(1, sizeof(*stream)); if(!stream){ params->result = E_OUTOFMEMORY; @@ -1245,6 +1289,18 @@ static NTSTATUS oss_get_mix_format(void *args) return STATUS_SUCCESS; }
+static NTSTATUS oss_get_device_period(void *args) +{ + struct get_device_period_params *params = args; + + if (params->def_period) + *params->def_period = g_def_period; + if (params->min_period) + *params->min_period = g_min_period; + + return STATUS_SUCCESS; +} + static NTSTATUS oss_get_buffer_size(void *args) { struct get_buffer_size_params *params = args; @@ -1635,7 +1691,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = { oss_not_implemented, oss_not_implemented, - oss_not_implemented, + oss_main_loop, oss_get_endpoint_ids, oss_create_stream, oss_release_stream, @@ -1649,7 +1705,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = oss_release_capture_buffer, oss_is_format_supported, oss_get_mix_format, - oss_not_implemented, + oss_get_device_period, oss_get_buffer_size, oss_get_latency, oss_get_current_padding, @@ -1689,6 +1745,19 @@ static NTSTATUS oss_wow64_test_connect(void *args) return STATUS_SUCCESS; }
+static NTSTATUS oss_wow64_main_loop(void *args) +{ + struct + { + PTR32 event; + } *params32 = args; + struct main_loop_params params = + { + .event = ULongToHandle(params32->event) + }; + return oss_main_loop(¶ms); +} + static NTSTATUS oss_wow64_get_endpoint_ids(void *args) { struct @@ -1860,6 +1929,28 @@ static NTSTATUS oss_wow64_get_mix_format(void *args) return STATUS_SUCCESS; }
+static NTSTATUS oss_wow64_get_device_period(void *args) +{ + struct + { + PTR32 device; + EDataFlow flow; + HRESULT result; + PTR32 def_period; + PTR32 min_period; + } *params32 = args; + struct get_device_period_params params = + { + .device = ULongToPtr(params32->device), + .flow = params32->flow, + .def_period = ULongToPtr(params32->def_period), + .min_period = ULongToPtr(params32->min_period), + }; + oss_get_device_period(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + static NTSTATUS oss_wow64_get_buffer_size(void *args) { struct @@ -2037,7 +2128,7 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] = { oss_not_implemented, oss_not_implemented, - oss_not_implemented, + oss_wow64_main_loop, oss_wow64_get_endpoint_ids, oss_wow64_create_stream, oss_wow64_release_stream, @@ -2051,7 +2142,7 @@ unixlib_entry_t __wine_unix_call_wow64_funcs[] = oss_release_capture_buffer, oss_wow64_is_format_supported, oss_wow64_get_mix_format, - oss_not_implemented, + oss_wow64_get_device_period, oss_wow64_get_buffer_size, oss_wow64_get_latency, oss_wow64_get_current_padding,