barrettotte/doppelganger

TTS voice cloning Discord bot

0

stars

32

commits

Python

primary language

May 19, 2026

updated

discord-bot
tts
voice-cloning
Browse cluster: Text-to-Speech and Voice Synthesis

README

Doppelganger

TTS voice cloning Discord bot.

Two TTS engines are supported:

  • Chatterbox TTS - zero-shot voice cloning from a short reference audio clip, no fine-tuning needed
  • Orpheus TTS - LoRA fine-tuned voices via vLLM for higher quality on specific characters

Quick Start

# Install dependencies (requires CUDA GPU)
uv sync

# Start Postgres
make docker-db

# Run database migrations
make migrate

# Copy and configure environment
cp .env.example .env

# Build dashboard
make frontend

# Start dev server at http://localhost:8000
make dev

Dependencies

  • Python 3.12+ and uv
  • Docker and Docker Compose
  • NVIDIA GPU with CUDA (8-16 GB VRAM for inference)
  • FFmpeg (for Discord voice audio)
  • Node.js + pnpm (for frontend build)

Discord Bot

The bot runs inside the FastAPI process. Starting the API starts the bot. See docs/bot-setup.md for Discord Developer Portal setup.

CommandDescription
/say <character> <text>Generate TTS and play it in a voice channel
/voicesList available character voices

Dashboard

The Svelte dashboard is served at http://localhost:8000:

  • Dashboard - request metrics, recent activity
  • Queue - view, cancel, and bump TTS requests
  • Cache - manage audio cache entries, playback, download
  • Characters - register, delete, and tune character voices
  • Users - view users, blacklist/unblacklist
  • Config - read-only view of current settings
  • Metrics - per-character and per-user request breakdowns
  • System - GPU stats, engine status, cache hit rate, uptime

Voice Cloning

Chatterbox (Zero-Shot)

Register a character with a 5-30 second WAV reference clip. Around 10 seconds of clean mono speech at 22050 Hz works best.

# Upload via API
curl -X POST "http://localhost:8000/api/characters?name=my-character" \
  -F "audio=@/path/to/reference.wav"

# Or place manually and restart
# voices/my-character/reference.wav

Orpheus (Fine-Tuned)

Train a LoRA adapter from multiple audio clips for higher quality. See docs/lora-tuning.md for the full guide.

export CUDA_VISIBLE_DEVICES=0
export CHARACTER=my_character

# Prepare audio clips (3-13s each, normalized)
make prepare-audio ARGS="raw_audio/$CHARACTER/ prepared/$CHARACTER/"

# Transcribe with Whisper
make transcribe ARGS="prepared/$CHARACTER/ --model large"

# Train LoRA adapter
make train-lora ARGS="$CHARACTER prepared/$CHARACTER/ --device cuda --epochs 1"

The voice registry auto-detects adapter files (adapter_config.json) and routes to the Orpheus engine.

API

OpenAPI docs at http://localhost:8000/docs.

Health and Status

MethodPathDescription
GET/healthDB, TTS model, and GPU status
GET/api/statusBot connection, guilds, config
GET/api/metricsRequest counts, top users, queue depth
GET/api/system/statsGPU VRAM, engine status, cache stats, uptime

TTS

MethodPathDescription
POST/api/tts/generateGenerate speech as WAV (cached)
POST/api/tts/streamStream speech in chunks

Characters

MethodPathDescription
GET/api/charactersList all characters
POST/api/charactersCreate character (name + audio upload)
PUT/api/characters/{id}/tuningUpdate per-character TTS parameters
DELETE/api/characters/{id}Delete character and reference audio

Queue

MethodPathDescription
GET/api/queueCurrent queue state
POST/api/queue/{id}/cancelCancel a pending request
POST/api/queue/{id}/bumpMove request to front

Requests

MethodPathDescription
GET/api/requestsList requests (filterable, paginated)
GET/api/requests/{id}Get single request

Users

MethodPathDescription
GET/api/usersList all users
POST/api/users/{id}/blacklistToggle blacklist
GET/api/users/{id}/requestsUser's request history

Cache

