mirror of
https://github.com/MonitorControl/MonitorControl.git
synced 2026-10-23 08:07:35 -06:00
[PR #1929] Add opt-in software volume fallback for digital monitor audio #1339
Labels
No labels
Status: Abandoned
arm64
beta
beta
bug
done
duplicate
enhancement
feedback needed from reporter
in progress
information
invalid
investigating
known Issue
monitor Issue
pull-request
translation
unable to reproduce
unreleased
x86
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/MonitorControl#1339
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/MonitorControl/MonitorControl/pull/1929
Author: @jodansi90
Created: 10/18/2026
Status: 🔄 Open
Base:
main← Head:software-volume-fallback📝 Commits (2)
d0eaf59Add opt-in software volume fallback for digital monitor audioa4efde3Preserve playback key routing with session volume tap📊 Changes
24 files changed (+1509 additions, -3 deletions)
View changed files
📝
MonitorControl.xcodeproj/project.pbxproj(+40 -0)📝
MonitorControl/Info.plist(+2 -0)📝
MonitorControl/Model/OtherDisplay.swift(+12 -1)➕
MonitorControl/SoftwareAudio/AudioBufferListUtilities.swift(+116 -0)➕
MonitorControl/SoftwareAudio/AudioDevices.swift(+109 -0)➕
MonitorControl/SoftwareAudio/AudioOutputDevice.swift(+18 -0)➕
MonitorControl/SoftwareAudio/AudioProcessor.swift(+37 -0)➕
MonitorControl/SoftwareAudio/CoreAudioTapError.swift(+27 -0)➕
MonitorControl/SoftwareAudio/Licenses/CoreAudioTapKit-MIT.txt(+21 -0)➕
MonitorControl/SoftwareAudio/Licenses/CoreAudioTapKit-commit.txt(+1 -0)➕
MonitorControl/SoftwareAudio/MonitorSoftwareAudio.swift(+181 -0)➕
MonitorControl/SoftwareAudio/SoftwareVolume.swift(+268 -0)➕
MonitorControl/SoftwareAudio/SystemAudioDeviceLookup.swift(+113 -0)➕
MonitorControl/SoftwareAudio/SystemAudioTapEngine.swift(+119 -0)➕
MonitorControl/SoftwareAudio/SystemTapCapture.swift(+337 -0)➕
MonitorControl/SoftwareAudio/TapKitIdentity.swift(+12 -0)📝
MonitorControl/Support/AppDelegate.swift(+5 -0)📝
MonitorControl/Support/MediaKeyTapManager.swift(+6 -0)📝
MonitorControl/Support/MenuHandler.swift(+3 -2)📝
MonitorControl/Support/SliderHandler.swift(+4 -0)...and 4 more files
📄 Description
Digital monitor outputs such as the Samsung Smart M80F can expose no writable CoreAudio volume and ignore DDC volume commands: the OSD moves, but the sound stays unchanged. This adds an opt-in software-volume fallback for the selected monitor output on macOS 15+, using a device-scoped CoreAudio process tap and a private aggregate device. It attenuates the audio signal, not the monitor’s internal volume.
The existing slider and multimedia volume/mute keys share one state and the existing OSD. Duplicate press notifications observed 2–4 ms apart are coalesced within 20 ms, so mute does not immediately toggle back and volume does not advance twice. Volume repeat and fine adjustment are preserved. The backend pauses on another output, releases resources on quit/sleep, and uses an idle-aware progress watchdog with bounded recovery.
The change is disabled by default, explains audio capture before opt-in, and is availability-gated without raising the existing deployment target. Brightness, slider layout, signing, application version and updater behavior are retained. No Logitech-specific reader, key remapping, driver or companion app is added. Vendored CoreAudioTapKit is MIT-licensed; its attribution and pinned revision are included in source and app resources. See implementation and testing notes.
Validation
bash Tests/run-software-audio-tests.sh: gain bounds/NaN, stereo ramp to silence, duplicate media events, mute repeat, output matching, watchdog idle/stall/recovery.Related discussion: #1077, particularly https://github.com/MonitorControl/MonitorControl/discussions/1077#discussioncomment-19010109 . This PR offers a concrete implementation for maintainer review; architecture and broader support can be refined together.
Playback-key compatibility update
The dedicated volume interceptor now uses
cgSessionEventTapinstead ofcgAnnotatedSessionEventTap. In the local Samsung prototype, this restored Spotify previous/next/play-pause keys while retaining software volume and mute; the user confirmed playback keys and volume worked together. Playback events are passed through unchanged, without Spotify-specific handling or key remapping. The cleaned PR integration was rebuilt for Apple Silicon and the software-audio test suite passed; the physical confirmation applies to the local prototype. Existing OSD and brightness behavior in this PR remain unchanged.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.