hydra

Terminal replacement for Loopback — virtual audio devices and routing on macOS, from a ratatui TUI.
Log | Files | Refs | README | LICENSE

README.md (4300B)


      1 # Hydra
      2 
      3 A terminal-native, functional replacement for [Loopback](https://rogueamoeba.com/loopback/) —
      4 create virtual audio devices, capture per-app audio, combine inputs, monitor, and map
      5 channels, all from a `ratatui` TUI. Fully themeable (drop a `.toml` in
      6 `~/.config/hydra/themes/`, press `t`), with optional terminal-background transparency.
      7 
      8 > macOS only. Per-app capture needs **macOS 14.4+** (Core Audio process taps); the virtual
      9 > driver is a fork of [BlackHole](https://github.com/ExistentialAudio/BlackHole) (GPL-3.0).
     10 
     11 ## Architecture
     12 
     13 | Piece | Crate / dir | Role |
     14 |-------|-------------|------|
     15 | Daemon | `crates/hydrad` | Owns **all** CoreAudio state; persists routing; the only process that links the engine. |
     16 | Engine | `crates/hydra-core` | Routing model, config, CoreAudio FFI (taps / aggregates / IOProcs). |
     17 | Wire protocol | `crates/hydra-ipc` | Shared NDJSON types over a Unix socket. **No macOS deps** — keeps the TUI off CoreAudio. |
     18 | TUI / query | `crates/hydra` | `ratatui` client + (P5) `hydra query --sketchybar`. |
     19 | Driver | `driver/` *(P2)* | Forked BlackHole publishing dynamic devices from a JSON manifest. |
     20 
     21 The daemon runs as a per-user **LaunchAgent** (GUI session — required for tap TCC consent).
     22 Clients talk to it over `~/Library/Application Support/hydra/hydrad.sock`.
     23 
     24 ## Status — a working, self-healing Loopback replacement
     25 
     26 Features (all verified on real hardware unless noted):
     27 - **Per-app capture → virtual mic** — route any app's audio into "Hydra" (2ch / 44.1 kHz,
     28   stereo-confirmed) so other apps (Discord/Vesktop, Zoom, OBS) pick it as an input.
     29 - **Monitor** — or route to your speakers/interface to hear it.
     30 - **Combine** — `c` mixes several apps into one route (shared gain); `C` starts each as a
     31   **separate route** to the same device for independent per-source volume/mute/record.
     32 - **Presets** — `P` save the whole routing setup, `p` recall it in one keystroke.
     33 - **Record any route to WAV** — `R` → `~/Music/Hydra/`.
     34 - **Rename the device** — `n`.
     35 - **dB-scaled meters** with peak-hold; **SketchyBar widget**; `hydra query` subcommand.
     36 - **Self-healing** — a supervisor rebuilds routes after a coreaudiod restart / driver
     37   reinstall, and the LaunchAgent (RunAtLoad + KeepAlive) survives crashes and reboots.
     38   Set a route once; it stays up. (The live coreaudiod-rebuild path is proven by unit test +
     39   no-thrash run; its full end-to-end confirmation is the next real driver reinstall.)
     40 
     41 See `TESTING.md` for the verified-vs-user-gated breakdown and `diagnostics/` for the
     42 audio-debugging toolkit.
     43 
     44 ## Install
     45 
     46 **Prebuilt download (macOS 14.4+):** grab `Hydra-<ver>.dmg` from
     47 <https://ganten.neocities.org/hydra/>, open it, then in Terminal:
     48 
     49 ```sh
     50 cd /Volumes/Hydra*           # the mounted dmg
     51 ./install.sh                 # driver step needs admin + briefly restarts audio
     52 ```
     53 
     54 > Not notarized: if Gatekeeper blocks a binary, `xattr -dr com.apple.quarantine .` in the
     55 > mounted folder, or right-click → Open once.
     56 
     57 **From source:**
     58 
     59 ```sh
     60 ./install.sh              # build everything; prompts before the sudo driver step
     61 ./install.sh --no-driver  # capture→speakers only (no sudo, no virtual mic yet)
     62 ./uninstall.sh            # remove it all
     63 ```
     64 
     65 Then launch the control panel with `hydra`, and pick **Hydra** as the microphone in any
     66 app to receive the routed audio.
     67 
     68 Build a release yourself: `./scripts/make-release.sh` → `dist/release/` (.dmg + source tarball).
     69 
     70 ## Dev loop
     71 
     72 ```sh
     73 cargo run -p hydrad      # terminal 1: the daemon (or run the signed bundle for capture TCC)
     74 cargo run -p hydra       # terminal 2: the TUI
     75 cargo test               # unit tests
     76 ```
     77 
     78 TUI keys:
     79 - **Apps pane:** `↑↓` select · `⏎` monitor selected · `␣` mark · `c` mix marked into one
     80   route · `C` separate route each · `o` cycle output · `a` show all apps · `n` rename device ·
     81   `p` presets · `P` save preset
     82 - **Routes pane** (`⇥` to switch): `↑↓` select · `m` mute · `+/-` gain · `R` record · `d` stop
     83 - **Always:** `r` refresh · `q` quit
     84 
     85 Theming: drop a `.toml` in `~/.config/hydra/themes/` and pick it with `t` (toggle terminal
     86 transparency with `T`). See `themes/README.md`.
     87 
     88 ## License
     89 
     90 GPL-3.0-or-later (the BlackHole-derived driver makes this obligatory for the whole work).