MethodPathDescription
GET/api/cacheCache state with all entries
POST/api/cache/toggleEnable/disable cache
POST/api/cache/flushClear all entries
DELETE/api/cache/{key}Delete single entry
GET/api/cache/{key}/downloadDownload cached WAV

Other

MethodPathDescription
GET/api/auditAudit log (filterable)
GET/api/configCurrent settings (secrets redacted)

Configuration

Application

VariableDefaultDescription
DOPPELGANGER_DEBUGfalseEnable debug logging
DOPPELGANGER_HOST0.0.0.0Server bind host
DOPPELGANGER_PORT8000Server bind port
DOPPELGANGER_ALLOWED_ORIGINS["*"]CORS allowed origins
DOPPELGANGER_VOICES_DIRvoicesCharacter voice files directory
DOPPELGANGER_CACHE_MAX_SIZE100Max audio cache entries

Database

VariableDefaultDescription
DOPPELGANGER_DATABASE__HOSTlocalhostPostgreSQL host
DOPPELGANGER_DATABASE__PORT5432PostgreSQL port
DOPPELGANGER_DATABASE__USERdoppelgangerDatabase user
DOPPELGANGER_DATABASE__PASSWORDdoppelgangerDatabase password
DOPPELGANGER_DATABASE__NAMEdoppelgangerDatabase name
DOPPELGANGER_DATABASE__POOL_SIZE5Connection pool size
DOPPELGANGER_DATABASE__POOL_MAX_OVERFLOW10Max pool overflow

Chatterbox TTS

VariableDefaultDescription
DOPPELGANGER_CHATTERBOX__DEVICEcudaTorch device
DOPPELGANGER_CHATTERBOX__EXAGGERATION0.3Vocal expressiveness (0.0-1.0)
DOPPELGANGER_CHATTERBOX__CFG_WEIGHT3.0Classifier-free guidance strength
DOPPELGANGER_CHATTERBOX__TEMPERATURE0.75Sampling temperature
DOPPELGANGER_CHATTERBOX__CHUNK_SIZE50Tokens per streaming chunk

Orpheus TTS

VariableDefaultDescription
DOPPELGANGER_ORPHEUS__ENABLEDtrueEnable Orpheus engine
DOPPELGANGER_ORPHEUS__VLLM_BASE_URLhttp://localhost:8001/v1vLLM API endpoint
DOPPELGANGER_ORPHEUS__TEMPERATURE0.6Generation temperature
DOPPELGANGER_ORPHEUS__TOP_P0.95Nucleus sampling threshold
DOPPELGANGER_ORPHEUS__REPETITION_PENALTY1.1Repetition penalty
DOPPELGANGER_ORPHEUS__FREQUENCY_PENALTY0.0Frequency penalty
HUGGING_FACE_HUB_TOKEN-HF token for model access

Discord

VariableDefaultDescription
DOPPELGANGER_DISCORD__TOKEN-Bot token (required for bot)
DOPPELGANGER_DISCORD__GUILD_ID-Guild ID for slash commands
DOPPELGANGER_DISCORD__REQUIRED_ROLE_ID-Optional required role
DOPPELGANGER_DISCORD__COOLDOWN_SECONDS5Cooldown between plays
DOPPELGANGER_DISCORD__ENTRANCE_SOUND-Optional WAV on channel join
DOPPELGANGER_DISCORD__MAX_TEXT_LENGTH255Max chars per request
DOPPELGANGER_DISCORD__MAX_QUEUE_DEPTH20Max pending requests
DOPPELGANGER_DISCORD__REQUESTS_PER_MINUTE3Per-user rate limit

Development

make test             # All tests (unit + integration)
make test-unit        # Unit tests only (no Docker)
make test-integration # Integration tests (needs Docker)
make check            # Format + lint + type-check
make fmt              # Format with ruff
make lint             # Lint with ruff

Docker

make docker-db        # PostgreSQL only
make docker-up        # API + PostgreSQL
make docker-down      # Stop all containers
make vllm             # Start vLLM for Orpheus
make psql             # Connect to database

References

Contributors

barrettotte

30 commits

barrettotte/doppelganger

TTS voice cloning Discord bot

