diff --git a/app/src/components/AudioPlayer/AudioPlayer.tsx b/app/src/components/AudioPlayer/AudioPlayer.tsx
index 75e1b4e5..667404f3 100644
--- a/app/src/components/AudioPlayer/AudioPlayer.tsx
+++ b/app/src/components/AudioPlayer/AudioPlayer.tsx
@@ -139,7 +139,11 @@ export function AudioPlayer() {
barRadius: 2,
height: 80,
normalize: true,
- backend: 'WebAudio',
+ // Use MediaElement backend (default). Unlike the WebAudio backend,
+ // MediaElement uses a standard
+
+ {/* Save as Custom dialog */}
+
);
}
diff --git a/app/src/components/Sidebar.tsx b/app/src/components/Sidebar.tsx
index ac4e9f17..88659399 100644
--- a/app/src/components/Sidebar.tsx
+++ b/app/src/components/Sidebar.tsx
@@ -45,12 +45,15 @@ export function Sidebar({ isMacOS }: SidebarProps) {
{/* Navigation Buttons */}
- {tabs.map((tab) => {
+ {tabs.map((tab, index) => {
const Icon = tab.icon;
// For index route, use exact match; for others, use default matching
const isActive =
tab.path === '/' ? matchRoute({ to: '/', exact: true }) : matchRoute({ to: tab.path });
+ // Accent fades as buttons get further from the logo
+ const accentOpacity = Math.max(0.08, 0.5 - index * 0.07);
+
return (
)}
diff --git a/docs/RELEASE_v0.2.0.md b/docs/RELEASE_v0.2.0.md
new file mode 100644
index 00000000..9d2d8e7b
--- /dev/null
+++ b/docs/RELEASE_v0.2.0.md
@@ -0,0 +1,163 @@
+# Voicebox v0.2.0 -- Release Notes
+
+## The story
+
+Voicebox v0.1.x shipped as a single-engine voice cloning app built around Qwen3-TTS. It worked, but it was limited: one model family, 10 languages, English-centric emotion, a synchronous generation pipeline that locked the UI, and a hard ceiling on how much text you could generate at once.
+
+v0.2.0 is a ground-up rethink. Voicebox is now a **multi-engine voice cloning platform**. Four TTS engines. 23 languages. Expressive paralinguistic controls. A full post-processing effects pipeline. Unlimited generation length. Asynchronous everything. And it runs on every major GPU vendor -- NVIDIA, AMD, Intel Arc, Apple Silicon -- plus Docker for headless deployment.
+
+This is the release where Voicebox stops being a proof of concept and starts being a real tool.
+
+---
+
+## Major New Features
+
+### Multi-Engine Architecture
+Voicebox now supports **four TTS engines**, each with different strengths. Switch between them per-generation from a single unified interface:
+
+| Engine | Languages | Strengths |
+|--------|-----------|-----------|
+| **Qwen3-TTS** (0.6B / 1.7B) | 10 | High-quality multilingual cloning, delivery instructions ("speak slowly", "whisper") |
+| **LuxTTS** | English | Lightweight (~1GB VRAM), 48kHz output, 150x realtime on CPU |
+| **Chatterbox Multilingual** | 23 | Broadest language coverage -- Arabic, Danish, Finnish, Greek, Hebrew, Hindi, Malay, Norwegian, Polish, Swahili, Swedish, Turkish and more |
+| **Chatterbox Turbo** | English | Fast 350M model with paralinguistic emotion/sound tags |
+
+### Emotions and Paralinguistic Tags (Chatterbox Turbo)
+Type `/` in the text input to open an autocomplete for **9 expressive tags** that the model synthesizes inline with speech:
+
+`[laugh]` `[chuckle]` `[gasp]` `[cough]` `[sigh]` `[groan]` `[sniff]` `[shush]` `[clear throat]`
+
+Tags render as inline badges in a rich text editor and serialize cleanly to the API. This makes generated speech sound natural and expressive in a way that plain TTS can't.
+
+### 23 Languages via Chatterbox Multilingual
+The Chatterbox Multilingual engine brings zero-shot voice cloning to **23 languages**: Arabic, Chinese, Danish, Dutch, English, Finnish, French, German, Greek, Hebrew, Hindi, Italian, Japanese, Korean, Malay, Norwegian, Polish, Portuguese, Russian, Spanish, Swahili, Swedish, and Turkish. The language dropdown dynamically filters to show only languages supported by the selected engine.
+
+### Unlimited Generation Length (Auto-Chunking)
+Previously, long text would hit model context limits and degrade. Now, text is **automatically split at sentence boundaries** and each chunk is generated independently, then crossfaded back together. This is fully engine-agnostic and works with all four engines.
+
+- **Auto-chunking limit slider** (100-5,000 chars, default 800) -- controls when text gets split
+- **Crossfade slider** (0-200ms, default 50ms) -- blends chunk boundaries smoothly, or set to 0 for a hard cut
+- **Max text length raised to 50,000 characters** -- generate entire scripts, chapters, or articles in one go
+- Smart splitting respects abbreviations (Dr., e.g., a.m.), CJK punctuation, and never breaks inside paralinguistic `[tags]`
+
+### Asynchronous Generation Queue
+Generation is now fully **non-blocking**. Submit a generation and immediately start typing the next one -- no more frozen UI waiting for inference to complete.
+
+- Serial execution queue prevents GPU contention across all backends
+- Real-time SSE status streaming (`generating` -> `completed` / `failed`)
+- Failed generations can be retried without re-entering text
+- Stale generations from crashes are auto-recovered on startup
+- Generating status pill shown inline in the story editor
+
+### Post-Processing Effects Pipeline
+A full audio effects system powered by Spotify's `pedalboard` library. Apply effects after generation, preview them in real time, and build reusable presets -- all without leaving the app.
+
+**8 effects available:**
+
+| Effect | What it does |
+|--------|-------------|
+| **Pitch Shift** | Shift pitch up or down by up to 12 semitones |
+| **Reverb** | Room reverb with configurable size, damping, and wet/dry mix |
+| **Delay** | Echo with adjustable delay time, feedback, and mix |
+| **Chorus / Flanger** | Modulated delay -- short for metallic flanger, longer for lush chorus |
+| **Compressor** | Dynamic range compression with threshold, ratio, attack, and release |
+| **Gain** | Volume adjustment from -40 to +40 dB |
+| **High-Pass Filter** | Remove low frequencies below a configurable cutoff |
+| **Low-Pass Filter** | Remove high frequencies above a configurable cutoff |
+
+**Effects presets** -- Four built-in presets ship out of the box (Robotic, Radio, Echo Chamber, Deep Voice), and you can create unlimited custom presets. Presets are drag-and-drop chains of effects with per-parameter sliders.
+
+**Per-profile default effects** -- Assign an effects chain to a voice profile and it applies automatically to every generation with that voice. Override per-generation from the generate box.
+
+**Live preview** -- Audition any effects chain against an existing generation before committing. The preview streams processed audio without saving anything.
+
+### Generation Versions
+Every generation now supports **multiple versions** with full provenance tracking:
+
+- **Original** -- the clean, unprocessed TTS output (always preserved)
+- **Effects versions** -- apply different effects chains to create new versions from any source version
+- **Takes** -- regenerate with the same text and voice but a new seed for variation
+- **Source tracking** -- each version records which version it was derived from
+- **Version pinning in stories** -- pin a specific version to a track clip in the story editor, independent of the generation's default
+- **Favorites** -- star generations to mark them for quick access
+
+---
+
+## New Platform Support
+
+### Linux (Native)
+Full Linux support with `.deb` and `.rpm` packages. Includes PulseAudio/PipeWire audio capture for voice sample recording.
+
+### AMD ROCm GPU Acceleration
+AMD GPU users now get hardware-accelerated inference via ROCm, with automatic `HSA_OVERRIDE_GFX_VERSION` configuration for GPUs not officially in the ROCm compatibility list (e.g., RX 6600).
+
+### NVIDIA CUDA Backend Swap
+The CPU-only release can download and swap in a CUDA-accelerated backend binary from within the app -- no reinstall required. Handles GitHub's 2GB asset limit by downloading split parts and verifying SHA-256 checksums.
+
+### Intel Arc (XPU) and DirectML
+PyTorch backend also supports Intel Arc GPUs via IPEX/XPU and Windows any-GPU via DirectML.
+
+### Docker + Web Deployment
+Run Voicebox headless as a Docker container with the full web UI:
+```bash
+docker compose up
+```
+3-stage build, non-root runtime, health checks, persistent model cache across rebuilds. Binds to localhost only by default.
+
+---
+
+## Model Management
+- **Per-model unload** -- free GPU memory without deleting downloaded models
+- **Custom models directory** -- set `VOICEBOX_MODELS_DIR` to store models anywhere
+- **Model folder migration** -- move all models to a new location with progress tracking
+- **Whisper Turbo** -- added `openai/whisper-large-v3-turbo` as a transcription model option
+- **Download cancel/clear UI** -- cancel in-progress downloads, VS Code-style problems panel for errors
+
+---
+
+## Security
+- **CORS hardening** -- replaced wildcard `*` with an explicit allowlist of local origins; extensible via `VOICEBOX_CORS_ORIGINS` env var
+- **Network access toggle** -- fully disable outbound network requests for air-gapped deployments
+
+## Accessibility
+- Comprehensive screen reader support (tested with NVDA/Narrator) across all major UI surfaces
+- Keyboard navigation for voice cards, history rows, model management, and story editor
+- State-aware `aria-label` attributes on all interactive controls
+
+## Reliability
+- **Atomic audio saves** -- two-phase write prevents corrupted files on crash/interrupt
+- **Filesystem health endpoint** -- proactive disk space and directory writability checks
+- **Errno-specific error messages** -- clear feedback for permission denied, disk full, missing directory
+
+## UX Polish
+- Responsive layout with horizontal-scroll voice cards on mobile
+- App version shown in sidebar
+- Voice card heights normalized
+- Audio player title hidden at narrow widths to prevent overflow
+
+---
+
+## Installation
+
+| Platform | Download |
+|----------|----------|
+| **macOS (Apple Silicon)** | `Voicebox_0.2.0_aarch64.dmg` |
+| **macOS (Intel)** | `Voicebox_0.2.0_x64.dmg` |
+| **Windows** | `Voicebox_0.2.0_x64_en-US.msi` or `x64-setup.exe` |
+| **Linux** | `.deb` / `.rpm` packages |
+| **Docker** | `docker compose up` |
+
+The app includes automatic updates -- future patches will be installed automatically.
+
+---
+
+## Video Script Beats
+
+For the marketing video, focus on these six beats:
+
+1. **"Four engines, one app"** -- show the engine dropdown switching between Qwen, LuxTTS, Chatterbox, and Turbo
+2. **"23 languages"** -- generate the same voice clone in Arabic, Japanese, Hindi, etc.
+3. **"Make it expressive"** -- type `/laugh` and `/sigh` with Chatterbox Turbo, play back the result
+4. **"Shape your sound"** -- apply the Robotic or Deep Voice preset, preview it live, then build a custom effects chain with drag-and-drop
+5. **"No limits"** -- paste a long script, show it auto-chunk and generate seamlessly
+6. **"Queue and go"** -- fire off multiple generations back-to-back without waiting
diff --git a/landing/src/app/api/stars/route.ts b/landing/src/app/api/stars/route.ts
new file mode 100644
index 00000000..bc8f73c5
--- /dev/null
+++ b/landing/src/app/api/stars/route.ts
@@ -0,0 +1,15 @@
+import { NextResponse } from 'next/server';
+import { getStarCount } from '@/lib/releases';
+
+export const dynamic = 'force-dynamic';
+export const revalidate = 600;
+
+export async function GET() {
+ try {
+ const count = await getStarCount();
+ return NextResponse.json({ count });
+ } catch (error) {
+ console.error('Error fetching star count:', error);
+ return NextResponse.json({ error: 'Failed to fetch star count' }, { status: 500 });
+ }
+}
diff --git a/landing/src/app/globals.css b/landing/src/app/globals.css
index 709d74b7..143203e7 100644
--- a/landing/src/app/globals.css
+++ b/landing/src/app/globals.css
@@ -116,16 +116,17 @@
}
/* Noise texture overlay for hero glow */
-.hero-glow::after {
+/* .hero-glow::after {
content: "";
position: absolute;
inset: 0;
z-index: 5;
pointer-events: none;
- background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.8' numOctaves='5' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
- opacity: 0.3;
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2048' height='2048'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.5' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
+ opacity: 0.35;
mix-blend-mode: overlay;
-}
+ will-change: transform;
+} */
/* Scrollbar hiding */
::-webkit-scrollbar {
diff --git a/landing/src/app/layout.tsx b/landing/src/app/layout.tsx
index a5ba9383..164b7f71 100644
--- a/landing/src/app/layout.tsx
+++ b/landing/src/app/layout.tsx
@@ -4,11 +4,11 @@ import './globals.css';
export const metadata: Metadata = {
title: 'Voicebox - Open Source Voice Cloning Desktop App',
description:
- 'Near-perfect voice cloning powered by Qwen3-TTS. Desktop app for Mac, Windows, and Linux. Multi-sample support, smart caching, local or remote inference.',
+ 'Near-perfect voice cloning with multiple TTS engines. Desktop app for Mac, Windows, and Linux. Multi-sample support, smart caching, local or remote inference.',
keywords: [
'voice cloning',
'TTS',
- 'Qwen3',
+ 'multi-engine',
'desktop app',
'AI voice',
'open source',
@@ -32,6 +32,14 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
+
+
+
+
+
{children}
diff --git a/landing/src/app/page.tsx b/landing/src/app/page.tsx
index cc5728e3..e78d1ca3 100644
--- a/landing/src/app/page.tsx
+++ b/landing/src/app/page.tsx
@@ -1,6 +1,6 @@
'use client';
-import { Github } from 'lucide-react';
+import { Github, Globe, Languages, MessageSquare, Zap } from 'lucide-react';
import Image from 'next/image';
import { useEffect, useState } from 'react';
import { ControlUI } from '@/components/ControlUI';
@@ -8,6 +8,7 @@ import { Features } from '@/components/Features';
import { Footer } from '@/components/Footer';
import { Navbar } from '@/components/Navbar';
import { AppleIcon, LinuxIcon, WindowsIcon } from '@/components/PlatformIcons';
+import { VoiceCreator } from '@/components/VoiceCreator';
import { DOWNLOAD_LINKS, GITHUB_REPO } from '@/lib/constants';
import type { DownloadLinks } from '@/lib/releases';
@@ -44,18 +45,18 @@ export default function Home() {
{/* Logo */}
@@ -72,8 +73,8 @@ export default function Home() {
className="fade-in mx-auto mt-6 max-w-2xl text-lg text-muted-foreground md:text-xl"
style={{ animationDelay: '200ms' }}
>
- Open source voice cloning studio powered by Qwen3-TTS. Clone any voice, generate natural
- speech, and compose multi-voice projects — all running locally.
+ Open source voice cloning studio with support for multiple TTS engines. Clone any voice,
+ generate natural speech, and compose multi-voice projects — all running locally.
{/* CTAs */}
@@ -116,27 +117,125 @@ export default function Home() {
{/* ── Features ─────────────────────────────────────────────── */}
- {/* ── About / Manifesto ────────────────────────────────────── */}
+ {/* ── Voice Creator ────────────────────────────────────────── */}
+
+
+ {/* ── Models ─────────────────────────────────────────────────── */}
-
-
- Why Voicebox exists
-
-
-
- Cloud voice cloning services lock your voice data behind subscriptions, rate limits,
- and terms of service that can change at any time. Your voice — and the voices you
- clone — should belong to you.
-
-
- Voicebox is a local-first voice cloning studio. Download a model, clone any voice from
- a few seconds of audio, and generate speech entirely on your machine.
-
-
- Optimized with Metal acceleration on Mac and CUDA on Windows/Linux. No Python install
- required. No cloud. No subscriptions. Free and open-source, forever.
+
+
+
+ Multi-Engine Architecture
+
+
+ Choose the right model for every job. All models run locally on your hardware —
+ download once, use forever.
+
+
+ {/* Qwen3-TTS */}
+
+
+
+
Qwen3-TTS
+ by Alibaba
+
+
+
+ 1.7B
+
+
+ 0.6B
+
+
+
+
+ High-quality multilingual voice cloning with natural prosody. The only engine with
+ delivery instructions — control tone, pace, and emotion with natural language.
+
+ Production-grade voice cloning with the broadest language support. 23 languages with
+ zero-shot cloning and emotion exaggeration control.
+
+
+
+
+ 23 languages
+
+
+
+
+ {/* Chatterbox Turbo */}
+
+
+
+
Chatterbox Turbo
+ by Resemble AI
+
+
+ 350M
+
+
+
+ Lightweight and fast. Supports paralinguistic tags — embed [laugh], [sigh], [gasp]
+ and more directly in your text for expressive, natural speech.
+
+
+
+
+ 350M params
+
+
+
+ [laugh] [sigh] tags
+
+
+
+
+ {/* LuxTTS */}
+
+
+
+
LuxTTS
+ by ZipVoice
+
+
+
+ Ultra-fast, CPU-friendly voice cloning at 48kHz. Exceeds 150x realtime on CPU with
+ ~1GB VRAM. The fastest engine for quick iterations.
+
+
+
+
+ 150x realtime
+
+
+ 48kHz output
+
+
+
+
@@ -193,16 +292,17 @@ export default function Home() {
{/* Linux */}
-
-
+
Linux
-
Coming soon
+
AppImage (x64)
-
+
{/* GitHub link */}
diff --git a/landing/src/components/ControlUI.tsx b/landing/src/components/ControlUI.tsx
index 886f1374..b7babe96 100644
--- a/landing/src/components/ControlUI.tsx
+++ b/landing/src/components/ControlUI.tsx
@@ -17,7 +17,7 @@ import {
Wand2,
} from 'lucide-react';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { LandingAudioPlayer } from './LandingAudioPlayer';
+import { LandingAudioPlayer, unlockAudioContext } from './LandingAudioPlayer';
// ─── Data ───────────────────────────────────────────────────────────────────
// Edit this section to customise all the content shown in the ControlUI demo.
@@ -29,7 +29,7 @@ interface VoiceProfile {
hasEffects: boolean;
}
-/** Voice profiles shown in the 3×3 grid. Index matters — DemoScript references profiles by index. */
+/** Voice profiles shown in the grid / scroll strip. Index matters — DemoScript references profiles by index. */
const PROFILES: VoiceProfile[] = [
{
name: 'Jarvis',
@@ -301,24 +301,27 @@ function LoadingBars({ mode }: { mode: 'idle' | 'generating' | 'playing' }) {
// ─── Profile Card ───────────────────────────────────────────────────────────
-function ProfileCard({
+const ProfileCard = ({
profile,
selected,
selecting,
+ cardRef,
}: {
profile: VoiceProfile;
selected: boolean;
selecting: boolean;
-}) {
+ cardRef?: React.Ref;
+}) => {
return (
-