Skip to content

prehani/mac-sticky-mic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StickyMic

macOS menu bar utility that persists your preferred audio input device. Prevents macOS from silently switching your microphone when AirPods, headsets, or other devices connect/disconnect.

StickyMic menu bar screenshot

Features

  • Priority-based mic selection: Set an ordered list of preferred microphones. StickyMic uses the highest-priority available device.
  • Block list: Mark devices (e.g., AirPods mic, headset mic) as "never use" — they'll be skipped even if macOS selects them.
  • Real-time enforcement: Monitors CoreAudio device events and automatically switches back to your preferred mic within milliseconds.
  • Menu bar status: Shows current mic status at a glance. Click to see all devices, change preferences, or toggle enforcement.
  • Launch at login: Optional auto-start (when installed as .app bundle).

Quick Start

# Build and run
make run

# Or build and run directly
swift build && swift run StickyMic

The mic icon appears in your menu bar. Click it to:

  1. See all connected input devices
  2. Click any device to set it as preferred (#1 priority)
  3. Toggle enforcement on/off

Install as App

# Build .app bundle and install to /Applications
make install

This creates a proper macOS app bundle with LSUIElement (no dock icon) and launch-at-login support.

Commands

Command Description
make build Build debug executable
make release Build release executable
make test Run all tests (51 tests)
make run Build and run directly
make app Build .app bundle
make install Install to /Applications
make clean Remove build artifacts

How It Works

  1. Startup: StickyMic reads your priority list and block list from UserDefaults.
  2. Monitoring: Registers CoreAudio property listeners for device changes and default input changes.
  3. Enforcement: When a change is detected, walks the priority list to find the best available device and sets it as default.
  4. Debounce: A suppress flag + timestamp debounce prevents feedback loops (setting the device triggers a change notification).

Architecture

Sources/StickyMicLib/           # Testable library
  Audio/
    AudioDevice.swift           # Device model with stable UID identity
    AudioHardwareInterface.swift # Protocol for CoreAudio abstraction
    CoreAudioHardware.swift     # Real CoreAudio C API implementation
    AudioDeviceManager.swift    # Orchestrator: enforcement + monitoring
  Preferences/
    PreferenceStore.swift       # Persistence protocol
    PreferenceManager.swift     # Priority list, block list, best-device logic
  Views/
    MenuBarView.swift           # Menu bar dropdown
    PreferencesView.swift       # Settings window

Sources/StickyMic/              # App entry point
  StickyMicApp.swift            # @main, MenuBarExtra

Tests/StickyMicTests/           # 51 tests
  Audio/                        # Device model, manager, CoreAudio system tests
  Preferences/                  # Priority/block logic, UserDefaults persistence
  Integration/                  # Full lifecycle scenarios

Requirements

  • macOS 14.0+ (Sonoma)
  • Swift 6.0+

About

Persist the same audio input on mac regardless of new devices (airpods, etc.) connecting. Will always default back to a selected device when available.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors