From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/coreaudio.c | 37 ++++++++++++++++-------------- dlls/winecoreaudio.drv/mmdevdrv.c | 16 ++++++------- 2 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index aef678e7ca7..902d01459c4 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1665,28 +1665,31 @@ static NTSTATUS unix_set_volumes(void *args) { struct set_volumes_params *params = args; struct coreaudio_stream *stream = handle_get_stream(params->stream); - Float32 level = 1.0, tmp; + Float32 level = params->master_volume; OSStatus sc; UINT32 i; + AudioObjectPropertyAddress prop_addr = { + kAudioDevicePropertyVolumeScalar, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + };
- if(params->channel >= stream->fmt->nChannels || params->channel < -1){ - ERR("Incorrect channel %d\n", params->channel); - return STATUS_SUCCESS; - } + sc = AudioObjectSetPropertyData(stream->dev_id, &prop_addr, 0, NULL, sizeof(float), &level); + if (sc == noErr) + level = 1.0f; + else + WARN("Couldn't set master volume, applying it directly to the channels: %x\n", (int)sc);
- 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]; + for (i = 1; i <= stream->fmt->nChannels; ++i) { + const float vol = level * params->session_volumes[i - 1] * params->volumes[i - 1]; + + prop_addr.mElement = i;
- sc = AudioUnitSetParameter(stream->unit, kHALOutputParam_Volume, - kAudioUnitScope_Global, 0, level, 0); - if(sc != noErr) - WARN("Couldn't set volume: %x\n", (int)sc); + sc = AudioObjectSetPropertyData(stream->dev_id, &prop_addr, 0, NULL, sizeof(float), &vol); + if (sc != noErr) { + WARN("Couldn't set channel #%u volume: %x\n", i, (int)sc); + } + }
return STATUS_SUCCESS; } diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 5113132f09b..6f62a69028b 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -224,7 +224,7 @@ static void get_device_guid(EDataFlow flow, const char *dev, GUID *guid) RegCloseKey(key); }
-static void set_stream_volumes(ACImpl *This, int channel) +static void set_stream_volumes(ACImpl *This) { struct set_volumes_params params;
@@ -232,7 +232,7 @@ static void set_stream_volumes(ACImpl *This, int channel) 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; + params.channel = 0;
UNIX_CALL(set_volumes, ¶ms); } @@ -689,7 +689,7 @@ end: This->vols = NULL; }else{ This->stream = stream; - set_stream_volumes(This, -1); + set_stream_volumes(This); }
sessions_unlock(); @@ -1521,8 +1521,7 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
This->vols[index] = level;
- WARN("CoreAudio doesn't support per-channel volume control\n"); - set_stream_volumes(This, index); + set_stream_volumes(This);
sessions_unlock();
@@ -1566,7 +1565,7 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes( for(i = 0; i < count; ++i) This->vols[i] = levels[i];
- set_stream_volumes(This, -1); + set_stream_volumes(This);
sessions_unlock();
@@ -1682,9 +1681,8 @@ static HRESULT WINAPI ChannelAudioVolume_SetChannelVolume(
session->channel_vols[index] = level;
- WARN("CoreAudio doesn't support per-channel volume control\n"); LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry) - set_stream_volumes(client, index); + set_stream_volumes(client);
sessions_unlock();
@@ -1737,7 +1735,7 @@ static HRESULT WINAPI ChannelAudioVolume_SetAllVolumes( session->channel_vols[i] = levels[i];
LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry) - set_stream_volumes(client, -1); + set_stream_volumes(client);
sessions_unlock();