Commit b3bfa1e5 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

winecoreaudio: Move set_volumes to the unixlib.

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: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAndrew Eikum <aeikum@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 22981cc9
...@@ -1554,6 +1554,36 @@ static NTSTATUS is_started(void *args) ...@@ -1554,6 +1554,36 @@ static NTSTATUS is_started(void *args)
return STATUS_SUCCESS; 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[] = unixlib_entry_t __wine_unix_call_funcs[] =
{ {
get_endpoint_ids, get_endpoint_ids,
...@@ -1575,4 +1605,5 @@ unixlib_entry_t __wine_unix_call_funcs[] = ...@@ -1575,4 +1605,5 @@ unixlib_entry_t __wine_unix_call_funcs[] =
get_position, get_position,
get_frequency, get_frequency,
is_started, is_started,
set_volumes,
}; };
...@@ -176,7 +176,6 @@ static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, ...@@ -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 struct list g_sessions = LIST_INIT(g_sessions);
static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); 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) static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
{ {
...@@ -337,6 +336,19 @@ static void get_device_guid(EDataFlow flow, DWORD device_id, GUID *guid) ...@@ -337,6 +336,19 @@ static void get_device_guid(EDataFlow flow, DWORD device_id, GUID *guid)
RegCloseKey(key); 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, &params);
}
HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out, HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids_out,
GUID **guids_out, UINT *num, UINT *def_index) GUID **guids_out, UINT *num, UINT *def_index)
{ {
...@@ -782,8 +794,6 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, ...@@ -782,8 +794,6 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
list_add_tail(&This->session->clients, &This->entry); list_add_tail(&This->session->clients, &This->entry);
ca_setvol(This, params.stream, -1);
end: end:
if(FAILED(params.result)){ if(FAILED(params.result)){
if(params.stream){ if(params.stream){
...@@ -792,8 +802,10 @@ end: ...@@ -792,8 +802,10 @@ end:
} }
HeapFree(GetProcessHeap(), 0, This->vols); HeapFree(GetProcessHeap(), 0, This->vols);
This->vols = NULL; This->vols = NULL;
}else }else{
This->stream = params.stream; This->stream = params.stream;
set_stream_volumes(This, -1);
}
LeaveCriticalSection(&g_sessions_lock); LeaveCriticalSection(&g_sessions_lock);
...@@ -1818,52 +1830,6 @@ static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl = ...@@ -1818,52 +1830,6 @@ static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl =
AudioSessionControl_SetDuckingPreference 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( static HRESULT WINAPI SimpleAudioVolume_QueryInterface(
ISimpleAudioVolume *iface, REFIID riid, void **ppv) ISimpleAudioVolume *iface, REFIID riid, void **ppv)
{ {
...@@ -1902,7 +1868,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume( ...@@ -1902,7 +1868,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
{ {
AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface); AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
AudioSession *session = This->session; AudioSession *session = This->session;
HRESULT ret; ACImpl *client;
TRACE("(%p)->(%f, %s)\n", session, level, wine_dbgstr_guid(context)); TRACE("(%p)->(%f, %s)\n", session, level, wine_dbgstr_guid(context));
...@@ -1916,11 +1882,12 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume( ...@@ -1916,11 +1882,12 @@ static HRESULT WINAPI SimpleAudioVolume_SetMasterVolume(
session->master_vol = level; 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); LeaveCriticalSection(&g_sessions_lock);
return ret; return S_OK;
} }
static HRESULT WINAPI SimpleAudioVolume_GetMasterVolume( static HRESULT WINAPI SimpleAudioVolume_GetMasterVolume(
...@@ -1944,6 +1911,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface, ...@@ -1944,6 +1911,7 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
{ {
AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface); AudioSessionWrapper *This = impl_from_ISimpleAudioVolume(iface);
AudioSession *session = This->session; AudioSession *session = This->session;
ACImpl *client;
TRACE("(%p)->(%u, %s)\n", session, mute, debugstr_guid(context)); TRACE("(%p)->(%u, %s)\n", session, mute, debugstr_guid(context));
...@@ -1954,7 +1922,8 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface, ...@@ -1954,7 +1922,8 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
session->mute = mute; 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); LeaveCriticalSection(&g_sessions_lock);
...@@ -2040,7 +2009,6 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume( ...@@ -2040,7 +2009,6 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
IAudioStreamVolume *iface, UINT32 index, float level) IAudioStreamVolume *iface, UINT32 index, float level)
{ {
ACImpl *This = impl_from_IAudioStreamVolume(iface); ACImpl *This = impl_from_IAudioStreamVolume(iface);
HRESULT ret;
TRACE("(%p)->(%d, %f)\n", This, index, level); TRACE("(%p)->(%d, %f)\n", This, index, level);
...@@ -2055,11 +2023,11 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume( ...@@ -2055,11 +2023,11 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
This->vols[index] = level; This->vols[index] = level;
WARN("CoreAudio doesn't support per-channel volume control\n"); 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); LeaveCriticalSection(&g_sessions_lock);
return ret; return S_OK;
} }
static HRESULT WINAPI AudioStreamVolume_GetChannelVolume( static HRESULT WINAPI AudioStreamVolume_GetChannelVolume(
...@@ -2085,7 +2053,6 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes( ...@@ -2085,7 +2053,6 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
{ {
ACImpl *This = impl_from_IAudioStreamVolume(iface); ACImpl *This = impl_from_IAudioStreamVolume(iface);
UINT32 i; UINT32 i;
HRESULT ret;
TRACE("(%p)->(%d, %p)\n", This, count, levels); TRACE("(%p)->(%d, %p)\n", This, count, levels);
...@@ -2100,11 +2067,11 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes( ...@@ -2100,11 +2067,11 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
for(i = 0; i < count; ++i) for(i = 0; i < count; ++i)
This->vols[i] = levels[i]; This->vols[i] = levels[i];
ret = ca_setvol(This, This->stream, -1); set_stream_volumes(This, -1);
LeaveCriticalSection(&g_sessions_lock); LeaveCriticalSection(&g_sessions_lock);
return ret; return S_OK;
} }
static HRESULT WINAPI AudioStreamVolume_GetAllVolumes( static HRESULT WINAPI AudioStreamVolume_GetAllVolumes(
...@@ -2198,7 +2165,7 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume( ...@@ -2198,7 +2165,7 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
{ {
AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface); AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
AudioSession *session = This->session; AudioSession *session = This->session;
HRESULT ret; ACImpl *client;
TRACE("(%p)->(%d, %f, %s)\n", session, index, level, TRACE("(%p)->(%d, %f, %s)\n", session, index, level,
wine_dbgstr_guid(context)); wine_dbgstr_guid(context));
...@@ -2217,11 +2184,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume( ...@@ -2217,11 +2184,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
session->channel_vols[index] = level; session->channel_vols[index] = level;
WARN("CoreAudio doesn't support per-channel volume control\n"); 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); LeaveCriticalSection(&g_sessions_lock);
return ret; return S_OK;
} }
static HRESULT WINAPI ChannelAudioVolume_GetChannelVolume( static HRESULT WINAPI ChannelAudioVolume_GetChannelVolume(
...@@ -2249,8 +2217,8 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes( ...@@ -2249,8 +2217,8 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
{ {
AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface); AudioSessionWrapper *This = impl_from_IChannelAudioVolume(iface);
AudioSession *session = This->session; AudioSession *session = This->session;
int i; ACImpl *client;
HRESULT ret; UINT32 i;
TRACE("(%p)->(%d, %p, %s)\n", session, count, levels, TRACE("(%p)->(%d, %p, %s)\n", session, count, levels,
wine_dbgstr_guid(context)); wine_dbgstr_guid(context));
...@@ -2269,11 +2237,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes( ...@@ -2269,11 +2237,12 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes(
for(i = 0; i < count; ++i) for(i = 0; i < count; ++i)
session->channel_vols[i] = levels[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); LeaveCriticalSection(&g_sessions_lock);
return ret; return S_OK;
} }
static HRESULT WINAPI ChannelAudioVolume_GetAllVolumes( static HRESULT WINAPI ChannelAudioVolume_GetAllVolumes(
......
...@@ -194,6 +194,15 @@ struct is_started_params ...@@ -194,6 +194,15 @@ struct is_started_params
HRESULT result; 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 enum unix_funcs
{ {
unix_get_endpoint_ids, unix_get_endpoint_ids,
...@@ -215,6 +224,7 @@ enum unix_funcs ...@@ -215,6 +224,7 @@ enum unix_funcs
unix_get_position, unix_get_position,
unix_get_frequency, unix_get_frequency,
unix_is_started, unix_is_started,
unix_set_volumes,
}; };
extern unixlib_handle_t coreaudio_handle; extern unixlib_handle_t coreaudio_handle;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment