Metadata-Version: 2.4
Name: morphmic
Version: 1.0.0
Summary: Real-time voice processor for Linux: virtual mic with DSP graph (gate, denoise, EQ, pitch, ring-mod, band-pass, compressor, limiter, gain).
Author: wachawo
License: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/wachawo/morphmic
Project-URL: Source, https://github.com/wachawo/morphmic
Project-URL: Issues, https://github.com/wachawo/morphmic/issues
Keywords: audio,voice,dsp,pipewire,pulseaudio,virtual-microphone
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Multimedia :: Sound/Audio :: Capture/Recording
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: apscheduler>=3.10
Requires-Dist: click>=8.1
Requires-Dist: numpy>=1.26
Requires-Dist: psutil>=5.9
Requires-Dist: scipy>=1.11
Requires-Dist: sounddevice>=0.5
Requires-Dist: tomli-w>=1.0
Provides-Extra: gui
Requires-Dist: PySide6>=6.5; extra == "gui"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: black; extra == "dev"
Provides-Extra: all
Requires-Dist: morphmic[dev,gui]; extra == "all"
Dynamic: license-file

# 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)

```bash
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/`.

```bash
# 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

```bash
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:

```bash
# 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):

```bash
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 when `pw-cat` or `parec`+`pacat` are 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:

```bash
morphmicd --audio-engine pipe       # subprocess
morphmicd --audio-engine portaudio  # PortAudio
morphmicd --audio-tool pw-cat       # force PipeWire-native
```

Or in `~/.config/morphmic/config.toml`:

```toml
audio_engine = "pipe"     # auto | portaudio | pipe
audio_tool = "auto"       # auto | pw-cat | parec
```

---

## Testing

```bash
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).
