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.
-- v4: winecoreaudio: quality improvements Revert "winecoreaudio: Implement per-channel volume control."
From: Ada yretenai@gmail.com
This reverts commit f46e9b8f120605d984f4ae14b4c815a67fbd1b59. --- dlls/winecoreaudio.drv/coreaudio.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 6b81a7d1d5c..1d47e76df51 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1762,32 +1762,20 @@ 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; - - 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); - } + for(i = 0; i < stream->fmt->nChannels; ++i){ + tmp = params->master_volume * params->volumes[i] * params->session_volumes[i]; + level = tmp < level ? tmp : level; }
+ 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 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 1d47e76df51..8a8a4dd3c34 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,15 +1761,19 @@ 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;
for(i = 0; i < stream->fmt->nChannels; ++i){ - tmp = params->master_volume * params->volumes[i] * params->session_volumes[i]; - level = tmp < level ? tmp : level; + const Float32 vol = params->master_volume * params->volumes[i] * params->session_volumes[i]; + level = fminf(level, vol); }
sc = AudioUnitSetParameter(stream->unit, kHALOutputParam_Volume,
On Thu May 29 18:31:29 2025 +0000, Davide Beatrici wrote:
Ideally each commit should build successfully.
I re-reverted the commit with the fix applied in the same revert, but it seems the CI server badly configured...