Per-app volume control for macOS, right in your menu bar.
Turn YouTube down while you're on a WhatsApp call, keep Spotify quiet under a Zoom meeting, or mute that one noisy tab without touching the system volume.
┌─────────────────────────────────────────┐
│ Output: MacBook Pro Speakers │
│ [▶] YouTube (Safari) ━━━━━○────── 45% │
│ [✆] WhatsApp ━━━━━━━━━━○ 100% │
│ [♫] Spotify Muted │
├─────────────────────────────────────────┤
│ Reset All Levels │
│ ✓ Launch at Login │
│ Quit Sonora ⌘Q │
└─────────────────────────────────────────┘
- One slider per app that is playing audio. 100% is the app exactly as it sounds without Sonora, the full volume your speakers give it, and sliding left turns it down. Sonora never makes an app quieter than you set it, and never stands between an app and the speakers at 100%.
- Click an app's icon to mute it.
- Volumes are remembered per app and re-applied whenever it plays again.
- During calls, Sonora can turn other apps down a little (−6 dB), a lot (−12 dB, the default) or mute them, so music from your speakers doesn't leak into your microphone. They fade gently back a moment after the call ends. With Leave Other Apps Alone, apps at 100% stay untouched during calls. macOS itself may still lower them during a call, exactly as it does without Sonora. The first time each app starts a call, a small tip under the menu bar icon suggests macOS's Voice Isolation mic mode and shows how to turn it on. This stops speaker music from leaking into your microphone: call apps' echo cancellers remove speech well but music poorly. During a call the menu also offers Filter Music Out of Your Mic…, which explains how to turn on macOS's Voice Isolation mic mode (the green camera icon in the menu bar during a call → Mic Mode), the strongest mic filter available. macOS doesn't let one app change another app's mic mode, so Sonora can't switch it for you.
- Browser and app helper processes are grouped under the app you know (Chrome, Safari, WhatsApp…).
- No audio driver or kernel extension to install, and no virtual device to pick. It works with whatever output you're using, including AirPods, and follows output changes automatically.
- Apps you leave at 100% are not touched at all.
- The menu bar title "deciphers" into the app name and level whenever you move a slider, then goes back to the plain icon. Menu rows slide in, and playing apps show bouncing activity bars (green during a call). All animation stops if macOS Reduce Motion is on.
- Only regular apps are listed. macOS background processes (Siri, dictation, alert sounds) are left alone, except call audio from
avconferenced, which is shown as FaceTime (or Phone for iPhone calls when only the Phone app is open). - If Sonora can't capture audio (System Audio Recording denied), it stops tapping so no app is ever left silent, and the menu shows how to fix it.
- macOS 14.2 Sonoma or newer (Apple Silicon or Intel)
Download Sonora-<version>.dmg from Releases, open it, and drag Sonora onto Applications.
Sonora isn't notarized by Apple yet, so the first time you open it macOS says it can't verify the developer. Click Done, open System Settings → Privacy & Security, scroll down and click Open Anyway next to Sonora. You only need to do this once.
Requires Go 1.22+ and the Xcode Command Line Tools (xcode-select --install).
git clone https://github.com/astralisdev/sonora.git
cd sonora
make install # builds Sonora.app, copies it to /Applications and launches itOther targets: make app (build only, into build/), make run, make test, make universal (arm64 + x86_64), make dmg (drag-to-Applications disk image), make zip.
make signs the app with your first Developer ID or Apple Development certificate if you have one, so macOS remembers the permission below across rebuilds; with no certificate it falls back to an ad-hoc signature, and macOS asks again after every rebuild.
On first launch Sonora opens a short welcome window. It asks for the audio permission up front, offers to open at login, and then shows you the menu. You can reopen it from Setup Guide… in the menu.
The first time you change an app's volume, macOS asks for permission to capture system audio. Allow it (System Settings → Privacy & Security → Screen & System Audio Recording → System Audio Recording Only). Sonora needs it to read the app's audio and play it back at the new level. Nothing is recorded or sent anywhere.
Turn on Launch at Login from the menu to keep Sonora running.
Sonora uses Core Audio process taps (AudioHardwareCreateProcessTap, added in macOS 14.2).
For every app whose volume is not 100%:
- A private tap is created over all of the app's audio processes. Its mute behaviour is
CATapMutedWhenTapped, so the app's own sound is silenced only while Sonora is reading the tap. - A private aggregate device combines the current output device with that tap.
- A real-time IOProc copies the tapped audio to the output, multiplied by the app's gain. Gain changes are ramped so they don't click.
When the app goes back to 100%, or has been quiet for a few seconds, the tap is torn down and the app plays directly again. If Sonora quits or crashes, every app goes back to normal immediately, because a muted-when-tapped tap stops muting once nobody reads it.
| File | What it does |
|---|---|
main.go |
Entry point and CLI flags (-list, -version) |
settings.go |
Per-app settings saved to ~/Library/Application Support/Sonora/settings.json and exported to the native side |
engine.m |
Audio engine: process discovery and grouping, taps, aggregate devices |
dsp.c / dsp.h |
Real-time signal path: gain ramp and look-ahead limiter (plain C, unit-tested) |
dsp.go, dsp_test.go |
Go wrapper for the DSP, and tests for transparency, clipping, distortion and smoothness |
ui.m |
Menu bar item and slider rows (AppKit) |
The UI and audio layers are Objective-C called through cgo, since AppKit and the real-time Core Audio callback have no pure-Go equivalent. Everything else is Go.
- Calls (WhatsApp, FaceTime, Zoom, Google Meet…) are detected from the echo canceller's signature (the app reads a speaker device back as an input), and a call lasts as long as the app keeps the microphone running. Sonora never replays the call itself: macOS can make call audio louder after the point where Sonora reads it, so a replayed call always came out quieter. The call plays exactly as the app sends it, always 1:1, and Sonora balances your other apps around it.
- Latency: an app that is not at 100% is heard about 60 ms late. Most of that delay comes from macOS's tap and aggregate-device path, and Sonora keeps its own part small (128-frame buffers, 1.3 ms limiter). You can notice it as a slight lip-sync offset on video calls. At 100%, Sonora steps out of the way within 3 s and there is no added delay.
- Creating or removing a tap can cause a very short glitch in other audio.
- Output follows the system default device. Routing apps to different devices isn't supported (yet).
100% is the maximum: the app plays untouched, at its native level, with no added delay. Below 100% the slider is squared (50% ≈ -12 dB, about half as loud to the ear), so you can weigh apps against each other.
Every tapped app goes through a look-ahead peak limiter with a -1 dBFS ceiling. Instead of reshaping individual samples, which is what makes raised audio crackle, it lowers the volume smoothly about 1.3 ms before a peak arrives, then recovers over about 80 ms. Left and right share one gain, so the stereo image never shifts. Gain changes from the sliders are ramped to avoid clicks.
./build/Sonora.app/Contents/MacOS/Sonora -list # audio apps; PLAYING / CALL / idle
SONORA_DEBUG=1 ./build/Sonora.app/Contents/MacOS/Sonora # logs taps, gains, levels and dropouts
./build/Sonora.app/Contents/MacOS/Sonora -snapshot rows.png # renders a menu row for every audio process
./build/Sonora.app/Contents/MacOS/Sonora -snapshot-welcome welcome.png # renders the welcome window
./build/Sonora.app/Contents/MacOS/Sonora -snapshot-tip tip.png # renders the call tip
./build/Sonora.app/Contents/MacOS/Sonora -compare com.apple.Safari # direct vs Sonora at 100%, with spoken labels
make fakecall && build/fakecall 60 # a stand-in voice call (Apple voice processing + a looping voice), no one to call needed
SONORA_SIMULATE_NO_PERMISSION=1 ./build/Sonora.app/Contents/MacOS/Sonora # exercises the permission watchdog- Per-app output device routing
- Global keyboard shortcuts
- Signed and notarized releases, Homebrew cask
- Optional Control Center / WidgetKit controls
Contributions are welcome. Open an issue or a PR.