Overlord e19f398397 Introduce initial implementation of the vmic CLI with PipeWire integration
- Added `Cargo.toml` to define dependencies and project metadata.
- Implemented core CLI functionality for managing virtual microphones (`create`, `edit`, `delete`, `list`, `route`, and `wipe` commands) using `clap`.
- Integrated `rusqlite` for persistent state storage and `pipewire` to manage PipeWire nodes.
- Ensured graceful handling of feedback loops and system defaults during virtual mic creation and deletion.
- Added error handling via `thiserror` for cleaner error definitions.
2026-08-11 13:28:33 +02:00
2026-08-09 08:14:17 +00:00

vmic

Create and manage PipeWire virtual microphones easily, from the command line.

What it does

A vmic is two chained loopback stages:

apps -> vmic_X_sink =(stage 1)=> vmic_X_mid -> vmic_X_mix =(stage 2)=> vmic_X_mic -> recorders
                                                   ^ hardware mic joins here (route -s)

Point an app's output device at vmic_X_sink, and a recording app's input device at vmic_X_mic. Optionally mix in a real microphone downstream, and optionally hear your own output via a self-monitor loopback (which never carries the mixed-in mic).

Requirements

  • PipeWire + pipewire-pulse (pactl, pw-loopback, pw-link on PATH)
  • Rust (edition 2021)

Build

cargo build --release

If the build fails inside libspa-sys (e.g. no field 'data' on type 'spa_pod_builder'), your system clang is newer than the pinned bindgen version supports. Point LIBCLANG_PATH at an older libclang - a quick fix is a pip-vendored one:

python3 -m venv ~/.local/share/vmic-build/libclang-venv
~/.local/share/vmic-build/libclang-venv/bin/pip install libclang

then add to .cargo/config.toml:

[env]
LIBCLANG_PATH = "/home/<you>/.local/share/vmic-build/libclang-venv/lib/python3.*/site-packages/clang/native"

Usage

vmic create <name> [-l]              # create a vmic, optionally with self-monitor
vmic route  <name> -i <app[:media]>  # move an app's playback into the vmic
vmic route  <name> -o <app[:media]>  # move an app's recording off the vmic
vmic route  <name> -s <source|off>   # mix a hardware mic in, or remove it
vmic edit   <name> -l <true|false>   # toggle the self-monitor loopback
vmic edit   <name> -v <0.8|80>       # self-monitor loopback volume
vmic edit   <name> -sv <0.8|80>      # mixed-in source volume
vmic delete <name>                   # tear down one vmic
vmic list                            # show all vmics and their status
vmic wipe                            # tear down every vmic, tracked or not

Aliases: create = mk/make, delete = rm/remove, list = ls, wipe = reset.

Shell completions: vmic completions <bash|zsh|fish|...>.

Example

vmic create podcast -l
# set your app's output device to vmic_podcast_sink
# set your recorder's input device to vmic_podcast_mic
vmic route podcast -s "USB Microphone"

State

Tracked in a SQLite database at ~/.config/vmic/vmic.db (override the directory with VMIC_STATE_DIR_OVERRIDE).

License

APGL-3

Description
Create and manage PipeWire virtual microphones easily.
Readme AGPL-3.0 137 KiB
2026-08-14 19:15:15 +00:00
Languages
Rust 86.4%
Shell 13.6%