0

stars

32

commits

Python

primary language

May 19, 2026

updated

discord-bot
tts
voice-cloning
Browse cluster: Text-to-Speech and Voice Synthesis

README

Doppelganger

TTS voice cloning Discord bot.

Two TTS engines are supported:

  • Chatterbox TTS - zero-shot voice cloning from a short reference audio clip, no fine-tuning needed
  • Orpheus TTS - LoRA fine-tuned voices via vLLM for higher quality on specific characters

Quick Start

# Install dependencies (requires CUDA GPU)
uv sync

# Start Postgres
make docker-db

# Run database migrations
make migrate

# Copy and configure environment
cp .env.example .env

# Build dashboard
make frontend

# Start dev server at http://localhost:8000
make dev

Dependencies

  • Python 3.12+ and uv
  • Docker and Docker Compose
  • NVIDIA GPU with CUDA (8-16 GB VRAM for inference)
  • FFmpeg (for Discord voice audio)
  • Node.js + pnpm (for frontend build)

Discord Bot

The bot runs inside the FastAPI process. Starting the API starts the bot. See docs/bot-setup.md for Discord Developer Portal setup.

CommandDescription
/say <character> <text>Generate TTS and play it in a voice channel
/voicesList available character voices

Dashboard

The Svelte dashboard is served at http://localhost:8000:

  • Dashboard - request metrics, recent activity
  • Queue - view, cancel, and bump TTS requests
  • Cache - manage audio cache entries, playback, download
  • Characters - register, delete, and tune character voices
  • Users - view users, blacklist/unblacklist
  • Config - read-only view of current settings
  • Metrics - per-character and per-user request breakdowns
  • System - GPU stats, engine status, cache hit rate, uptime

Voice Cloning

Chatterbox (Zero-Shot)

Register a character with a 5-30 second WAV reference clip. Around 10 seconds of clean mono speech at 22050 Hz works best.

# Upload via API
curl -X POST "http://localhost:8000/api/characters?name=my-character" \
  -F "audio=@/path/to/reference.wav"

# Or place manually and restart
# voices/my-character/reference.wav

Orpheus (Fine-Tuned)

Train a LoRA adapter from multiple audio clips for higher quality. See docs/lora-tuning.md for the full guide.

export CUDA_VISIBLE_DEVICES=0
export CHARACTER=my_character

# Prepare audio clips (3-13s each, normalized)
make prepare-audio ARGS="raw_audio/$CHARACTER/ prepared/$CHARACTER/"

# Transcribe with Whisper
make transcribe ARGS="prepared/$CHARACTER/ --model large"

# Train LoRA adapter
make train-lora ARGS="$CHARACTER prepared/$CHARACTER/ --device cuda --epochs 1"

The voice registry auto-detects adapter files (adapter_config.json) and routes to the Orpheus engine.

API

OpenAPI docs at http://localhost:8000/docs.

Health and Status

MethodPathDescription
GET/healthDB, TTS model, and GPU status
GET/api/statusBot connection, guilds, config
GET/api/metricsRequest counts, top users, queue depth
GET/api/system/statsGPU VRAM, engine status, cache stats, uptime

TTS

MethodPathDescription
POST/api/tts/generateGenerate speech as WAV (cached)
POST/api/tts/streamStream speech in chunks

Characters

MethodPathDescription
GET/api/charactersList all characters
POST/api/charactersCreate character (name + audio upload)
PUT/api/characters/{id}/tuningUpdate per-character TTS parameters
DELETE/api/characters/{id}Delete character and reference audio

Queue

MethodPathDescription
GET/api/queueCurrent queue state
POST/api/queue/{id}/cancelCancel a pending request
POST/api/queue/{id}/bumpMove request to front

Requests

MethodPathDescription
GET/api/requestsList requests (filterable, paginated)
GET/api/requests/{id}Get single request

Users

MethodPathDescription
GET/api/usersList all users
POST/api/users/{id}/blacklistToggle blacklist
GET/api/users/{id}/requestsUser's request history

Cache

MethodPathDescription
GET/api/cacheCache state with all entries
POST/api/cache/toggleEnable/disable cache
POST/api/cache/flushClear all entries
DELETE/api/cache/{key}Delete single entry
GET/api/cache/{key}/downloadDownload cached WAV

Other

MethodPathDescription
GET/api/auditAudit log (filterable)
GET/api/configCurrent settings (secrets redacted)

Configuration

Application

VariableDefaultDescription
DOPPELGANGER_DEBUGfalseEnable debug logging
DOPPELGANGER_HOST0.0.0.0Server bind host
DOPPELGANGER_PORT8000Server bind port
DOPPELGANGER_ALLOWED_ORIGINS["*"]CORS allowed origins
DOPPELGANGER_VOICES_DIRvoicesCharacter voice files directory
DOPPELGANGER_CACHE_MAX_SIZE100Max audio cache entries

Database

VariableDefaultDescription
DOPPELGANGER_DATABASE__HOSTlocalhostPostgreSQL host
DOPPELGANGER_DATABASE__PORT5432PostgreSQL port
DOPPELGANGER_DATABASE__USERdoppelgangerDatabase user
DOPPELGANGER_DATABASE__PASSWORDdoppelgangerDatabase password
DOPPELGANGER_DATABASE__NAMEdoppelgangerDatabase name
DOPPELGANGER_DATABASE__POOL_SIZE5Connection pool size
DOPPELGANGER_DATABASE__POOL_MAX_OVERFLOW10Max pool overflow

Chatterbox TTS

VariableDefaultDescription
DOPPELGANGER_CHATTERBOX__DEVICEcudaTorch device
DOPPELGANGER_CHATTERBOX__EXAGGERATION0.3Vocal expressiveness (0.0-1.0)
DOPPELGANGER_CHATTERBOX__CFG_WEIGHT3.0Classifier-free guidance strength
DOPPELGANGER_CHATTERBOX__TEMPERATURE0.75Sampling temperature
DOPPELGANGER_CHATTERBOX__CHUNK_SIZE50Tokens per streaming chunk

Orpheus TTS

VariableDefaultDescription
DOPPELGANGER_ORPHEUS__ENABLEDtrueEnable Orpheus engine
DOPPELGANGER_ORPHEUS__VLLM_BASE_URLhttp://localhost:8001/v1vLLM API endpoint
DOPPELGANGER_ORPHEUS__TEMPERATURE0.6Generation temperature
DOPPELGANGER_ORPHEUS__TOP_P0.95Nucleus sampling threshold
DOPPELGANGER_ORPHEUS__REPETITION_PENALTY1.1Repetition penalty
DOPPELGANGER_ORPHEUS__FREQUENCY_PENALTY0.0Frequency penalty
HUGGING_FACE_HUB_TOKEN-HF token for model access

Discord

VariableDefaultDescription
DOPPELGANGER_DISCORD__TOKEN-Bot token (required for bot)
DOPPELGANGER_DISCORD__GUILD_ID-Guild ID for slash commands
DOPPELGANGER_DISCORD__REQUIRED_ROLE_ID-Optional required role
DOPPELGANGER_DISCORD__COOLDOWN_SECONDS5Cooldown between plays
DOPPELGANGER_DISCORD__ENTRANCE_SOUND-Optional WAV on channel join
DOPPELGANGER_DISCORD__MAX_TEXT_LENGTH255Max chars per request
DOPPELGANGER_DISCORD__MAX_QUEUE_DEPTH20Max pending requests
DOPPELGANGER_DISCORD__REQUESTS_PER_MINUTE3Per-user rate limit

Development

make test             # All tests (unit + integration)
make test-unit        # Unit tests only (no Docker)
make test-integration # Integration tests (needs Docker)
make check            # Format + lint + type-check
make fmt              # Format with ruff
make lint             # Lint with ruff

Docker

make docker-db        # PostgreSQL only
make docker-up        # API + PostgreSQL
make docker-down      # Stop all containers
make vllm             # Start vLLM for Orpheus
make psql             # Connect to database

References

Contributors

barrettotte

30 commits

Languages

Python

75.9%

Svelte

20.2%

TypeScript

1.9%

SCSS

1.2%