Skip to content

molanocortes/multi-volume-controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multi Volume Controller

A per-app volume mixer for macOS. Multi Volume Controller lists every application that is currently playing sound and gives each one its own volume slider, mute button, and live level meter. Turning one app down or muting it never touches the others.

Multi Volume Controller is built on the modern Core Audio process-tap API (macOS 14.4 and later), so it needs no audio driver, no admin install, and no restart of coreaudiod. It never sets a virtual device as your system output, which is the design choice that keeps it from ever leaving you without sound.

Features

  • One row per audible app: icon, name, live meter, volume slider (up to 150 percent), and a per-app mute.
  • A master "All apps" slider and mute, plus an output device picker.
  • Rows appear and disappear as apps start and stop playing.
  • Per-app levels persist across launches, keyed by bundle id.
  • Lives in both the Dock and the menu bar.
  • Works the same across multiple displays. Taps are per app, not per screen.

Requirements

  • macOS 14.4 or later.
  • Apple Silicon or Intel.
  • Xcode Command Line Tools (full Xcode is not required).

Build and install

./build.sh

That compiles the C real-time core and the Swift app, draws the icon, assembles MultiVolumeController.app, code-signs it, and installs it to /Applications. Then launch Multi Volume Controller from the Dock or Finder.

The build is signed ad hoc, which is enough for the audio permission to work on the machine that built it. To distribute Multi Volume Controller to other Macs, sign it with a Developer ID and notarize it.

Permission

The first time an app plays audio, macOS asks to let Multi Volume Controller record this computer's audio. This is the standard Core Audio system-audio-capture consent (NSAudioCaptureUsageDescription), separate from the microphone and from screen recording. Multi Volume Controller uses it only to re-mix other apps' audio so it can set each one's volume. It never records or saves audio. If you decline, Multi Volume Controller keeps running and shows how to enable it later.

How it works

  • One muted-when-tapped process tap per audible app captures that app's audio and silences its direct output.
  • One private aggregate device wraps those taps around your real output device, which clocks the graph. Sub-tap drift compensation is on.
  • One real-time IOProc reads each tap, multiplies by that app's atomic gain, sums the result, and writes it to the output device. Per-app peaks are published to the meters over a lock-free path.

Audible apps are detected with kAudioProcessPropertyIsRunningOutput. Note that kAudioHardwarePropertyProcessIsAudible returns an unknown-property error when read on a process object on macOS 15, so it cannot be used for this.

The real-time callback does no memory allocation, takes no locks, sends no Objective-C or Swift messages, and does no logging or I/O. A test in tests/rt_test.c verifies the mixing core is correct and runs 500,000 cycles with zero heap allocations.

Why it will not leave you without sound

  • The taps use the muted-when-tapped behavior, so the moment Multi Volume Controller stops reading a tap (it quits, crashes, or stalls) macOS un-mutes the app and it plays normally again.
  • Multi Volume Controller never becomes your system default output device, so its absence changes nothing about how audio is routed.
  • If any tap or device fails to build, Multi Volume Controller tears down cleanly and lets every app play straight through the real output device. It degrades to "no per-app control," never to "no audio."
  • Output device changes (headphones, Bluetooth, HDMI) are detected live and the aggregate is rebuilt around the new device.
  • App Nap is disabled while mixing so the render keeps full priority even when the window is closed.

Limitations

  • Per app means per application. Several tabs in one browser are a single audio process, so they share one row. Separate apps get separate rows.
  • Pro-audio hosts (Logic, GarageBand, Ableton, Pro Tools) and macOS system-audio helpers are excluded by default so Multi Volume Controller does not fight apps that manage their own audio. The exclusion list is editable in Sources/Persistence.swift.

Project layout

  • Sources/RTMixer.h, Sources/RTMixer.c — the real-time mixing core (C).
  • Sources/TapEngine.swift — taps, aggregate, IOProc, device changes, fail-safe.
  • Sources/*.swift, Sources/UI/*.swift — enumeration, model, SwiftUI interface.
  • tests/rt_test.c — correctness and zero-allocation proof for the core.
  • build.sh — build, sign, install.

References

Multi Volume Controller stands on the shoulders of several open efforts that mapped out the process-tap approach:

  • MacMixer by burghr
  • AudioCap by Guilherme Rambo
  • OnlyEQ by zollans
  • Apple's "Capturing system audio with Core Audio taps" sample

License

Multi Volume Controller is dual licensed. It is available under the GNU Affero General Public License v3.0 (see LICENSE), and under a separate commercial license for use in closed-source or proprietary products. For a commercial license, contact the author.

About

A per-app volume mixer for macOS. Driver-free, crash-safe, one slider per app. Built on Core Audio process taps (macOS 14.4+).

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages