Skip to content

Fix persistent low volume after uninstalling Background Music#850

Open
pranahonk wants to merge 1 commit intokyleneideck:masterfrom
pranahonk:fix/persistent-low-volume-841
Open

Fix persistent low volume after uninstalling Background Music#850
pranahonk wants to merge 1 commit intokyleneideck:masterfrom
pranahonk:fix/persistent-low-volume-841

Conversation

@pranahonk
Copy link
Copy Markdown

Summary

Fixes #841 — After uninstalling Background Music, system audio volume is persistently low even with the slider at 100%. Running sudo killall coreaudiod temporarily fixes it, but the issue returns after reboot or when restarting Apple Music.

Root cause: During app termination (both normal quit and killall from the uninstall script), BGMDeviceControlSync's volume/mute listeners were still active when unsetBGMDeviceAsOSDefault changed the default device back. This default device change triggered HAL notifications that could cause the listeners to sync a stale/incorrect volume to the output device. macOS then persisted this bad volume state in audio preferences, causing it to survive reboots.

Fix:

  1. Add prepareForTermination to BGMAudioDeviceManager — Deactivates control sync (removes volume/mute listeners) and playthrough BEFORE the default device is changed back. Called from both applicationWillTerminate and BGMTermination::CleanUpAudioDevices (signal handler for SIGTERM/SIGINT).

  2. Clean up audio preferences in uninstall script — Removes BGMDevice entries (BGMDevice, BGMDevice_UISounds) from macOS audio preference plists (com.apple.audio.DeviceSettings.plist, com.apple.audio.SystemSettings.plist, and ByHost audio plists) to prevent stale device settings from persisting.

Test plan

  • Build with latest Xcode (verified: BUILD SUCCEEDED)
  • Install Background Music, adjust volume, then quit — volume should remain at the correct level
  • Install Background Music, then uninstall via uninstall.sh — volume should remain correct
  • Reboot after uninstall — volume should still be correct
  • Restart Apple Music after uninstall — volume should not drop

…ideck#841)

Deactivate control sync and playthrough BEFORE changing the default
device back during app termination. Previously, the volume sync
listeners were still active when the default device changed, which
could leave the output device at the wrong volume — a state that
persisted across reboots via macOS audio preferences.

Also clean up BGMDevice entries from macOS audio preference plists
during uninstall to prevent stale device settings from affecting
volume after BGMDevice is removed.
@kyleneideck
Copy link
Copy Markdown
Owner

Hi @pranahonk, thanks for the PRs. I'm actually sick right now, but I'll take a look when I get a chance.

In the meantime, do you have any advice for reproducing the bug? I haven't been able to. I just followed the steps in #841.

If you have a way to reproduce the underlying macOS bug without Background Music, that would really help, too. Plus then we could report the bug to Apple.

What macOS version are you testing on?

Can you explain how you figured out what the root cause was? I can try to follow the same process and see if my system matches yours.

This default device change triggered HAL notifications that could cause the listeners to sync a stale/incorrect volume to the output device. macOS then persisted this bad volume state in audio preferences, causing it to survive reboots.

Can you explain this a bit? What do you mean by a stale/incorrect volume? What does macOS add to your .plist files when it persists that?

It looks like the code you added to BGMApp/BGMApp/_uninstall-non-interactive.sh removes BGMDevice (and BGMDevice_UISounds) from some macOS plists that cache some properties and info from your devices. Do you know why that fixes the stale/incorrect volume that was synced to the output device?

@pranahonk
Copy link
Copy Markdown
Author

pranahonk commented Apr 2, 2026

Hi @kyleneideck , hope you feel better soon. Let me try to answer each question.
macOS version: macOS 15 (Sequoia, Darwin 25.3)

Reproducing the bug:
The most reliable path I found:

  1. Note your current output volume (e.g., 75% in System Settings → Sound).
  2. Open Background Music. The BGMApp output slider will sync to your output device's volume.
  3. Lower the BGMApp output volume slider to something very low (e.g., 5–10%). This sets BGMDevice's volume and BGMDeviceControlSync immediately mirrors it to your real output device.
  4. Quit Background Music with Cmd+Q (or killall "Background Music").
  5. Open System Settings → Sound → Output. The output device volume should now be 5–10%.
  6. Restart your Mac. It'll still be at 5–10% — or if you've uninstalled, the next audio app you launch might restart coreaudiod and restore from the plist.

The race condition means it doesn't always reproduce. The key is ensuring BGMDevice's volume is significantly different from the output device's "natural" volume before quitting.

