I was able to replicate the issue seen in [Bug 58113](https://bugs.winehq.org/show_bug.cgi?id=58113) on my M1.
The issue stems from the usage of AudioDevicePropertyVolumeScalar, which the audio driver for the M1 does not support (at least so it appears.) Using AudioObjectIsPropertySettable allows for fast checking for this situation, including preemptively disabling main channel audio if it appears to be unsupported.
-- v3: winecoreaudio: Fixed outdated params, improvements Revert "winecoreaudio: Implement per-channel volume control."
From: Ada yretenai@gmail.com
This reverts commit f46e9b8f120605d984f4ae14b4c815a67fbd1b59. --- dlls/winecoreaudio.drv/coreaudio.c | 37 ++++++++++++++---------------- 1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 6b81a7d1d5c..fdae645a80a 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1762,31 +1762,28 @@ static NTSTATUS unix_set_volumes(void *args) { struct set_volumes_params *params = args; struct coreaudio_stream *stream = handle_get_stream(params->stream); - Float32 level = params->master_volume; + Float32 level = 1.0, tmp; OSStatus sc; UINT32 i; - AudioObjectPropertyAddress prop_addr = { - kAudioDevicePropertyVolumeScalar, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMain - }; - - 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);
- 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; + 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), &vol); - if (sc != noErr) { - WARN("Couldn't set channel #%u volume: %x\n", i, (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]; + + 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; }
From: Ada yretenai@gmail.com
--- dlls/winecoreaudio.drv/coreaudio.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index fdae645a80a..067f4d263d3 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -42,6 +42,7 @@ #include <fcntl.h> #include <fenv.h> #include <unistd.h> +#include <math.h>
#include <CoreAudio/CoreAudio.h> #include <AudioToolbox/AudioFormat.h> @@ -1760,26 +1761,21 @@ static NTSTATUS unix_get_prop_value(void *args)
static NTSTATUS unix_set_volumes(void *args) { + static unsigned int once; + if (!once++) + WARN("CoreAudio doesn't support per-channel volume control\n"); + 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;
- if(params->channel >= stream->fmt->nChannels || params->channel < -1){ - ERR("Incorrect channel %d\n", params->channel); - return STATUS_SUCCESS; + for(i = 0; i < stream->fmt->nChannels; ++i){ + const float vol = params->master_volume * params->volumes[i] * params->session_volumes[i]; + level = fminf(level, vol); }
- 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)
It failed on the revert commit, the build failure being resolved in the subsequent commit...
On Thu May 29 18:31:29 2025 +0000, Ada Ahmed wrote:
It failed on the revert commit, the build failure being resolved in the subsequent commit...
Ideally each commit should build successfully.