Skip to content

vkehfdl1/MicGuardian

Repository files navigation

Mic Guardian

Mic Guardian Thumbnail

A macOS menubar app that automatically prevents Bluetooth headsets (AirPods, etc.) from hijacking your microphone.

The Problem

When you connect AirPods or any Bluetooth headset, macOS automatically switches the default input device to the headset's microphone. This causes:

  • Your external USB mic to be ignored
  • Terrible audio quality (HFP/SCO codec)
  • Garbage call/recording quality

Mic Guardian detects this behavior and immediately switches back to your protected microphone.

How It Works

  1. Real-time Monitoring: Listens to CoreAudio default input device changes via AudioObjectAddPropertyListenerBlock
  2. Instant Block: When a Bluetooth mic tries to become default input, it gets blocked immediately
  3. Restore Protected Mic: Switches back to your chosen (or auto-selected) non-Bluetooth microphone
  4. Re-assertion (45s total): macOS retries aggressively after connection, so Mic Guardian keeps re-asserting:
    • Phase 1: 0.5s interval × 10s (aggressive blocking)
    • Phase 2: 2s interval × 30s (relaxed blocking)

Features

Feature Description
🛡️ Auto Block Prevents AirPods mic takeover automatically
🎤 Protected Mic Selection Choose any non-Bluetooth mic (USB, built-in, etc.)
📊 Block Counter Shows how many times BT mic was blocked today
⚡ Real-time Status Live display of current input device
✅ Toggle ON/OFF Enable/disable blocking as needed

Requirements

  • macOS 13.0 (Ventura) or later
  • At least one non-Bluetooth microphone to protect
  • Bluetooth headset (AirPods, AirPods Pro, Bose, Sony, etc.)

Build

git clone https://github.com/vkehfdl1/MicGuardian.git
cd MicGuardian
swift build -c release

Install

# Create .app bundle and copy to /Applications
mkdir -p MicGuardian.app/Contents/MacOS
cp .build/release/OpenToothFairy MicGuardian.app/Contents/MacOS/MicGuardian
cp OpenToothFairy/Resources/Info.plist MicGuardian.app/Contents/Info.plist
codesign --sign - --force --deep MicGuardian.app
cp -R MicGuardian.app /Applications/

Or run directly:

.build/release/OpenToothFairy

Usage

  1. Launch the app — 🛡️ icon appears in your menu bar
  2. Click the icon — check the current status:
    • Protected: Name of your protected microphone
    • Current: Currently active input device
    • Blocked today: Number of blocks today
  3. Change Protected Mic → Select your preferred mic (USB mic recommended)
  4. Ensure Block Bluetooth Mics toggle is ON
  5. Connect your AirPods — Blocked today counter should increment
  6. AirPods audio stays on AAC codec (Option+click Bluetooth menu to verify)

Architecture

OpenToothFairy/
├── App/
│   ├── OpenToothFairyApp.swift       # @main, MenuBarExtra scene
│   └── AppDelegate.swift              # LSUIElement, lifecycle
├── Models/
│   └── AudioDevice.swift              # CoreAudio device model
├── Protocols/
│   └── AudioDeviceManaging.swift      # Protocol for audio manager
├── Services/
│   ├── AudioDeviceManager.swift       # CoreAudio C API wrapper
│   └── MicGuardian.swift              # Mic blocking business logic
└── Views/
    └── MenuBarView.swift              # Menubar popover UI

Key Files

File Purpose
MicGuardian.swift Core logic. Detects input changes → blocks BT mic → restores protected mic
AudioDeviceManager.swift Raw CoreAudio C API. Enumerates devices, switches input, listens for changes
MenuBarView.swift SwiftUI menubar UI. Toggle, status display, mic picker

Credits

Inspired by ToothFairy.

  • Zero external dependencies
  • Non-sandboxed (required for system audio device switching)

License

MIT

About

I hate when Airpods hijacks my expensive microphone input on my Mac.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages