Skip to content

bahmetpalanci/teams-volume

Repository files navigation

TeamsVolume Logo

TeamsVolume

Per-app volume control for Microsoft Teams on macOS

macOS 14.2+ MIT License Swift 5.9+ 100 KB Zero Dependencies Homebrew

TeamsVolume - Per-app volume control for Microsoft Teams on macOS


Why TeamsVolume?

macOS has no built-in per-app volume control. When Microsoft Teams blasts notification sounds or a colleague's audio is too loud, your only option is the system-wide volume slider. TeamsVolume fixes this.

  • Independent volume control — Lower Teams volume without affecting Spotify, YouTube, or anything else.
  • Menu bar slider — Click the icon, drag the slider. Real-time volume adjustment.
  • Native Core Audio Tap — Uses Apple's new Core Audio Tap API (macOS 14.2+). No kernel extensions, no audio drivers, no hacks.
  • Lightweight — ~100 KB binary compiled from a single Swift file. No Electron, no bloat.
  • Zero dependencies — Built with native macOS frameworks. Nothing to install except the app itself.
  • Auto-detect — Automatically finds Teams when it starts, reconnects if Teams restarts.
  • Device change handling — Automatically reconnects when you switch audio devices (speakers, headphones, Bluetooth).
  • Bluetooth optimized — Uses stacked aggregate mode and native buffer sizes for Bluetooth devices (AirPods, etc.).
  • Dead tap recovery — Detects and recovers from broken audio taps automatically.
  • Auto permission detection — Detects Screen Recording permission grant without requiring app restart.
  • Clean audio — Volume ramping prevents clicks and pops when adjusting. At 100% volume, audio passes through as a zero-copy memcpy.
  • Privacy-first — Runs locally, no network access, no analytics, no data collection.

How It Works

TeamsVolume - Volume at 80%
TeamsVolume - Volume at 20%

Action Result
Left-click Show volume slider menu
Drag slider Adjust Teams volume (0-100%)
Right-click Show quit menu

Under the Hood

  1. Finds Microsoft Teams process via PID lookup
  2. Translates PID to AudioObjectID using Core Audio API
  3. Creates a CATapDescription with muteBehavior = .mutedWhenTapped (intercepts Teams audio)
  4. Builds an aggregate device with the tap attached
  5. In the real-time audio callback, multiplies each sample by the volume gain factor
  6. Outputs processed audio to your speakers/headphones

When you quit TeamsVolume, the tap is destroyed and Teams audio returns to normal.

Installation

Install with Homebrew

brew tap bahmetpalanci/tap
brew install teams-volume
open $(brew --prefix)/opt/teams-volume/TeamsVolume.app

Install from Source

git clone https://github.com/bahmetpalanci/teams-volume.git
cd teams-volume
bash build.sh
open TeamsVolume.app

Auto-Start on Login

bash install.sh

Uninstall

bash uninstall.sh

First Launch — Screen Recording Permission

On first launch, macOS will ask for Screen & System Audio Recording permission. This is required for the Core Audio Tap API to capture app audio.

  1. Open System Settings → Privacy & Security → Screen & System Audio Recording
  2. Enable TeamsVolume
  3. Relaunch the app when prompted

This permission is only asked once.

Requirements

  • macOS 14.2 (Sonoma) or later (Core Audio Tap API)
  • Xcode Command Line Tools (xcode-select --install)

Build from Source

TeamsVolume is a single Swift file that compiles to a native macOS app:

# Clone
git clone https://github.com/bahmetpalanci/teams-volume.git
cd teams-volume

# Build (creates TeamsVolume.app)
bash build.sh

# Run
open TeamsVolume.app

The entire source code is in TeamsVolume.swift — a single file, ~560 lines.

Project Structure

teams-volume/
├── TeamsVolume.swift          # Complete source code (single file)
├── build.sh                   # Build script
├── install.sh                 # Install as login item
├── uninstall.sh               # Remove login item
├── TeamsVolume.app/           # App bundle
│   └── Contents/
│       ├── Info.plist
│       ├── Resources/AppIcon.icns
│       └── MacOS/TeamsVolume
├── assets/                    # Logo and screenshots
└── README.md

How It's Built

TeamsVolume uses native macOS APIs:

  • Core Audio Tap APICATapDescription + AudioHardwareCreateProcessTap to intercept app audio (macOS 14.2+)
  • Aggregate Device — Routes tapped audio through a custom IO proc for gain processing
  • NSStatusItem — Places the icon in the menu bar
  • SF Symbols — Native speaker.wave.X.fill icons that reflect current volume level
  • NSSlider — Embedded in menu for real-time volume control
  • Volume Ramping — Exponential smoothing prevents clicks on volume changes
  • LaunchAgent — Auto-start on login via standard macOS mechanism

No frameworks, no package managers, no build systems. Just swiftc.

FAQ

Does it affect audio quality? No. TeamsVolume applies a simple linear gain to each audio sample. At 100% volume, the audio passes through as a zero-copy memcpy — completely unmodified. There is no resampling, compression, or format conversion. Note: When using Bluetooth headsets during a call (mic + speaker), macOS may switch to the lower-quality HFP codec. This is a Bluetooth/macOS limitation, not a TeamsVolume issue.
Does it work with other apps besides Teams? Currently hardcoded for Microsoft Teams, but the Core Audio Tap approach works with any app. Future versions may support multiple apps.
Why macOS 14.2 minimum? The Core Audio Tap API (CATapDescription, AudioHardwareCreateProcessTap) was introduced in macOS 14.2 (Sonoma). There is no way to achieve per-app volume control on older macOS versions without kernel extensions or virtual audio drivers.
Does it need special permissions? Yes — Screen & System Audio Recording permission is required. macOS will prompt you on first launch. This is needed for the Core Audio Tap API to intercept app audio. No microphone access or accessibility permissions are needed.
What happens when Teams is not running? TeamsVolume shows "searching..." in the menu and polls every 3 seconds. When Teams starts, it automatically connects the audio tap.
What happens when I switch audio devices? TeamsVolume automatically detects output device changes and reconnects the audio tap to the new device. For Bluetooth devices, it waits 3 seconds for the Bluetooth stack to settle before reconnecting.
What happens when I quit TeamsVolume? The audio tap is destroyed and Teams audio immediately returns to normal system volume. No residual effects.

Alternatives

App Size Price Per-App Volume Open Source No Drivers
TeamsVolume 100 KB Free Yes Yes Yes
Background Music 5 MB Free Yes Yes No (virtual driver)
SoundSource 25 MB $39 Yes No No (kernel ext)
eqMac 30 MB Freemium Yes Partial No (virtual driver)

See Also

  • MicMute — One-click microphone mute/unmute for macOS menu bar (same author, same philosophy)

Disclaimer

  • This software is provided as-is, without warranty of any kind. Use at your own risk.
  • TeamsVolume is not affiliated with, endorsed by, or associated with Microsoft Corporation or Apple Inc.
  • "Microsoft Teams" is a trademark of Microsoft Corporation.
  • TeamsVolume uses macOS Core Audio Tap API, which requires Screen & System Audio Recording permission. This permission is needed to intercept app audio — TeamsVolume does not record or store any audio data.
  • Bluetooth audio quality note: When using Bluetooth headsets (AirPods, etc.) as both microphone and speaker during a call, macOS switches from the high-quality A2DP codec to the lower-quality HFP (Hands-Free Profile) codec. This is a macOS/Bluetooth limitation, not a TeamsVolume issue. Audio may sound lower quality in this mode regardless of TeamsVolume.
  • TeamsVolume does not collect, transmit, or store any personal data. It has no network access.

Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

License

MIT — Use it however you want.


Built with Swift and native macOS Core Audio APIs

About

Per-app volume control for Microsoft Teams on macOS. Lightweight menu bar utility using native Core Audio Tap API. No drivers, no kernel extensions, just Swift.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors