| src/blackhole_doctor | ||
| tests | ||
| .gitignore | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
blackhole-doctor
A macOS-only diagnostic CLI that checks whether your Core Audio routing is ready for real-time voice DSP — the kind of setup you need when piping a voice-transformation engine (pitch shift, EQ, compressor, de-esser) into Zoom / Teams / Meet via the BlackHole virtual audio driver.
$ blackhole-doctor check
Audio devices:
builtin MacBook Pro Microphone (in=1, out=0) [DEFAULT-IN]
blackhole BlackHole 2ch (in=2, out=2)
multioutput Multi-Output Device (in=0, out=2) [DEFAULT-OUT]
Diagnostics:
✓ blackhole_installed
Found BlackHole device(s): BlackHole 2ch.
✓ multi_output_device
Found 1 Multi-Output Device(s): Multi-Output Device
→ (Verify it includes BOTH BlackHole and your speakers.)
! aggregate_device
No Aggregate Device found.
→ Optional: Audio MIDI Setup → + → Create Aggregate Device. ...
Overall: WARN
Why this project
The flagship Catacolabs/voice-enhancer C++ pipeline (HPF → Compressor → EQ
→ DeEsser → PitchShift → gain → Limiter, WSOLA pitch-shift ±12 semitones)
has been gated for weeks on macOS audio routing plumbing — the BlackHole
2ch + Multi-Output + Aggregate Device dance that lets the DSP sit between
your physical mic and Zoom/Teams.
Cron summaries from May 3, May 5, May 6, May 7, and May 9 all flag the same unresolved step: "BlackHole virtual-audio-driver plumbing remains the gating step for the Zoom/Teams demo."
blackhole-doctor solves the boring half of that: a one-shot CLI that
inspects your Core Audio configuration, names every device by role, and
tells you exactly which piece is missing — with the Audio MIDI Setup steps
to fix it. Drop it in front of any voice-DSP demo, screenshot the green
output, and you've got a credible "production-ready DSP" consulting
deliverable that's not just C++ in a vacuum.
It's also a clean OSS standalone tool — anyone shipping a voice-transformation product on Mac (real-time translation, anonymization, voice cloning, accessibility) hits this same routing wall.
Install
pip install -e .
Pure Python stdlib — no third-party dependencies.
Use
blackhole-doctor # default = check
blackhole-doctor check --json # machine-readable output
blackhole-doctor devices # just list Core Audio devices
blackhole-doctor install-help # print Multi-Output / Aggregate setup steps
Exit codes: 0 ok or warn, 1 fail (no BlackHole found).
What it checks
| Check | What it means |
|---|---|
blackhole_installed |
BlackHole 2ch / 16ch / 64ch is registered with Core Audio |
multi_output_device |
A Multi-Output exists (so you can hear yourself + the call) |
aggregate_device |
An Aggregate exists (mic + virtual loopback for the DSP) |
default_input_sane |
Default input isn't pointed at BlackHole by accident |
default_output_sane |
Default output isn't pointed at BlackHole by accident |
How it works
Shells out to system_profiler SPAudioDataType -json, parses the device
tree, classifies each device (builtin / blackhole / aggregate /
multioutput / other), and runs each check against the list. No
private APIs, no kexts, no entitlements.
Tests
python -m pytest tests/ -v
License
MIT — see LICENSE.