[PATCH 07/11] winecoreaudio: Move set_volumes to the unixlib.
Andrew Eikum
aeikum at codeweavers.com
Wed Nov 24 09:26:35 CST 2021
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Wed, Nov 24, 2021 at 11:26:48AM +0000, Huw Davies wrote:
> The session setvol helper has been removed to reduce the number of
> helper functions as the loop over the session's clients isn't very
> complicated.
>
> Session mute is handled by setting the master volume to zero.
>
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
> dlls/winecoreaudio.drv/coreaudio.c | 31 +++++++++
> dlls/winecoreaudio.drv/mmdevdrv.c | 103 ++++++++++-------------------
> dlls/winecoreaudio.drv/unixlib.h | 10 +++
> 3 files changed, 77 insertions(+), 67 deletions(-)
>
> diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c
> index 9636975607c..5569869de6e 100644
> --- a/dlls/winecoreaudio.drv/coreaudio.c
> +++ b/dlls/winecoreaudio.drv/coreaudio.c
> @@ -1554,6 +1554,36 @@ static NTSTATUS is_started(void *args)
> return STATUS_SUCCESS;
> }
>
> +static NTSTATUS set_volumes(void *args)
> +{
> + struct set_volumes_params *params = args;
> + struct coreaudio_stream *stream = params->stream;
> + Float32 level = 1.0, tmp;
> + OSStatus sc;
> + UINT32 i;
> +
> + if(params->channel >= stream->fmt->nChannels || params->channel < -1){
> + ERR("Incorrect channel %d\n", params->channel);
> + return STATUS_SUCCESS;
> + }
> +
> + if(params->channel == -1){
> + for(i = 0; i < stream->fmt->nChannels; ++i){
> + tmp = params->master_volume * params->volumes[i] * params->session_volumes[i];
> + level = tmp < level ? tmp : level;
> + }
> + }else
> + level = params->master_volume * params->volumes[params->channel] *
> + params->session_volumes[params->channel];
> +
> + sc = AudioUnitSetParameter(stream->unit, kHALOutputParam_Volume,
> + kAudioUnitScope_Global, 0, level, 0);
> + if(sc != noErr)
> + WARN("Couldn't set volume: %x\n", (int)sc);
> +
> + return STATUS_SUCCESS;
> +}
> +
> unixlib_entry_t __wine_unix_call_funcs[] =
> {
> get_endpoint_ids,
> @@ -1575,4 +1605,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
> get_position,
> get_frequency,
> is_started,
> + set_volumes,
> };
> diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
> index 07260c16ff0..047979df4f3 100644
> --- a/dlls/winecoreaudio.drv/mmdevdrv.c
> +++ b/dlls/winecoreaudio.drv/mmdevdrv.c
> @@ -176,7 +176,6 @@ static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0,
> static struct list g_sessions = LIST_INIT(g_sessions);
>
> static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
> -static HRESULT ca_setvol(ACImpl *This, struct coreaudio_stream *stream, UINT32 index);
>
> static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
> {
> @@ -337,6 +336,19 @@ static void get_device_guid(EDataFlow flow, DWORD device_id, GUID *guid)
> RegCloseKey(key);
> }
>
> +static void set_stream_volumes(ACImpl *This, int channel)
> +{
> + 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;
> + params.channel = channel;
> +
> + UNIX_CALL(set_volumes, ¶ms);
> +}
> +
> HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out,
> GUID **guids_out, UINT *num, UINT *def_index)
> {
> @@ -782,8 +794,6 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
>
> list_add_tail(&This->session->clients, &This->entry);
>
> - ca_setvol(This, params.stream, -1);
> -
> end:
> if(FAILED(params.result)){
> if(params.stream){
> @@ -792,8 +802,10 @@ end:
> }
> HeapFree(GetProcessHeap(), 0, This->vols);
> This->vols = NULL;
> - }else
> + }else{
> This->stream = params.stream;
> + set_stream_volumes(This, -1);
> + }
>
> LeaveCriticalSection(&g_sessions_lock);
>
> @@ -1818,52 +1830,6 @@ static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl =
> AudioSessionControl_SetDuckingPreference
> };
>
> -/* index == -1 means set all channels, otherwise sets only the given channel */
> -static HRESULT ca_setvol(ACImpl *This, struct coreaudio_stream *stream, UINT32 index)
> -{
> - Float32 level;
> - OSStatus sc;
> -
> - if(This->session->mute)
> - level = 0.;
> - else{
> - if(index == (UINT32)-1){
> - UINT32 i;
> - level = 1.;
> - for(i = 0; i < stream->fmt->nChannels; ++i){
> - Float32 tmp;
> - tmp = This->session->master_vol *
> - This->session->channel_vols[i] * This->vols[i];
> - level = tmp < level ? tmp : level;
> - }
> - }else
> - level = This->session->master_vol *
> - This->session->channel_vols[index] * This->vols[index];
> - }
> -
> - sc = AudioUnitSetParameter(stream->unit, kHALOutputParam_Volume,
> - kAudioUnitScope_Global, 0, level, 0);
> - if(sc != noErr)
> - WARN("Couldn't set volume: %x\n", (int)sc);
> -
> - return S_OK;
> -}
> -
> -static HRESULT ca_session_setvol(AudioSession *session, UINT32 index)
> -{
> - HRESULT ret = S_OK;
> - ACImpl *client;
> -
> - LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry){
> - HRESULT hr;
> - hr = ca_setvol(client, client->stream, index);
> - if(FAILED(hr))
> - ret = hr;
> - }
> -
> - return ret;
> -}
> -
> static HRESULT WINAPI SimpleAudioVolume_QueryInterface(
> ISimpleAudioVolume *iface, REFIID riid, void **ppv)
> {
> @@ -1902,7 +1868,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
> {
> AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
> AudioSession *session = This->session;
> - HRESULT ret;
> + ACImpl *client;
>
> TRACE("(%p)->(%f, %s)\n", session, level, wine_dbgstr_guid(context));
>
> @@ -1916,11 +1882,12 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
>
> session->master_vol = level;
>
> - ret = ca_session_setvol(session, -1);
> + LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry)
> + set_stream_volumes(client, -1);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> - return ret;
> + return S_OK;
> }
>
> static HRESULT WINAPI SimpleAudioVolume_GetMasterVolume(
> @@ -1944,6 +1911,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
> {
> AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
> AudioSession *session = This->session;
> + ACImpl *client;
>
> TRACE("(%p)->(%u, %s)\n", session, mute, debugstr_guid(context));
>
> @@ -1954,7 +1922,8 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
>
> session->mute = mute;
>
> - ca_session_setvol(session, -1);
> + LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry)
> + set_stream_volumes(client, -1);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> @@ -2040,7 +2009,6 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
> IAudioStreamVolume *iface, UINT32 index, float level)
> {
> ACImpl *This = impl_from_IAudioStreamVolume(iface);
> - HRESULT ret;
>
> TRACE("(%p)->(%d, %f)\n", This, index, level);
>
> @@ -2055,11 +2023,11 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
> This->vols[index] = level;
>
> WARN("CoreAudio doesn't support per-channel volume control\n");
> - ret = ca_setvol(This, This->stream, index);
> + set_stream_volumes(This, index);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> - return ret;
> + return S_OK;
> }
>
> static HRESULT WINAPI AudioStreamVolume_GetChannelVolume(
> @@ -2085,7 +2053,6 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
> {
> ACImpl *This = impl_from_IAudioStreamVolume(iface);
> UINT32 i;
> - HRESULT ret;
>
> TRACE("(%p)->(%d, %p)\n", This, count, levels);
>
> @@ -2100,11 +2067,11 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
> for(i = 0; i < count; ++i)
> This->vols[i] = levels[i];
>
> - ret = ca_setvol(This, This->stream, -1);
> + set_stream_volumes(This, -1);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> - return ret;
> + return S_OK;
> }
>
> static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
> @@ -2198,7 +2165,7 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
> {
> AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
> AudioSession *session = This->session;
> - HRESULT ret;
> + ACImpl *client;
>
> TRACE("(%p)->(%d, %f, %s)\n", session, index, level,
> wine_dbgstr_guid(context));
> @@ -2217,11 +2184,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
> session->channel_vols[index] = level;
>
> WARN("CoreAudio doesn't support per-channel volume control\n");
> - ret = ca_session_setvol(session, index);
> + LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry)
> + set_stream_volumes(client, index);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> - return ret;
> + return S_OK;
> }
>
> static HRESULT WINAPI ChannelAudioVolume_GetChannelVolume(
> @@ -2249,8 +2217,8 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
> {
> AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
> AudioSession *session = This->session;
> - int i;
> - HRESULT ret;
> + ACImpl *client;
> + UINT32 i;
>
> TRACE("(%p)->(%d, %p, %s)\n", session, count, levels,
> wine_dbgstr_guid(context));
> @@ -2269,11 +2237,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
> for(i = 0; i < count; ++i)
> session->channel_vols[i] = levels[i];
>
> - ret = ca_session_setvol(session, -1);
> + LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry)
> + set_stream_volumes(client, -1);
>
> LeaveCriticalSection(&g_sessions_lock);
>
> - return ret;
> + return S_OK;
> }
>
> static HRESULT WINAPI ChannelAudioVolume_GetAllVolumes(
> diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
> index aac2df15f47..df00d27c27a 100644
> --- a/dlls/winecoreaudio.drv/unixlib.h
> +++ b/dlls/winecoreaudio.drv/unixlib.h
> @@ -194,6 +194,15 @@ struct is_started_params
> HRESULT result;
> };
>
> +struct set_volumes_params
> +{
> + struct coreaudio_stream *stream;
> + float master_volume;
> + const float *volumes;
> + const float *session_volumes;
> + int channel;
> +};
> +
> enum unix_funcs
> {
> unix_get_endpoint_ids,
> @@ -215,6 +224,7 @@ enum unix_funcs
> unix_get_position,
> unix_get_frequency,
> unix_is_started,
> + unix_set_volumes,
> };
>
> extern unixlib_handle_t coreaudio_handle;
> --
> 2.23.0
>
>
More information about the wine-devel
mailing list