Root cause (what I believe is happening):
BGMDeviceControlSync registers AudioObjectPropertyListener callbacks on BGMDevice for kAudioDevicePropertyVolumeScalar and kAudioDevicePropertyMute. When BGMApp calls UnsetAsOSDefault during termination, the HAL transition can fire those listeners on BGMDevice. BGMDeviceListenerProc then calls mOutputDevice.CopyVolumeFrom(mBGMDevice, scope), pushing BGMDevice's current volume (which may be low) onto the real output device.

This is the "stale volume" — BGMDevice had a volume set for Background Music's routing purposes, and it gets applied to your real output device at quit time.

The fix in prepareForTermination deactivates the listeners before unsetBGMDeviceAsOSDefault runs. Even if the HAL fires the notification, the listener proc checks mActive (now false) and returns early without touching the output device.

I'm honest that I haven't traced which exact internal coreaudiod event fires the notification during the device switch — it's closed source. But the deactivation-first ordering removes the possibility entirely.

GloryWord added a commit to GloryWord/BackgroundMusic that referenced this pull request Apr 12, 2026
Recent post-v0.4.3 Tahoe reports pointed to two failure modes that made
Background Music feel unsafe to use: aggregate output devices could lose
usable volume controls, and quitting or uninstalling could leave the
system stuck at the wrong volume. This change pulls the minimal proven
fixes onto a single branch so Tahoe users can build from source without
reopening the broader helper/ducking design.

The aggregate-device lane now treats aggregate outputs as special cases
for control detection and skips deprecated volume/mute sync paths that
can corrupt System Settings state. The termination lane deactivates
control-sync and playthrough before restoring the default device, and the
uninstall path removes stale BGM device preference entries that can keep
incorrect volume state alive across restarts.

Constraint: Must stay close to upstream master to preserve CoreAudio behavior and ease future rebases
Constraint: Cannot fully verify privileged install/runtime helper behavior in this environment because sudo is unavailable
Rejected: Large Tahoe-specific refactor of the helper/ducking pipeline | too broad without a reproducible runtime failure locally
Rejected: Leaving the open Tahoe stability fixes unmerged locally | keeps known aggregate/shutdown regressions in the user build
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Treat this as a Tahoe stability lane, not a complete fix for FaceTime/browser ducking; validate runtime capture separately on the target machine
Tested: xcodebuild build (Background Music Device, Background Music, BGMXPCHelper)
Tested: xcodebuild test -only-testing:BGMDriverTests
Tested: xcodebuild test -only-testing:BGMAppUnitTests
Not-tested: Privileged install of BGMXPCHelper/driver via launchd
Not-tested: Real FaceTime + browser YouTube runtime on macOS Tahoe 26.3.1
Related: upstream PR kyleneideck#849
Related: upstream PR kyleneideck#850
@kyleneideck
Copy link
Copy Markdown
Owner

kyleneideck commented Apr 19, 2026

Thanks for the repro instructions. I still haven't been able to reproduce the bug, unfortunately.

I wouldn't be too opposed to merging your fix just based on your results, but I'd like to try to understand what's going on a bit more. I'm trying to imagine what sort of bug in macOS could plausibly result in the symptoms you're seeing, but I haven't been able to come up with much. I think there might be something else going on that we're missing.

How consistently are you able to reproduce the bug? You mentioned that it doesn't always happen. How often does it happen? It's a pain to test since you have to reboot to reproduce it, so I wouldn't expect you to have a lot of data, but it would help to know how much.

Have you tried reinstalling Background Music without your fix since you tested your fix? If so, were you able to reproduce the bug? If you could get logs from Console.app covering that for Background Music, coreaudiod, Music.app and any other logs matching "audio", that would be ideal. It would take a fair amount of effort, though, so don't feel obligated.

You mentioned that the bug sometimes occurred when you reboot and sometimes when you launched Music.app. Do any other apps ever trigger it? Does it ever go away after you trigger it or do you have to reboot or restart coreaudiod every time?

I'm wondering if it might have something to do with macOS's audio ducking. I don't know much about it, but it might match the symptoms, especially this from #841:

If I change the volume to 50% using the keyboard or menu bar, it becomes even quieter, as if a "hidden" gain is set very low.

Is there any chance you might have had a process running that was using kAudioSessionProperty_OtherMixableAudioShouldDuck or voiceProcessingOtherAudioDucking or similar? Maybe something like this: https://apple.stackexchange.com/questions/458817/audio-keeps-ducking-going-down-m1-mac-mini-on-macos-ventura-13-3-1

In your repro instructions, when you said

Restart your Mac. It'll still be at 5–10% — or if you've uninstalled, the next audio app you launch might restart coreaudiod and restore from the plist.

It's expected behaviour for the volume to be set to 5-10%, since that's what you set last in BGMApp. Did you mean that it sounds like it's at 5-10% volume even when you change the volume to 100%?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persistent low volume / audio attenuation after uninstalling Background Music

2 participants