Real-time voice processor for Linux: virtual mic with DSP graph (gate, denoise, EQ, pitch, ring-mod, band-pass, compressor, limiter, gain).
Project description
MorphMic
Real-time voice processor for Linux. Captures audio from a physical
microphone, runs it through a DSP graph (gate, denoise, EQ, pitch / formant
shift, ring modulator, band-pass, compressor, limiter, gain) and exposes the
result as a virtual microphone MorphMic_Microphone that Discord, Zoom, OBS,
the browser, etc. pick up via PipeWire/PulseAudio.
Components
| Binary | Purpose |
|---|---|
morphmicd |
Long-running daemon: pactl module lifecycle, real-time DSP, JSON-RPC server. |
morphmic-gui |
PySide6 desktop GUI: dark theme, profile picker with editor, VU meters, ECHO test mode. |
morphmic-tui |
curses console UI: same feature surface, no X11 needed. |
morphmic |
Click-based CLI for scripts and headless setups. |
The daemon and the clients talk over a Unix socket ($XDG_RUNTIME_DIR/morphmic/control.sock, mode 0600) using JSON-RPC 2.0.
License: GPL-3.0-or-later.
Installation
System dependencies (Ubuntu 24.04)
sudo apt install -y python3.12 python3-venv python3-pip \
libportaudio2 portaudio19-dev librubberband-dev \
pulseaudio-utils pipewire pipewire-pulse ffmpeg \
autoconf automake libtool
# librnnoise is not in the Ubuntu 24.04 repos — build from source.
git clone --depth 1 https://github.com/xiph/rnnoise.git /tmp/rnnoise
(cd /tmp/rnnoise && ./autogen.sh && ./configure && make && sudo make install && sudo ldconfig)
Install MorphMic
Pick one. All three install the same morphmicd, morphmic-gui,
morphmic-tui, morphmic console scripts into the venv's bin/.
# A) Editable install from a local clone (dev workflow)
git clone https://github.com/wachawo/morphmic.git
cd morphmic
python3.12 -m venv .venv
.venv/bin/pip install -e ".[gui,dev]"
# B) Install straight from GitHub (no clone)
python3.12 -m venv .venv
.venv/bin/pip install "morphmic[gui] @ git+https://github.com/wachawo/morphmic.git"
# C) Headless / CLI-only (skip the [gui] extra to avoid PySide6)
.venv/bin/pip install "morphmic @ git+https://github.com/wachawo/morphmic.git"
Extras: gui adds PySide6, dev adds pytest/ruff/black, all is gui+dev.
Docker Compose
docker compose up -d # vc_daemon + vc_gui services
The host PipeWire socket is forwarded via /run/user/1000.
Quick start
After installing via pip (editable or from GitHub), activate the venv and
use the short commands:
# 1. Start the daemon (creates MorphMic_Microphone, runs DSP with profile "clean").
morphmicd --profile clean
# 2a. Desktop GUI
morphmic-gui
# 2b. Console TUI (curses, works over SSH)
morphmic-tui
# 2c. CLI commands
morphmic status
morphmic profiles set deep
morphmic denoise on --level 0.7
morphmic echo on --delay-ms 1500
# Self-check
morphmic doctor
Equivalent dev forms (run straight from a checkout, no install needed):
python3 daemon/main.py --profile clean
python3 gui/main.py
python3 tui/main.py
python3 -m tui.cli status
In Discord/Zoom/OBS/the browser, pick MorphMic_Microphone as the input device.
Built-in profiles
| Profile | Effect |
|---|---|
clean |
Gate + denoise + EQ + compressor + limiter (default). |
bypass |
Pass-through, no processing. |
deep |
Low, bassy (pitch -3, formant -3). |
bright |
Bright, airy (pitch +2, formant +1). |
robot |
Ring modulator at 80 Hz. |
radio |
Old-radio: 300-3000 Hz band-pass + soft clip. |
monster |
Deep monster (pitch -7, formant -5). |
anonymous |
Anonymisation (pitch -5 + 60 Hz ring-mod). |
child |
Higher pitch + formant lift. |
woman |
Pitch +3, formant +2. |
olderman |
Pitch -2, formant -1, slight roughness. |
Profiles are TOML files in ~/.config/morphmic/profiles/. Create custom
ones from the GUI (New… → editor) or from the CLI (profiles export →
edit → profiles save).
Audio engine
The daemon supports two backends:
pipe(default whenpw-catorparec+pacatare installed) — capture/playback through subprocesses. Bypasses libpulse entirely; opens in ~50 ms instead of the 30 s timeout that PortAudio's pulse host API produces on PipeWire systems where pipewire-pulse is wedged.portaudio—sd.Stream(device=("pulse","pulse")). Lower latency, the original code path, recommended on classic PulseAudio.
Select the backend:
morphmicd --audio-engine pipe # subprocess
morphmicd --audio-engine portaudio # PortAudio
morphmicd --audio-tool pw-cat # force PipeWire-native
Or in ~/.config/morphmic/config.toml:
audio_engine = "pipe" # auto | portaudio | pipe
audio_tool = "auto" # auto | pw-cat | parec
Testing
bash scripts/run_tests.sh # ruff + black + pytest
192 unit + integration tests at v1.0.0.
System requirements
- Ubuntu 24.04 LTS or any distribution with PipeWire ≥ 1.0 + WirePlumber.
- Python ≥ 3.12.
- Any PipeWire-compatible microphone.
Project files
ROADMAP.md— planned features for upcoming releases.CHANGELOG.md— release-by-release notes.LICENSE— full license text (GPL-3.0-or-later).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file morphmic-1.0.0.tar.gz.
File metadata
- Download URL: morphmic-1.0.0.tar.gz
- Upload date:
- Size: 77.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1df958b3f9f81b8339bd528d6fbdd798d1cc7d2558943341533e18adba134fb9
|
|
| MD5 |
aca71154bc8dee78227f410c76346738
|
|
| BLAKE2b-256 |
f26e57310d9d249da0bc89ddbf04302899d0ad7b2538fc7719e801544518192f
|
Provenance
The following attestation bundles were made for morphmic-1.0.0.tar.gz:
Publisher:
publish.yml on wachawo/morphmic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphmic-1.0.0.tar.gz -
Subject digest:
1df958b3f9f81b8339bd528d6fbdd798d1cc7d2558943341533e18adba134fb9 - Sigstore transparency entry: 1403365638
- Sigstore integration time:
-
Permalink:
wachawo/morphmic@71a7850ff119c72573411c7f6d118d101e045a55 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wachawo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@71a7850ff119c72573411c7f6d118d101e045a55 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file morphmic-1.0.0-py3-none-any.whl.
File metadata
- Download URL: morphmic-1.0.0-py3-none-any.whl
- Upload date:
- Size: 95.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6570268c611441364c8e0a65a7a32f80363ad26a3a0f365e0f390528b257b128
|
|
| MD5 |
8ea4e370f48a2ae96f576ffe9307cf59
|
|
| BLAKE2b-256 |
44e0483b3d2bda293ed44e45876240357063ce152b7bf416ce9beaf0df282c42
|
Provenance
The following attestation bundles were made for morphmic-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on wachawo/morphmic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphmic-1.0.0-py3-none-any.whl -
Subject digest:
6570268c611441364c8e0a65a7a32f80363ad26a3a0f365e0f390528b257b128 - Sigstore transparency entry: 1403365707
- Sigstore integration time:
-
Permalink:
wachawo/morphmic@71a7850ff119c72573411c7f6d118d101e045a55 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wachawo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@71a7850ff119c72573411c7f6d118d101e045a55 -
Trigger Event:
workflow_dispatch
-
Statement type: