better docs

This commit is contained in:
Jamie Pine
2026-01-25 21:42:38 -08:00
parent 82431dc5f5
commit 9396c6c86d
18 changed files with 750 additions and 5488 deletions
-1215
View File
File diff suppressed because it is too large Load Diff
+8 -21
View File
@@ -1,6 +1,6 @@
# Tauri v2 Autoupdater Setup
# Auto-Updater Documentation
The autoupdater has been configured for this project. Follow these steps to complete the setup.
Voicebox includes automatic updates powered by Tauri's updater plugin. This document explains how it works for both users and developers.
## 1. Generate Signing Keys
@@ -148,28 +148,15 @@ Add your private key to GitHub secrets:
- Add `TAURI_SIGNING_PRIVATE_KEY` with the content of `~/.tauri/voicebox.key`
- Add `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` (empty string if no password)
## 5. Frontend Integration (Already Completed)
## Frontend Integration
The frontend integration is already complete in this project with the following components:
The frontend integration is complete with automatic update notifications and manual update checks:
### Automatic Update Notifications
- `app/src/components/UpdateNotification.tsx` - Shows a banner when updates are available
- Automatically checks for updates on app startup
- Displays download/install progress
- Only shows in Tauri desktop builds
- **Update Notification Banner** - Appears automatically when updates are available
- **Settings Panel** - Manual "Check for Updates" button in Settings tab
- **Update Hook** - React hook handles all update operations
### Manual Update Check
- `app/src/components/ServerSettings/UpdateStatus.tsx` - Settings panel for updates
- Allows manual update checks via "Check for Updates" button
- Shows current version and update status
- Located in the Settings tab (only visible in Tauri builds)
### Update Hook
- `app/src/hooks/useAutoUpdater.ts` - React hook for update functionality
- Handles update checking, downloading, and installation
- Includes Tauri context detection (won't run in web builds)
The components are already integrated into the main App layout.
See `docs/AUTOUPDATER_QUICKSTART.md` for a quick setup guide.
## Security Notes
-246
View File
@@ -1,246 +0,0 @@
# 🎉 Backend Implementation Complete!
Your voicebox backend is fully implemented and ready for frontend integration.
## What Was Built
### 📦 Complete Backend (1,500 lines, 12 files)
I've implemented a **production-quality FastAPI backend** based on the best patterns from your reference projects:
#### Core Modules
1. **TTS Module** (`backend/tts.py`)
- Qwen3-TTS model loading and inference
- Voice prompt creation with caching
- Multi-reference combination
- Model size switching (1.7B/0.6B)
- Async generation
2. **Profiles Module** (`backend/profiles.py`)
- Full CRUD for voice profiles
- Multi-sample support per profile
- Audio validation
- Automatic sample combination
3. **History Module** (`backend/history.py`)
- Generation tracking with full metadata
- Search and filtering
- Pagination
- Statistics
4. **Transcription Module** (`backend/transcribe.py`)
- Whisper ASR integration
- Language hints
- Model management
5. **Database Module** (`backend/database.py`)
- SQLite with SQLAlchemy ORM
- Clean schema design
- Proper relationships
6. **Utils Module** (`backend/utils/`)
- Audio processing and validation
- Voice prompt caching (memory + disk)
- Input validation
7. **API Module** (`backend/main.py`)
- 20+ REST endpoints
- File upload/download
- Health checks
- Model management
## 🎯 What's Different from References
### Better Than ALL References
| Feature | Your Backend | Reference Projects |
|---------|-------------|-------------------|
| **Code Organization** | ✅ 12 modular files (~1,500 lines) | ❌ 1-2 monolithic files (2,815 lines) |
| **Type Safety** | ✅ 100% Pydantic + type hints | ❌ Little to no typing |
| **Async/Await** | ✅ Full async throughout | ⚠️ Partial or none |
| **Caching** | ✅ Voice prompts (memory + disk) | ⚠️ Partial or none |
| **Multi-Sample** | ✅ Advanced combination | ⚠️ Basic or none |
| **Database** | ✅ SQLite with search | ❌ File-based |
| **API Design** | ✅ 20+ RESTful endpoints | ⚠️ 3 endpoints or Gradio only |
| **Error Handling** | ✅ Detailed + contextual | ⚠️ Generic |
### Pattern Sources
-**Architecture** from mimic (best structured)
-**Caching** from Voice-Clone-Studio (brilliant implementation)
-**Audio processing** from qwen3-tts-enhanced (quality focus)
-**API design** from Qwen3-TTS_server (clean REST)
-**Best practices** from professional software engineering
### What We Avoided
- ❌ No 2,815-line monolithic files
- ❌ No global mutable state
- ❌ No synchronous blocking
- ❌ No code duplication
- ❌ No poor separation of concerns
## 📚 Documentation Created
1. **`backend/README.md`** - Complete API documentation
2. **`backend/IMPLEMENTATION_STATUS.md`** - Implementation status
3. **`backend/example_usage.py`** - Working example client
4. **`docs/BACKEND_IMPLEMENTATION.md`** - Implementation details
5. **`docs/COMPETITIVE_ANALYSIS.md`** - Comparison with references
## 🚀 Ready For
### ✅ Immediate Integration
The backend is ready for:
- Tauri desktop app integration
- Web app deployment
- OpenAPI client generation
- Production deployment
### 🔌 All Endpoints Working
```
Health:
GET /health
Profiles:
POST /profiles
GET /profiles
GET /profiles/{id}
PUT /profiles/{id}
DELETE /profiles/{id}
POST /profiles/{id}/samples
GET /profiles/{id}/samples
DELETE /profiles/samples/{id}
Generation:
POST /generate
History:
GET /history
GET /history/{id}
DELETE /history/{id}
GET /history/stats
Audio:
GET /audio/{id}
Transcription:
POST /transcribe
Models:
POST /models/load
POST /models/unload
```
## 🎬 Next Steps
### 1. Test the Backend
```bash
# Terminal 1: Start backend
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py
# Terminal 2: Test it
curl http://localhost:8000/health
python backend/example_usage.py
```
### 2. Generate OpenAPI Client
```bash
# Start backend first, then:
curl http://localhost:8000/openapi.json > app/openapi.json
cd app
npx openapi-typescript-codegen \
--input openapi.json \
--output src/lib/api \
--client fetch
```
### 3. Build Frontend
Now you can build the Tauri frontend that:
- Creates voice profiles
- Uploads audio samples
- Generates speech
- Views history
- Downloads audio
## 📊 Performance
- **First generation:** 6-10 seconds (creates prompt)
- **Cached generation:** 1-2 seconds (uses cache)
- **Model loading:** 3-5 seconds (one-time)
- **Voice prompt cache:** Persists across restarts
## 🎯 Key Benefits
1. **Maintainable** - Clean, modular, documented
2. **Type-safe** - Catch errors at development time
3. **Fast** - Caching makes repeat generations instant
4. **Complete** - All core features implemented
5. **Professional** - Production-ready patterns throughout
## 🔮 Future Enhancements (Optional)
These are planned but not blocking frontend work:
**Phase 2:**
- WebSocket streaming for progress
- Batch generation endpoint
- Audio effects (M3GAN)
- Voice design
**Phase 3:**
- Audio studio timeline
- Word-level timestamps
- Project management
**Phase 4:**
- Authentication
- Rate limiting
- Docker deployment
- CI/CD
## 📖 Reference Projects Analyzed
Based on analysis of:
- **voice** - Rust CLI with Python backend
- **Voice-Clone-Studio** - Feature-rich Gradio app
- **Qwen3-TTS_server** - Clean FastAPI wrapper
- **mimic** - Web app with best backend structure
- **qwen3-tts-enhanced** - Production-quality Gradio
## ✨ Summary
**Your backend is:**
- ✅ Fully implemented (20+ endpoints)
- ✅ Production-ready (error handling, health checks)
- ✅ Well-documented (5 documentation files)
- ✅ Type-safe (100% Pydantic)
- ✅ Performant (voice prompt caching)
- ✅ Maintainable (clean architecture)
**Status:** READY FOR FRONTEND INTEGRATION
**No blockers.** You can start building the Tauri app immediately!
---
## Questions?
See the documentation:
- `backend/README.md` - API reference
- `backend/example_usage.py` - Usage examples
- `docs/BACKEND_IMPLEMENTATION.md` - Implementation details
- `docs/COMPETITIVE_ANALYSIS.md` - vs. reference projects
Happy building! 🚀
-368
View File
@@ -1,368 +0,0 @@
# Backend Implementation Summary
Complete implementation of the voicebox backend based on analysis of reference projects.
## What's Been Built
### ✅ Core Modules (100% Complete)
#### 1. TTS Module (`tts.py`)
**Pattern Source:** mimic + Voice-Clone-Studio
**Features:**
- Lazy model loading with device detection (CPU/CUDA/MPS)
- Voice prompt creation with dual caching (memory + disk)
- Multi-reference combination for quality improvement
- Async generation with seed control
- Model size switching (1.7B/0.6B)
- Proper memory management and cleanup
**Key Improvements Over References:**
- Cleaner async/await patterns than mimic
- Better error handling than Voice-Clone-Studio
- Proper type hints throughout
- Modular design vs monolithic files
#### 2. Profiles Module (`profiles.py`)
**Pattern Source:** mimic + qwen3-tts-enhanced
**Features:**
- Full CRUD operations for voice profiles
- Multi-sample support per profile
- Audio validation before adding samples
- Automatic sample combination for generation
- File storage organization in `data/profiles/`
- Database persistence with timestamps
**Key Improvements:**
- Better separation of concerns than mimic
- Proper async implementation
- Validation integrated at module level
- Cleaner API than reference implementations
#### 3. History Module (`history.py`)
**Pattern Source:** mimic
**Features:**
- Generation history tracking with full metadata
- Search and filtering capabilities
- Pagination support
- Statistics endpoint
- Audio file cleanup on deletion
- Profile-based filtering
**Key Improvements:**
- Returns total count for pagination
- Statistics aggregation
- Better query patterns
- Proper cleanup of associated files
#### 4. Transcribe Module (`transcribe.py`)
**Pattern Source:** Voice-Clone-Studio + mimic
**Features:**
- Whisper model loading and transcription
- Language hint support
- Word-level timestamps (placeholder for full implementation)
- Model size selection
- VRAM management
**Differences:**
- Simplified vs Voice-Clone-Studio's complex setup
- Prepared for future timestamp integration
- Better device handling
#### 5. Database Module (`database.py`)
**Pattern Source:** mimic
**Features:**
- SQLite with SQLAlchemy ORM
- Proper foreign key relationships
- Automatic timestamp management
- UUID primary keys
- Clean session management
**Schema:**
- `profiles` - Voice profile metadata
- `profile_samples` - Multi-sample support
- `generations` - Complete generation history
- `projects` - Future audio studio projects
#### 6. Models Module (`models.py`)
**Pattern Source:** Qwen3-TTS_server + mimic
**Features:**
- Pydantic v2 models for validation
- Request/response models separated
- Proper field validation
- Type safety throughout
- `from_attributes` for ORM compatibility
#### 7. Utils Module
##### `audio.py`
**Pattern Source:** qwen3-tts-enhanced + Voice-Clone-Studio
- RMS normalization with peak limiting
- Audio loading with resampling
- Audio saving in consistent format
- Reference audio validation (duration, RMS, clipping)
##### `cache.py`
**Pattern Source:** Voice-Clone-Studio (their best pattern)
- MD5-based cache key generation
- Dual caching (memory + disk)
- Automatic cache invalidation
- Corrupted cache file handling
- Persistent across server restarts
##### `validation.py`
**Pattern Source:** Original design
- Text validation
- Language code validation
- File path validation
- Reusable validation patterns
### ✅ API Implementation (`main.py`)
**Pattern Source:** Qwen3-TTS_server + mimic
**Complete REST API:**
- 20+ endpoints covering all features
- Proper HTTP status codes
- File upload handling
- File serving for audio
- Health check with model status
- Model management endpoints
- Error handling with details
- CORS configuration
**Endpoints Organized:**
1. Health & Info (2)
2. Voice Profiles (8)
3. Generation (1)
4. History (4)
5. Audio Files (1)
6. Transcription (1)
7. Model Management (2)
## Architecture Comparison
### Reference Projects Analysis
| Aspect | voice | Voice-Clone-Studio | Qwen3-TTS_server | mimic | voicebox |
|--------|-------|-------------------|------------------|-------|----------|
| **Code Organization** | Good | Poor (2815 lines) | Excellent | Backend: Good | Excellent |
| **Type Safety** | Rust: Yes, Python: No | No | Partial | Partial | Full (Pydantic) |
| **Async/Await** | No (subprocess) | No | Limited | Full | Full |
| **Caching** | Voice prompts | Voice prompts + disk | None | None | Voice prompts + disk |
| **Multi-Sample** | No | No | No | Yes | Yes |
| **Database** | File-based | File-based | None | SQLite | SQLite |
| **API Design** | HTTP basic | Gradio only | REST clean | REST good | REST excellent |
| **Error Handling** | Good | Basic | Basic | Good | Excellent |
| **File Lines** | ~500 | 2815 | ~800 | ~4000 | ~1500 |
### What Makes voicebox Better
#### 1. **Clean Architecture**
- No monolithic files (largest file: ~300 lines in main.py)
- Proper module separation
- Each file has single responsibility
- Easy to test and maintain
#### 2. **Production-Ready Patterns**
- Full async/await (not bolted on)
- Proper error handling with context
- Type safety throughout
- Database transactions
- Resource cleanup
#### 3. **Best Patterns from Each Reference**
- Voice prompt caching → Voice-Clone-Studio
- Multi-sample profiles → qwen3-tts-enhanced + mimic
- Audio normalization → qwen3-tts-enhanced
- API structure → Qwen3-TTS_server
- Database design → mimic
- VRAM management → Voice-Clone-Studio
#### 4. **Avoiding Reference Mistakes**
- ❌ No 2000+ line files
- ❌ No global mutable state
- ❌ No code duplication
- ❌ No mixed concerns
- ❌ No poor error messages
## API Feature Matrix
| Feature | Implemented | Source Pattern |
|---------|-------------|----------------|
| Voice profile CRUD | ✅ | mimic |
| Multi-sample profiles | ✅ | qwen3-tts-enhanced + mimic |
| Voice prompt caching | ✅ | Voice-Clone-Studio |
| Generation with seed | ✅ | All |
| History tracking | ✅ | mimic |
| History search | ✅ | mimic |
| Transcription | ✅ | Voice-Clone-Studio |
| Audio validation | ✅ | qwen3-tts-enhanced |
| Model management | ✅ | Original |
| File serving | ✅ | mimic |
| Health checks | ✅ | Qwen3-TTS_server |
| Statistics | ✅ | Original |
| Batch generation | ⏳ | TODO |
| WebSocket streaming | ⏳ | TODO |
| Audio effects (M3GAN) | ⏳ | TODO |
| Voice design | ⏳ | TODO |
| Audio studio | ⏳ | TODO |
| Projects | ⏳ | TODO |
## File Structure
```
backend/
├── main.py # 300 lines - FastAPI app + all routes
├── models.py # 100 lines - Pydantic models
├── tts.py # 200 lines - TTS inference
├── transcribe.py # 150 lines - Whisper ASR
├── profiles.py # 250 lines - Profile management
├── history.py # 150 lines - History management
├── studio.py # 70 lines - Audio studio (skeleton)
├── database.py # 90 lines - SQLite ORM
├── requirements.txt # Dependencies
├── README.md # Complete API documentation
├── example_usage.py # Example client code
└── utils/
├── __init__.py
├── audio.py # 120 lines - Audio processing
├── cache.py # 90 lines - Voice prompt caching
└── validation.py # 65 lines - Input validation
Total: ~1,500 lines (clean, maintainable, type-safe)
```
Compare to references:
- voice: ~500 lines (but limited features)
- Voice-Clone-Studio: 2,815 lines in ONE file
- Qwen3-TTS_server: ~800 lines (but no history/profiles)
- mimic backend: ~1,200 lines (our closest match, but less clean)
## Testing Strategy
### Manual Testing
1. Start server: `python -m backend.main`
2. Run example: `python backend/example_usage.py`
3. Test with curl/Postman
### Unit Testing (TODO)
```
tests/
├── test_tts.py
├── test_profiles.py
├── test_history.py
├── test_transcribe.py
├── test_audio.py
└── test_cache.py
```
## Performance Characteristics
### Voice Prompt Caching
- **First generation:** ~5-10 seconds
- Load model: 3-5s
- Create prompt: 2-3s
- Generate: 1-2s
- **Subsequent generations:** ~1-2 seconds
- Model loaded: 0s
- Prompt cached: 0s
- Generate: 1-2s
### Multi-Sample Profiles
- Combining 2-3 samples: +1-2 seconds on first use
- Cached after first use
- Better quality than single sample
### Model Sizes
- **1.7B:** Best quality, ~3GB VRAM, slower on CPU
- **0.6B:** Good quality, ~1GB VRAM, faster on CPU
## Next Steps
### Phase 1: Testing & Polish
1. Add unit tests
2. Add integration tests
3. Error handling edge cases
4. Documentation improvements
### Phase 2: Advanced Features
1. Batch generation endpoint
2. WebSocket for progress
3. Audio effects (M3GAN, pitch, etc.)
4. Voice design (text-to-voice)
### Phase 3: Audio Studio
1. Word-level timestamps (full implementation)
2. Timeline mixing
3. Trim/fade operations
4. Project save/load
5. Export options
### Phase 4: Production Features
1. Authentication & authorization
2. Rate limiting
3. Usage tracking
4. Model caching strategies
5. Distributed generation (multiple GPUs)
## Deployment
### Development
```bash
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py
```
### Production
```bash
# Using uvicorn directly
uvicorn backend.main:app --host 0.0.0.0 --port 8000 --workers 4
# Or using gunicorn
gunicorn backend.main:app -w 4 -k uvicorn.workers.UvicornWorker
```
### Docker (TODO)
```dockerfile
FROM python:3.11
# ... setup
CMD ["uvicorn", "backend.main:app", "--host", "0.0.0.0"]
```
## Conclusion
The voicebox backend is **production-ready** for:
- ✅ Voice profile management
- ✅ Multi-sample voice cloning
- ✅ Generation history
- ✅ Transcription
- ✅ Basic audio processing
It successfully combines:
- **Best architecture** from mimic
- **Best caching** from Voice-Clone-Studio
- **Best audio processing** from qwen3-tts-enhanced
- **Best API design** from Qwen3-TTS_server
- **Best practices** from professional software engineering
While avoiding:
- ❌ Monolithic files
- ❌ Global state
- ❌ Poor separation of concerns
- ❌ Code duplication
- ❌ Weak typing
The result is a clean, maintainable, production-quality backend that's ready for the Tauri frontend integration.
-268
View File
@@ -1,268 +0,0 @@
# Biome Setup Complete
Biome v2.3.12 is now configured for voicebox.
## What Was Configured
### ✅ Installed
- `@biomejs/[email protected]` (exact version pinned)
- Removed ESLint and all related dependencies
### ✅ Configuration Files Created
**`biome.json`** - Main configuration:
- Formatter: 2-space indents, 100 char line width
- Linter: Recommended rules + React best practices
- JavaScript: Single quotes, double quotes for JSX
- Tailwind CSS: `@tailwind` directives allowed
**`.vscode/settings.json`** - IDE integration:
- Biome as default formatter
- Format on save enabled
- Auto-import organization
- Prettier and ESLint disabled
**`.vscode/extensions.json`** - Recommended extensions:
- Biome (biomejs.biome)
- Tailwind CSS IntelliSense
- Rust Analyzer
- Tauri Extension
**`.biomeignore`** - Ignored files:
- `node_modules`, `dist`, `target`
- Generated API client
- Config files
- Lock files
### ✅ Package Scripts
Run from root:
```bash
bun run lint # Check linting issues
bun run lint:fix # Fix linting issues
bun run format # Format all files
bun run format:check # Check formatting
bun run check # Check everything (lint + format)
bun run check:fix # Fix everything
bun run ci # Strict check for CI/CD
```
Run from `app/`:
```bash
bun run lint # Lint app/src
bun run lint:fix # Fix lint issues
bun run format # Format app/src
bun run check # Check app/src
```
## Current Status
✅ **26 files checked**
**1 warning** (accessibility - safe to ignore for now)
✅ **0 errors**
The single warning is:
```
app/src/App.tsx:14:11 - Provide explicit type prop for button
```
This is a good accessibility practice but not blocking. Add `type="button"` when you build real components.
## Biome vs ESLint + Prettier
| Feature | Biome | ESLint + Prettier |
|---------|-------|------------------|
| Speed | ~15ms for 26 files | ~500ms+ |
| Single tool | ✅ | ❌ (2 tools) |
| TypeScript support | ✅ Native | ⚠️ Plugins needed |
| JSON/CSS formatting | ✅ | ⚠️ Limited |
| Auto-fix | ✅ | ⚠️ Partial |
| Import sorting | ✅ Built-in | ❌ Needs plugin |
## Configuration Highlights
### Linting Rules
**Enabled (errors):**
- `noUnusedImports` - Remove unused imports
- `noDoubleEquals` - Use `===` instead of `==`
- `useHookAtTopLevel` - React hooks at component top level
- `useExhaustiveDependencies` - Complete React hook deps
**Enabled (warnings):**
- `noUnusedVariables` - Warn on unused vars (not error)
- `noExplicitAny` - Discourage `any` type
- `useButtonType` - Accessibility for buttons
**Disabled:**
- `noNonNullAssertion` - Allow `!` in React (safe with `getElementById`)
- `useFilenamingConvention` - Allow flexible naming
- `noUnknownAtRules` - Allow Tailwind CSS directives
### Formatting Style
```typescript
// Single quotes for JS/TS
import { foo } from 'bar';
// Double quotes for JSX
<Component prop="value" />
// Always semicolons
const x = 5;
// Always arrow parens
const fn = (x) => x + 1;
// Trailing commas
const obj = {
a: 1,
b: 2,
};
```
## VS Code Integration
1. **Install extension:**
- Search "Biome" in VS Code extensions
- Install "Biome" by Biomejs
2. **Automatic:**
- Format on save ✅
- Auto-import organization ✅
- Inline errors/warnings ✅
- Quick fixes ✅
3. **Manual formatting:**
- macOS: `⇧⌥F`
- Windows/Linux: `Shift+Alt+F`
## CI/CD Integration
Add to GitHub Actions:
```yaml
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Check code quality
run: bun run ci
```
The `ci` command is strict and fails if any fixes are needed.
## Migration Notes
### Removed
- ❌ `eslint`
- ❌ `@typescript-eslint/eslint-plugin`
- ❌ `@typescript-eslint/parser`
- ❌ `eslint-plugin-react-hooks`
- ❌ `eslint-plugin-react-refresh`
- ❌ `.eslintrc.cjs`
### Why Biome?
From your CLAUDE.md:
> "You are a senior software engineer specializing in Rust and TypeScript. You pride yourself on clean production ready code."
Biome is:
- **Written in Rust** - Aligns with your stack (Tauri is Rust)
- **Fast** - 20-30x faster than ESLint
- **Simple** - One tool instead of two (ESLint + Prettier)
- **Production-ready** - Used by Meta, Vercel, and other large teams
- **Type-aware** - Understands TypeScript natively
## Common Commands
```bash
# Format everything
bun run format
# Fix all auto-fixable issues
bun run check:fix
# Check before commit (no changes)
bun run ci
# Format specific file
bunx biome format --write app/src/App.tsx
# Check specific directory
bunx biome check app/src/components
```
## Advanced Configuration
### Add custom rules
Edit `biome.json`:
```json
{
"linter": {
"rules": {
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "error",
"options": {
"maxAllowedComplexity": 15
}
}
}
}
}
}
```
### Per-file configuration
Use `overrides` in `biome.json`:
```json
{
"overrides": [
{
"includes": ["app/src/lib/api/**"],
"linter": {
"enabled": false
}
}
]
}
```
## Troubleshooting
### Biome not formatting in VS Code
1. Open Command Palette (`Cmd+Shift+P`)
2. Search "Format Document With..."
3. Select "Biome"
4. Check if Biome extension is installed
### Conflicts with Prettier
Make sure Prettier is disabled in VS Code settings (already configured in `.vscode/settings.json`).
### Performance issues
Biome is extremely fast, but if you experience issues:
```bash
# Clear Biome cache
rm -rf .biome-cache
# Reinstall
bun remove @biomejs/biome
bun add -D -E @biomejs/biome
```
## Next Steps
1. ✅ Biome is ready to use
2. ✅ Run `bun run format` to format existing code
3. ✅ Install Biome VS Code extension
4. 🚀 Start building frontend components
All future code will be automatically formatted and linted on save!
-377
View File
@@ -1,377 +0,0 @@
# Competitive Analysis: voicebox vs Reference Implementations
Detailed comparison showing how voicebox improves upon each reference project.
## Executive Summary
voicebox combines the **best patterns** from 5 reference implementations while avoiding their **architectural mistakes**. The result is a production-quality system that's maintainable, type-safe, and feature-rich.
---
## 1. vs. voice (Rust CLI)
### What voice Does Well
- ✅ Clean Rust/Python separation
- ✅ M3GAN voice effect
- ✅ Voice profile abstraction
- ✅ Good error handling in Rust
### What voicebox Does Better
| Aspect | voice | voicebox |
|--------|-------|----------|
| **Concurrency** | Spawns subprocess per request | Async with persistent model |
| **Caching** | Voice prompts only | Voice prompts + disk |
| **History** | None | Full database with search |
| **API** | Basic HTTP | Full REST with 20+ endpoints |
| **Multi-sample** | No | Yes |
| **Type safety** | Python: No | Full Pydantic |
| **Database** | File-based | SQLite with migrations |
### Architecture Comparison
```
voice:
Rust HTTP → spawn Python → JSON IPC → generate → return
voicebox:
FastAPI → async TTS → cached prompt → generate → save to DB
```
**Winner:** voicebox (persistent models, caching, database)
---
## 2. vs. Voice-Clone-Studio (Gradio)
### What Voice-Clone-Studio Does Well
- ✅ Brilliant voice prompt caching (memory + disk)
- ✅ Dual engine support (Qwen + VibeVoice)
- ✅ Feature-rich (voice design, presets, conversations)
- ✅ VRAM efficiency (smart loading/unloading)
- ✅ Metadata tracking
### What voicebox Does Better
| Aspect | Voice-Clone-Studio | voicebox |
|--------|-------------------|----------|
| **Code organization** | 2,815 lines in ONE file | ~1,500 lines across 12 files |
| **State management** | Global mutable state | Proper dependency injection |
| **Type safety** | None | Full Pydantic + type hints |
| **Testing** | Impossible | Easy (modular) |
| **API** | Gradio only | REST + future WebSocket |
| **Separation of concerns** | All mixed | Clean modules |
| **Error handling** | Generic messages | Contextual errors |
| **Code duplication** | 5 identical model loaders | Single abstraction |
### Code Quality Comparison
```python
# Voice-Clone-Studio
def generate_voice_clone(...): # Line 450
global _tts_model, _whisper_model
if _whisper_model:
del _whisper_model
_whisper_model = None
# ... 200 more lines of mixed logic
# voicebox
async def generate(self, text: str, voice_prompt: dict, ...) -> Tuple[np.ndarray, int]:
"""Generate audio from text using voice prompt."""
self.load_model()
# ... clean, focused logic
```
**Winner:** voicebox (maintainable architecture)
---
## 3. vs. Qwen3-TTS_server (FastAPI)
### What Qwen3-TTS_server Does Well
- ✅ Clean API design
- ✅ Proper separation (routes, models, utils)
- ✅ Singleton model manager
- ✅ Health endpoint
- ✅ Docker deployment
- ✅ Base64 audio input
### What voicebox Does Better
| Aspect | Qwen3-TTS_server | voicebox |
|--------|-----------------|----------|
| **Authentication** | None | TODO (planned) |
| **Rate limiting** | None | TODO (planned) |
| **Concurrency** | Sequential | Async throughout |
| **Caching** | None | Voice prompts cached |
| **Streaming** | No | TODO (WebSocket planned) |
| **Storage** | Temporary | Persistent database |
| **History** | None | Full tracking + search |
| **Profiles** | None | Full CRUD + samples |
| **Error handling** | Basic | Detailed + contextual |
| **Features** | 3 endpoints | 20+ endpoints |
### Feature Matrix
| Feature | Qwen3-TTS_server | voicebox |
|---------|-----------------|----------|
| Generate | ✅ | ✅ |
| Clone | ✅ | ✅ |
| Health | ✅ | ✅ |
| Profiles | ❌ | ✅ |
| Multi-sample | ❌ | ✅ |
| History | ❌ | ✅ |
| Search | ❌ | ✅ |
| Transcription | ❌ | ✅ |
| File serving | ❌ | ✅ |
| Statistics | ❌ | ✅ |
**Winner:** voicebox (far more features)
---
## 4. vs. mimic (Web App)
### What mimic Does Well
- ✅ **Best backend structure** of all references
- ✅ Async/await throughout
- ✅ Database-backed persistence
- ✅ Audio studio with timeline
- ✅ Word-level timestamps
- ✅ Project system
- ✅ Full-text search
### What voicebox Does Better
| Aspect | mimic | voicebox |
|--------|-------|----------|
| **Type safety** | Partial | Full Pydantic |
| **Caching** | None | Voice prompts |
| **Multi-sample** | Basic | Advanced (combination) |
| **Audio validation** | Limited | Comprehensive |
| **API docs** | Basic | Auto-generated OpenAPI |
| **Model management** | Manual | Lazy + auto-cleanup |
| **Error messages** | Generic | Detailed + actionable |
| **Code organization** | Good | Excellent |
### Backend Comparison
```
mimic backend:
~1,200 lines, async, modular, but:
- No caching
- Basic multi-sample
- No audio validation
- Manual model management
voicebox backend:
~1,500 lines, async, modular, plus:
- Voice prompt caching
- Advanced multi-sample with combination
- Comprehensive validation
- Automatic lazy loading
```
### Where mimic is Still Ahead
- ⚠️ **Audio studio** - Timeline editing, mixing
- ⚠️ **Word timestamps** - Full implementation
- ⚠️ **Projects** - Save/load sessions
**Planned for voicebox Phase 3**
**Winner:** voicebox (backend), but mimic has features we'll add later
---
## 5. vs. qwen3-tts-enhanced (Gradio)
### What qwen3-tts-enhanced Does Well
- ✅ Multi-reference cloning
- ✅ Batch variations
- ✅ Smart audio normalization
- ✅ Cross-platform support
- ✅ Backward compatibility
- ✅ Audio validation
- ✅ Quality presets
- ✅ Clean code (despite being monolithic)
- ✅ Good error messages
### What voicebox Does Better
| Aspect | qwen3-tts-enhanced | voicebox |
|--------|-------------------|----------|
| **Architecture** | 1,892 lines in one file | 12 modular files |
| **Database** | File-based | SQLite |
| **History** | None | Full tracking |
| **API** | Gradio only | REST API |
| **Concurrency** | One at a time | Async support |
| **Profiles** | File-based | Database CRUD |
### What We Adopted
- ✅ Multi-reference combination
- ✅ Audio validation patterns
- ✅ RMS normalization
- ✅ Cross-platform audio handling
- ✅ Good error messages
**Winner:** voicebox (better architecture, adopted best features)
---
## Composite Feature Matrix
| Feature | voice | Voice-Clone-Studio | Qwen3-TTS_server | mimic | qwen3-tts-enhanced | **voicebox** |
|---------|-------|-------------------|------------------|-------|-------------------|--------------|
| **Architecture** | | | | | | |
| Modular code | ⚠️ | ❌ | ✅ | ✅ | ⚠️ | ✅ |
| Type safety | ⚠️ | ❌ | ⚠️ | ⚠️ | ❌ | ✅ |
| Async/await | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ |
| Database | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| REST API | ⚠️ | ❌ | ✅ | ✅ | ❌ | ✅ |
| **Features** | | | | | | |
| Voice cloning | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Multi-sample | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
| Voice prompt cache | ⚠️ | ✅ | ❌ | ❌ | ⚠️ | ✅ |
| History tracking | ❌ | ⚠️ | ❌ | ✅ | ❌ | ✅ |
| Search | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| Transcription | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ |
| Audio validation | ❌ | ❌ | ❌ | ⚠️ | ✅ | ✅ |
| Audio studio | ❌ | ❌ | ❌ | ✅ | ❌ | ⏳ |
| Voice design | ❌ | ✅ | ❌ | ❌ | ❌ | ⏳ |
| M3GAN effect | ✅ | ❌ | ❌ | ❌ | ❌ | ⏳ |
| **Quality** | | | | | | |
| Multi-reference | ❌ | ❌ | ❌ | ⚠️ | ✅ | ✅ |
| Normalization | ❌ | ⚠️ | ❌ | ⚠️ | ✅ | ✅ |
| Quality presets | ❌ | ❌ | ❌ | ❌ | ✅ | ⏳ |
| **Production** | | | | | | |
| Error handling | ✅ | ⚠️ | ⚠️ | ✅ | ✅ | ✅ |
| Health checks | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
| Model management | ⚠️ | ✅ | ⚠️ | ⚠️ | ⚠️ | ✅ |
| Docker ready | ❌ | ❌ | ✅ | ❌ | ❌ | ⏳ |
Legend:
- ✅ Excellent/Complete
- ⚠️ Partial/Basic
- ❌ Missing/Poor
- ⏳ Planned
---
## Code Quality Metrics
### Lines of Code
| Project | Total Lines | Largest File | Files |
|---------|------------|--------------|-------|
| voice | ~500 | main.rs (200) | 5 |
| Voice-Clone-Studio | 2,815 | voice_clone_studio.py (2,815) | 1 |
| Qwen3-TTS_server | ~800 | server.py (400) | 4 |
| mimic backend | ~1,200 | app.js (2,794) | 7 |
| qwen3-tts-enhanced | 1,892 | app.py (1,892) | 1 |
| **voicebox** | **~1,500** | **main.py (300)** | **12** |
### Maintainability Score
| Project | Organization | Type Safety | Modularity | Testing | Total |
|---------|-------------|-------------|------------|---------|-------|
| voice | 7/10 | 5/10 | 7/10 | 0/10 | **19/40** |
| Voice-Clone-Studio | 2/10 | 0/10 | 1/10 | 0/10 | **3/40** |
| Qwen3-TTS_server | 9/10 | 5/10 | 9/10 | 0/10 | **23/40** |
| mimic | 8/10 | 5/10 | 8/10 | 0/10 | **21/40** |
| qwen3-tts-enhanced | 6/10 | 3/10 | 3/10 | 0/10 | **12/40** |
| **voicebox** | **10/10** | **10/10** | **10/10** | **3/10** | **33/40** |
---
## Performance Comparison
### Voice Prompt Generation
| Project | First Gen | Cached Gen | Cache Type |
|---------|-----------|------------|------------|
| voice | 8-12s | 8-12s | None |
| Voice-Clone-Studio | 6-10s | 1-2s | Memory + Disk |
| Qwen3-TTS_server | 8-12s | 8-12s | None |
| mimic | 8-12s | 8-12s | None |
| qwen3-tts-enhanced | 6-10s | 6-10s | Basic |
| **voicebox** | **6-10s** | **1-2s** | **Memory + Disk** |
### Multi-Sample Combination
| Project | Supports | Method | Quality |
|---------|----------|--------|---------|
| voice | ❌ | - | - |
| Voice-Clone-Studio | ❌ | - | - |
| Qwen3-TTS_server | ❌ | - | - |
| mimic | ✅ | Simple concat | Good |
| qwen3-tts-enhanced | ✅ | Normalized concat | Excellent |
| **voicebox** | ✅ | **Normalized concat** | **Excellent** |
---
## What voicebox Achieves
### Combines Best of All References
1. **Architecture** from mimic + Qwen3-TTS_server
2. **Caching** from Voice-Clone-Studio
3. **Audio processing** from qwen3-tts-enhanced
4. **Effects** from voice (planned)
5. **Features** from all projects
### Avoids All Major Pitfalls
1. ❌ No monolithic files (Voice-Clone-Studio, qwen3-tts-enhanced)
2. ❌ No global state (Voice-Clone-Studio, voice)
3. ❌ No synchronous blocking (voice, Voice-Clone-Studio)
4. ❌ No missing features (Qwen3-TTS_server)
5. ❌ No poor separation (Voice-Clone-Studio)
### Production-Ready From Day One
- ✅ Type-safe with Pydantic
- ✅ Async/await throughout
- ✅ Proper error handling
- ✅ Database persistence
- ✅ Clean architecture
- ✅ Easy to test
- ✅ Auto-generated API docs
- ✅ Health monitoring
---
## Future Roadmap
### Phase 1: Current State ✅
- [x] Core TTS with caching
- [x] Profile management
- [x] Multi-sample support
- [x] History tracking
- [x] Transcription
- [x] REST API
### Phase 2: Next Quarter
- [ ] WebSocket streaming
- [ ] Batch generation
- [ ] Audio effects (M3GAN)
- [ ] Voice design
- [ ] Unit tests (80% coverage)
### Phase 3: Following Quarter
- [ ] Audio studio (from mimic)
- [ ] Word-level timestamps
- [ ] Project management
- [ ] Export options
### Phase 4: Production
- [ ] Authentication
- [ ] Rate limiting
- [ ] Docker deployment
- [ ] CI/CD pipeline
- [ ] Monitoring & logging
---
## Conclusion
voicebox backend is:
1. **Most maintainable** - Clean architecture, modular, type-safe
2. **Most feature-rich** - Combines features from all references
3. **Best performance** - Caching + async + proper pooling
4. **Production-ready** - Error handling, health checks, monitoring
5. **Future-proof** - Easy to extend, test, deploy
It's the **only implementation** that combines:
- ✅ Clean code (Qwen3-TTS_server)
- ✅ Advanced caching (Voice-Clone-Studio)
- ✅ Quality audio (qwen3-tts-enhanced)
- ✅ Full features (mimic)
- ✅ Type safety (none had this)
- ✅ Production patterns (our innovation)
**Result:** A professional-grade system ready for the Tauri frontend and real-world deployment.
File diff suppressed because it is too large Load Diff
-150
View File
@@ -1,150 +0,0 @@
# Icon Update Workflow for voicebox
## Prerequisites
- Xcode Command Line Tools installed (`xcode-select --install`)
- Your icon designed in Icon Composer and saved as `voicebox.icon` in the project root
## Directory Structure
```
voicebox/
├── voicebox.icon/ # macOS 26 Liquid Glass icon bundle
│ ├── icon.json
│ └── Assets/
│ └── Voicebox.png # Your source image
├── tauri/
│ ├── assets/
│ │ └── voicebox_exports/ # Your 1024x1024 exports
│ └── src-tauri/
│ ├── gen/ # Auto-generated at build time
│ │ ├── Assets.car # Liquid Glass assets
│ │ ├── voicebox.icns # Generated fallback icon
│ │ └── partial.plist
│ └── icons/ # Tauri fallback icons (all platforms)
│ ├── icon.icns
│ ├── icon.ico
│ ├── 32x32.png
│ ├── 128x128.png
│ └── ...
```
## Step 1: Update the Liquid Glass Icon
Edit `voicebox.icon/` in Icon Composer (or manually update `icon.json` and `Assets/`).
The build script (`build.rs`) automatically compiles this during `cargo build`.
## Step 2: Regenerate Fallback Icons
After updating the `.icon` bundle, regenerate the fallback icons:
```bash
cd tauri/src-tauri
# Trigger rebuild to generate new icns
cargo build
# Copy the generated icns to icons folder
cp gen/voicebox.icns icons/icon.icns
# Generate PNGs from the icns
sips -s format png -z 32 32 gen/voicebox.icns --out icons/32x32.png
sips -s format png -z 64 64 gen/voicebox.icns --out icons/64x64.png
sips -s format png -z 128 128 gen/voicebox.icns --out icons/128x128.png
sips -s format png -z 256 256 gen/voicebox.icns --out icons/128x128@2x.png
sips -s format png -z 512 512 gen/voicebox.icns --out icons/icon.png
# Windows Square logos
for size in 30 44 71 89 107 142 150 284 310; do
sips -s format png -z $size $size gen/voicebox.icns --out "icons/Square${size}x${size}Logo.png"
done
```
## Step 3: Rebuild the App
```bash
cd tauri && bun run tauri build
```
## Step 4: Clear Icon Cache (if icons don't update)
```bash
sudo rm -rf /Library/Caches/com.apple.iconservices.store
sudo killall Finder
sudo killall Dock
```
---
## How It Works
| File | Purpose |
|------|---------|
| `voicebox.icon/` | Source for macOS 26 Liquid Glass icon |
| `build.rs` | Compiles `.icon``Assets.car` + `voicebox.icns` at build time |
| `gen/Assets.car` | Liquid Glass assets (macOS 26+) |
| `gen/voicebox.icns` | Auto-generated fallback icon |
| `icons/icon.icns` | Tauri's fallback for older macOS |
| `icons/*.png` | Tauri's fallback for other platforms |
| `Info.plist` | Points to `voicebox` as icon name |
| `tauri.conf.json` | Bundles `gen/*` to Resources root |
## Key Config Files
### `build.rs` — Compiles the icon
```rust
xcrun actool --app-icon voicebox ... voicebox.icon
```
### `tauri.conf.json` — Bundles generated assets to Resources root
```json
"resources": {
"gen/Assets.car": "./",
"gen/voicebox.icns": "./",
"gen/partial.plist": "./"
}
```
### `Info.plist` — Tells macOS which icon to use
```xml
<key>CFBundleIconFile</key>
<string>voicebox</string>
<key>CFBundleIconName</key>
<string>voicebox</string>
```
## Quick Reference Script
Save this as `scripts/update-icons.sh`:
```bash
#!/bin/bash
set -e
cd "$(dirname "$0")/../tauri/src-tauri"
echo "Building to generate new icons..."
cargo build
echo "Copying icns to icons folder..."
cp gen/voicebox.icns icons/icon.icns
echo "Generating PNG icons..."
sips -s format png -z 32 32 gen/voicebox.icns --out icons/32x32.png
sips -s format png -z 64 64 gen/voicebox.icns --out icons/64x64.png
sips -s format png -z 128 128 gen/voicebox.icns --out icons/128x128.png
sips -s format png -z 256 256 gen/voicebox.icns --out icons/128x128@2x.png
sips -s format png -z 512 512 gen/voicebox.icns --out icons/icon.png
echo "Generating Windows Square logos..."
for size in 30 44 71 89 107 142 150 284 310; do
sips -s format png -z $size $size gen/voicebox.icns --out "icons/Square${size}x${size}Logo.png"
done
echo "Done! Icons updated."
echo "Run 'bun run tauri build' to rebuild the app."
```
Make it executable: `chmod +x scripts/update-icons.sh`
-287
View File
@@ -1,287 +0,0 @@
# Backend Implementation Status
## ✅ COMPLETE - Ready for Frontend Integration
### What's Been Built
The voicebox backend is **fully implemented** and production-ready with the following features:
#### Core Modules (100% Complete)
1. **TTS Module** (`tts.py`) - 200 lines
- Lazy model loading with device detection
- Voice prompt creation and caching
- Multi-reference combination
- Async generation with seed control
- Model size switching (1.7B/0.6B)
- Memory management
2. **Profiles Module** (`profiles.py`) - 250 lines
- Full CRUD operations
- Multi-sample support
- Audio validation
- Automatic sample combination
- File storage management
3. **History Module** (`history.py`) - 150 lines
- Generation tracking
- Search and filtering
- Pagination
- Statistics
- File cleanup
4. **Transcribe Module** (`transcribe.py`) - 150 lines
- Whisper transcription
- Language hints
- Model size selection
- VRAM management
5. **Database Module** (`database.py`) - 90 lines
- SQLite with SQLAlchemy
- Clean schema design
- Foreign keys
- UUID primary keys
6. **Utils Module** - 300 lines total
- Audio processing (normalization, validation)
- Voice prompt caching (memory + disk)
- Input validation
7. **API Module** (`main.py`) - 300 lines
- 20+ REST endpoints
- File upload handling
- File serving
- Health checks
- Model management
### API Endpoints
#### Implemented ✅
- `GET /` - Root
- `GET /health` - Health check
- `POST /profiles` - Create profile
- `GET /profiles` - List profiles
- `GET /profiles/{id}` - Get profile
- `PUT /profiles/{id}` - Update profile
- `DELETE /profiles/{id}` - Delete profile
- `POST /profiles/{id}/samples` - Add sample
- `GET /profiles/{id}/samples` - List samples
- `DELETE /profiles/samples/{id}` - Delete sample
- `POST /generate` - Generate speech
- `GET /history` - List history
- `GET /history/{id}` - Get generation
- `DELETE /history/{id}` - Delete generation
- `GET /history/stats` - Statistics
- `GET /audio/{id}` - Download audio
- `POST /transcribe` - Transcribe audio
- `POST /models/load` - Load model
- `POST /models/unload` - Unload model
#### Total: 20 endpoints, all tested and working
### Testing
```bash
# 1. Start server
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python main.py
# 2. Run example
python example_usage.py
# 3. Test with curl
curl http://localhost:8000/health
```
### Documentation
- ✅ `README.md` - Complete API documentation
- ✅ `IMPLEMENTATION_STATUS.md` - This file
- ✅ `example_usage.py` - Example client code
- ✅ `../docs/BACKEND_IMPLEMENTATION.md` - Implementation details
- ✅ `../docs/COMPETITIVE_ANALYSIS.md` - Comparison with references
### Code Quality
- **Total lines:** ~1,500 (clean, maintainable)
- **Largest file:** 300 lines (main.py)
- **Type safety:** 100% (Pydantic + type hints)
- **Async/await:** 100%
- **Modularity:** Excellent (12 files)
- **Error handling:** Comprehensive
- **Documentation:** Complete
### Next Steps for Integration
1. **Frontend can now:**
- Create voice profiles
- Upload audio samples
- Generate speech
- View history
- Download audio files
- Transcribe audio
2. **Frontend needs to:**
- Call REST API endpoints
- Handle file uploads
- Display UI for profiles/history
- Play audio files
3. **Backend ready for:**
- Tauri integration
- Web deployment
- Docker containerization
- Production deployment
### Future Enhancements (Not Blocking)
#### Phase 2 (Next)
- WebSocket streaming
- Batch generation
- Audio effects
- Voice design
- Unit tests
#### Phase 3 (Later)
- Audio studio
- Word-level timestamps
- Projects
- Export options
#### Phase 4 (Production)
- Authentication
- Rate limiting
- Docker
- CI/CD
### Dependencies
All dependencies in `requirements.txt`:
```
fastapi>=0.109.0
uvicorn[standard]>=0.27.0
pydantic>=2.5.0
sqlalchemy>=2.0.0
torch>=2.1.0
transformers>=4.36.0
librosa>=0.10.0
soundfile>=0.12.0
python-multipart>=0.0.6
```
### Performance
- **First generation:** 6-10 seconds (creates prompt + generates)
- **Cached generation:** 1-2 seconds (uses cached prompt)
- **Model loading:** 3-5 seconds (one-time)
- **Transcription:** 2-5 seconds (depends on audio length)
### Architecture Benefits
1. **Modular** - Easy to extend
2. **Type-safe** - Catch errors early
3. **Async** - Non-blocking operations
4. **Cached** - Fast repeated generations
5. **Persistent** - Database-backed
6. **Clean** - Maintainable code
7. **Documented** - Complete API docs
### Comparison to References
**voicebox is:**
- ✅ More maintainable than Voice-Clone-Studio (no 2815-line files)
- ✅ More feature-rich than Qwen3-TTS_server (20 vs 3 endpoints)
- ✅ Better caching than mimic (voice prompts cached)
- ✅ Better typed than all references (100% Pydantic)
- ✅ Better organized than qwen3-tts-enhanced (12 files vs 1)
### Status: READY FOR FRONTEND ✅
The backend is **complete and production-ready** for:
- ✅ Tauri desktop app integration
- ✅ Web app deployment
- ✅ API client generation (OpenAPI)
- ✅ Real-world usage
**No blockers remaining.** Frontend can begin integration immediately.
---
## Quick Start for Frontend Developers
### 1. Start Backend
```bash
cd backend
python main.py
```
### 2. Test Connection
```bash
curl http://localhost:8000/health
```
### 3. Create Profile
```bash
curl -X POST http://localhost:8000/profiles \
-H "Content-Type: application/json" \
-d '{"name": "Test Voice", "language": "en"}'
```
### 4. Generate OpenAPI Client
```bash
# OpenAPI spec available at:
http://localhost:8000/openapi.json
# Use with openapi-typescript-codegen
npx openapi-typescript-codegen \
--input http://localhost:8000/openapi.json \
--output ./src/lib/api \
--client fetch
```
### 5. Build Your UI
```typescript
import { ProfilesService, GenerateService } from '@/lib/api';
// Create profile
const profile = await ProfilesService.createProfile({
name: 'My Voice',
language: 'en',
});
// Generate speech
const generation = await GenerateService.generateSpeech({
profile_id: profile.id,
text: 'Hello world',
language: 'en',
});
// Download audio
const audioUrl = `/audio/${generation.id}`;
```
---
## Summary
**Backend Status:** ✅ COMPLETE
**Lines of Code:** ~1,500 (clean, maintainable)
**Test Coverage:** Manual testing complete, unit tests TODO
**Documentation:** 100% complete
**Ready for:** Frontend integration, deployment, production
**Next Steps:** Build Tauri frontend, integrate API
---
**Questions?** See:
- `README.md` for API documentation
- `example_usage.py` for usage examples
- `../docs/BACKEND_IMPLEMENTATION.md` for implementation details
-754
View File
@@ -1,754 +0,0 @@
# Tauri App Plan
Plan for building voicebox as a Tauri 2.0 desktop app with shared frontend code for web deployment.
---
## Project Structure
```
voicebox/
├── app/ # Shared React frontend (used by both web & desktop)
│ ├── src/
│ │ ├── components/
│ │ │ ├── VoiceProfiles/
│ │ │ ├── Generation/
│ │ │ ├── AudioStudio/
│ │ │ ├── History/
│ │ │ └── ServerSettings/
│ │ ├── lib/
│ │ │ ├── api/ # Generated OpenAPI client
│ │ │ ├── hooks/ # React Query hooks
│ │ │ └── utils/
│ │ ├── types/
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── package.json
│ ├── tsconfig.json
│ ├── vite.config.ts
│ └── tailwind.config.ts
├── tauri/ # Tauri desktop app
│ ├── src/ # Thin wrapper, imports from ../app
│ │ └── main.tsx # Entry point that renders App from ../app
│ ├── src-tauri/ # Rust backend
│ │ ├── src/
│ │ │ └── main.rs
│ │ ├── icons/
│ │ ├── binaries/ # Bundled Python server
│ │ │ ├── voicebox-server-x86_64-apple-darwin
│ │ │ ├── voicebox-server-aarch64-apple-darwin
│ │ │ ├── voicebox-server-x86_64-unknown-linux-gnu
│ │ │ └── voicebox-server-x86_64-pc-windows-msvc.exe
│ │ ├── capabilities/
│ │ │ └── default.json
│ │ ├── Cargo.toml
│ │ ├── Cargo.lock
│ │ ├── tauri.conf.json
│ │ └── build.rs
│ ├── package.json
│ └── vite.config.ts # Points to ../app
├── web/ # Web deployment
│ ├── src/
│ │ └── main.tsx # Entry point that renders App from ../app
│ ├── package.json
│ └── vite.config.ts # Points to ../app
├── backend/ # Python FastAPI server
│ ├── main.py
│ ├── models.py
│ ├── tts.py
│ ├── transcribe.py
│ ├── profiles.py
│ ├── history.py
│ ├── studio.py
│ ├── database.py
│ ├── utils/
│ ├── requirements.txt
│ └── build_binary.py # PyInstaller build script
├── scripts/
│ ├── build-server.sh # Build Python server for all platforms
│ └── generate-api.sh # Generate OpenAPI client
├── package.json # Root workspace config (Bun workspaces)
└── bun.lockb # Bun lockfile
```
---
## Technology Stack
### Desktop App (Tauri 2.0)
- **Tauri 2.9.5+** - Latest stable version
- **Rust** - Tauri backend
- **React + TypeScript** - Frontend (shared with web)
- **Vite** - Build tool
- **Bun** - Fast package manager and JavaScript runtime
### Shared Frontend
- **React 18+** - UI framework
- **TypeScript** - Type safety
- **Vite** - Build tool and dev server
- **Bun** - Package manager (faster than npm/yarn/pnpm)
- **React Query** - Server state management
- **Zustand** - Client state management
- **Tailwind CSS** - Styling
- **WaveSurfer.js** - Audio visualization
### Backend Bundling
- **PyInstaller** - Bundle Python server as standalone binary
- **FastAPI** - Python web framework
- **Tauri Sidecar** - Execute bundled Python server
---
## Bundling Python Server with Tauri
### 1. Build Python Server as Standalone Binary
**Using PyInstaller:**
```python
# backend/build_binary.py
import PyInstaller.__main__
import sys
import os
def build_server():
PyInstaller.__main__.run([
'main.py',
'--onefile',
'--name', 'voicebox-server',
'--add-data', 'data:data', # Include data files
'--hidden-import', 'torch',
'--hidden-import', 'transformers',
'--hidden-import', 'fastapi',
'--collect-all', 'qwen-tts',
'--noconfirm',
])
if __name__ == '__main__':
build_server()
```
**Build script for all platforms:**
```bash
#!/bin/bash
# scripts/build-server.sh
# Determine platform
PLATFORM=$(rustc --print host-tuple)
# Build Python binary
cd backend
python build_binary.py
# Rename with platform triple
cd dist
mv voicebox-server ../src-tauri/binaries/voicebox-server-${PLATFORM}
echo "Built voicebox-server-${PLATFORM}"
```
**Platform-specific binaries needed:**
- macOS Intel: `voicebox-server-x86_64-apple-darwin`
- macOS ARM: `voicebox-server-aarch64-apple-darwin`
- Linux: `voicebox-server-x86_64-unknown-linux-gnu`
- Windows: `voicebox-server-x86_64-pc-windows-msvc.exe`
### 2. Configure Tauri to Bundle Binary
**tauri/src-tauri/tauri.conf.json:**
```json
{
"bundle": {
"identifier": "sh.voicebox.app",
"externalBin": [
"binaries/voicebox-server"
],
"resources": [
"binaries/*"
]
},
"build": {
"beforeBuildCommand": "bun run build",
"devPath": "http://localhost:5173",
"distDir": "../dist"
}
}
```
**Capabilities (src-tauri/capabilities/default.json):**
```json
{
"identifier": "default",
"description": "Default permissions",
"permissions": [
"core:default",
"shell:allow-execute",
"shell:allow-spawn",
"fs:default"
]
}
```
### 3. Launch Python Server from Tauri
**tauri/src-tauri/src/main.rs:**
```rust
use tauri::{command, Manager};
use tauri_plugin_shell::ShellExt;
use std::sync::Mutex;
struct ServerState {
child: Mutex<Option<tauri_plugin_shell::process::CommandChild>>,
}
#[command]
async fn start_server(app: tauri::AppHandle, state: tauri::State<'_, ServerState>) -> Result<String, String> {
let sidecar = app.shell()
.sidecar("voicebox-server")
.map_err(|e| format!("Failed to get sidecar: {}", e))?;
let (mut rx, child) = sidecar
.spawn()
.map_err(|e| format!("Failed to spawn: {}", e))?;
// Store child process
*state.child.lock().unwrap() = Some(child);
// Wait for server to be ready (listen for startup log)
tokio::spawn(async move {
while let Some(event) = rx.recv().await {
if let tauri_plugin_shell::process::CommandEvent::Stdout(line) = event {
if String::from_utf8_lossy(&line).contains("Uvicorn running") {
break;
}
}
}
});
Ok("Server started on http://localhost:8000".to_string())
}
#[command]
async fn stop_server(state: tauri::State<'_, ServerState>) -> Result<(), String> {
if let Some(child) = state.child.lock().unwrap().take() {
child.kill().map_err(|e| format!("Failed to kill: {}", e))?;
}
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.manage(ServerState {
child: Mutex::new(None),
})
.invoke_handler(tauri::generate_handler![start_server, stop_server])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```
### 4. Call from Frontend
**app/src/lib/hooks/useServer.ts:**
```typescript
import { invoke } from '@tauri-apps/api/core';
import { useState } from 'react';
export function useServer() {
const [serverUrl, setServerUrl] = useState<string>('http://localhost:8000');
const [isRunning, setIsRunning] = useState(false);
const startServer = async () => {
try {
const url = await invoke<string>('start_server');
setServerUrl(url);
setIsRunning(true);
return url;
} catch (error) {
console.error('Failed to start server:', error);
throw error;
}
};
const stopServer = async () => {
try {
await invoke('stop_server');
setIsRunning(false);
} catch (error) {
console.error('Failed to stop server:', error);
throw error;
}
};
return { serverUrl, isRunning, startServer, stopServer };
}
```
---
## Shared Frontend Approach
### App Package Structure
The `app/` directory contains all React code that's shared between desktop and web.
**app/vite.config.ts:**
```typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
build: {
lib: {
entry: path.resolve(__dirname, 'src/main.tsx'),
formats: ['es'],
},
rollupOptions: {
external: ['react', 'react-dom'],
},
},
});
```
### Tauri Wrapper
**tauri/src/main.tsx:**
```typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from '../app/src/App';
import '../app/src/index.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
```
**tauri/vite.config.ts:**
```typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, '../app/src'),
},
},
clearScreen: false,
server: {
port: 5173,
strictPort: true,
},
envPrefix: ['VITE_', 'TAURI_'],
build: {
target: 'es2021',
minify: !process.env.TAURI_DEBUG,
sourcemap: !!process.env.TAURI_DEBUG,
outDir: 'dist',
},
});
```
**tauri/package.json:**
```json
{
"name": "@voicebox/tauri",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "^2.0.0",
"@tauri-apps/plugin-shell": "^2.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
},
"devDependencies": {
"@tauri-apps/cli": "^2.0.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "^5.6.0",
"vite": "^5.4.0"
}
}
```
### Web Wrapper
**web/src/main.tsx:**
```typescript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from '../../app/src/App';
import '../../app/src/index.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
```
**web/vite.config.ts:**
```typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, '../app/src'),
},
},
build: {
outDir: 'dist',
},
});
```
---
## Development Workflow
### 1. Initial Setup
```bash
# Install Bun (if not installed)
curl -fsSL https://bun.sh/install | bash
# Create Tauri app with official CLI
cd voicebox
bunx create-tauri-app tauri
# Move app code to shared directory
mkdir app
# Move tauri/src/* to app/src/
# Create web directory
mkdir web
cd web
bunx create-vite . --template react-ts
# Setup Bun workspace in root package.json
cat > package.json << 'EOF'
{
"name": "voicebox",
"private": true,
"workspaces": ["app", "tauri", "web"]
}
EOF
# Install all dependencies
bun install
```
### 2. Development
**Terminal 1 - Backend (Python FastAPI):**
```bash
cd backend
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install -r requirements.txt
uvicorn main:app --reload --port 8000
```
**Terminal 2 - Frontend (Tauri dev mode):**
```bash
cd tauri
bun run tauri dev
```
This will:
1. Start Vite dev server on port 5173
2. Launch Tauri window pointing to localhost:5173
3. Hot reload on code changes
**For web development:**
```bash
cd web
bun run dev
```
### 3. Building for Production
**Build Python server:**
```bash
./scripts/build-server.sh
```
**Build Tauri app:**
```bash
cd tauri
bun run tauri build
```
This will:
1. Build React frontend with Vite
2. Bundle Python server binary
3. Create platform-specific installers:
- macOS: `.app`, `.dmg`
- Windows: `.exe`, `.msi`
- Linux: `.deb`, `.AppImage`
**Build web app:**
```bash
cd web
bun run build
```
---
## Platform-Specific Considerations
### macOS
- Need both Intel and ARM builds
- Sign and notarize for distribution outside App Store
- Request permissions for microphone access (audio recording)
**tauri.conf.json additions:**
```json
{
"bundle": {
"macOS": {
"minimumSystemVersion": "10.15",
"entitlements": "src-tauri/Entitlements.plist"
}
}
}
```
**Entitlements.plist:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.device.audio-input</key>
<true/>
</dict>
</plist>
```
### Windows
- Build with NSIS or WiX installer
- Consider code signing for SmartScreen
### Linux
- Provide multiple formats: .deb, .AppImage, .rpm
- Consider Flatpak for broader distribution
---
## OpenAPI Client Generation
**scripts/generate-api.sh:**
```bash
#!/bin/bash
# Start backend if not running
if ! curl -s http://localhost:8000/openapi.json > /dev/null; then
echo "Starting backend..."
cd backend
uvicorn main:app --port 8000 &
BACKEND_PID=$!
sleep 5
fi
# Download OpenAPI schema
curl http://localhost:8000/openapi.json > app/openapi.json
# Generate TypeScript client
cd app
bunx openapi-typescript-codegen \
--input openapi.json \
--output src/lib/api \
--client fetch
echo "API client generated in app/src/lib/api"
# Kill backend if we started it
if [ ! -z "$BACKEND_PID" ]; then
kill $BACKEND_PID
fi
```
**Add to package.json:**
```json
{
"scripts": {
"generate:api": "./scripts/generate-api.sh"
}
}
```
---
## Server Mode Architecture
### Local Mode (Default)
1. Tauri app starts
2. App invokes `start_server` command
3. Rust spawns bundled Python binary as sidecar
4. Frontend connects to `http://localhost:8000`
5. All features work locally
### Remote Mode (One-Click)
1. User clicks "Start Server" on GPU machine
2. Tauri invokes `start_server` with `--host 0.0.0.0` flag
3. Server displays connection URL (e.g., `http://192.168.1.100:8000`)
4. User enters URL in client app
5. Client connects to remote server
6. All API calls go to remote machine
**Rust command with args:**
```rust
#[command]
async fn start_server(
app: tauri::AppHandle,
state: tauri::State<'_, ServerState>,
remote: bool,
) -> Result<String, String> {
let mut sidecar = app.shell().sidecar("voicebox-server")
.map_err(|e| format!("Failed to get sidecar: {}", e))?;
if remote {
sidecar = sidecar.args(["--host", "0.0.0.0"]);
}
// ... rest of spawn logic
}
```
---
## CI/CD for Multi-Platform Builds
**GitHub Actions workflow:**
```yaml
name: Build
on:
push:
tags:
- 'v*'
jobs:
build:
strategy:
matrix:
platform: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
cd tauri
bun install
- name: Build Python server
run: |
cd backend
pip install -r requirements.txt
pip install pyinstaller
python build_binary.py
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectPath: tauri
tagName: v__VERSION__
releaseName: 'voicebox v__VERSION__'
```
---
## Key Decisions
### Why This Structure?
1. **Shared `app/` directory** - Single source of truth for UI code
2. **Thin wrappers** - `tauri/` and `web/` just configure build tools
3. **Sidecar pattern** - Bundle Python server without modifying Tauri core
4. **PyInstaller** - Creates standalone Python binary with all dependencies
5. **Platform-specific binaries** - Tauri automatically selects correct binary per platform
### Benefits
- ✅ No code duplication between web and desktop
- ✅ Python server bundled - users don't install Python
- ✅ Single command to build everything
- ✅ Type-safe API calls via OpenAPI generation
- ✅ Native performance with Tauri
- ✅ Web fallback for unsupported platforms
- ✅ Fast development with Bun (20-30x faster installs than npm)
### Tradeoffs
- ⚠️ Large bundle size (Python runtime + ML models + Tauri)
- ⚠️ Need to build Python binary for each platform
- ⚠️ First launch slow (model loading)
- ⚠️ Separate web build doesn't include server (requires separate backend deployment)
---
## Next Steps
1. Set up monorepo structure
2. Initialize Tauri app with `bunx create-tauri-app`
3. Create shared `app/` directory
4. Configure Vite to share code
5. Build Python server with PyInstaller
6. Configure Tauri sidecar
7. Test on macOS, Windows, Linux
8. Set up CI/CD for multi-platform builds
---
## Resources
- [Tauri 2.0 Documentation](https://v2.tauri.app/)
- [Tauri Sidecar Guide](https://v2.tauri.app/develop/sidecar/)
- [Bun Documentation](https://bun.sh/docs)
- [Bun Workspaces](https://bun.sh/docs/install/workspaces)
- [PyInstaller Documentation](https://pyinstaller.org/)
- [React Query Documentation](https://tanstack.com/query/latest)
- [OpenAPI TypeScript Codegen](https://github.com/ferdikoomen/openapi-typescript-codegen)
+280
View File
@@ -0,0 +1,280 @@
# Troubleshooting Guide
Common issues and solutions for Voicebox.
## Installation Issues
### macOS: "Voicebox cannot be opened because it is from an unidentified developer"
**Solution:**
1. Right-click the `.dmg` file
2. Select "Open"
3. Click "Open" in the security dialog
4. Alternatively, go to System Settings → Privacy & Security → Allow Voicebox
### Windows: "Windows protected your PC"
**Solution:**
1. Click "More info"
2. Click "Run anyway"
3. Windows Defender may flag new software; this is normal for unsigned apps
### Linux: AppImage won't run
**Solution:**
```bash
chmod +x voicebox-*.AppImage
./voicebox-*.AppImage
```
## Runtime Issues
### Server won't start
**Symptoms:** App opens but shows "Server not connected"
**Solutions:**
1. **Check Python installation**
```bash
python --version # Should be 3.11+
```
2. **Check server binary exists**
- Look in `tauri/src-tauri/binaries/` for your platform
- Binary should match your system architecture
3. **Check permissions**
```bash
# macOS/Linux
chmod +x tauri/src-tauri/binaries/voicebox-server-*
```
4. **Check logs**
- macOS: Open Console.app and search for "voicebox"
- Linux: Check `~/.local/share/voicebox/` for logs
- Windows: Check Event Viewer
### "Model download failed"
**Symptoms:** First generation fails with download error
**Solutions:**
1. **Check internet connection**
- Models download from HuggingFace Hub (~2-4GB)
- First download may take several minutes
2. **Check disk space**
- Models are cached in `~/.cache/huggingface/`
- Ensure at least 5GB free space
3. **Manual download** (if automatic fails)
```bash
pip install huggingface_hub
huggingface-cli download Qwen/Qwen3-TTS-12Hz-1.7B-Base
```
### "Out of memory" errors
**Symptoms:** Generation fails with CUDA/VRAM errors
**Solutions:**
1. **Use smaller model**
- Switch to 0.6B model instead of 1.7B
- Settings → Model Management → Load 0.6B
2. **Close other applications**
- Free up GPU memory
- Close browser tabs, other ML apps
3. **Use CPU mode**
- Slower but works without GPU
- Backend automatically falls back to CPU
### Audio playback issues
**Symptoms:** Generated audio won't play
**Solutions:**
1. **Check audio format**
- Audio is saved as WAV files
- Ensure your system supports WAV playback
2. **Try downloading audio**
- Right-click → Download
- Play in external player
3. **Check browser permissions** (web version)
- Allow audio autoplay in browser settings
### Slow generation
**Symptoms:** Generation takes >30 seconds
**Solutions:**
1. **Use GPU** (if available)
- Check Settings → Server Status
- Should show "GPU available: true"
2. **Enable caching**
- Voice prompts are cached automatically
- Second generation with same voice should be faster
3. **Use smaller model**
- 0.6B model is faster than 1.7B
- Quality difference is minimal for most voices
4. **Check system resources**
- Close other CPU/GPU intensive apps
- Ensure adequate RAM (8GB+ recommended)
## API Issues
### "Connection refused" when using API
**Solutions:**
1. **Check server is running**
```bash
curl http://localhost:8000/health
```
2. **Check remote mode**
- If connecting remotely, ensure server is started with `--host 0.0.0.0`
- Check firewall settings
3. **Check port availability**
- Default port is 8000
- Ensure no other service is using it
### CORS errors in browser
**Solutions:**
1. **Use desktop app** (recommended)
- Desktop app doesn't have CORS restrictions
2. **Configure CORS** (for web deployment)
- Update `backend/main.py` CORS settings
- Add your domain to allowed origins
## Update Issues
### "Update check failed"
**Solutions:**
1. **Check internet connection**
- Updates are fetched from GitHub releases
2. **Check GitHub access**
- Ensure `github.com` is accessible
- Check firewall/proxy settings
3. **Manual update**
- Download latest release from GitHub
- Install manually
### "Invalid signature" error
**Solutions:**
1. **Re-download installer**
- Signature may be corrupted
- Download fresh copy from GitHub
2. **Check release integrity**
- Verify `.sig` file matches installer
- Report issue if signature is invalid
## Data Issues
### Profiles disappeared
**Solutions:**
1. **Check data directory**
- macOS: `~/Library/Application Support/voicebox/`
- Windows: `%APPDATA%/voicebox/`
- Linux: `~/.local/share/voicebox/`
2. **Check database**
- Database: `data/voicebox.db`
- Ensure file exists and is readable
3. **Restore from backup**
- Profiles can be exported/imported
- Check for backup files
### "Database locked" error
**Solutions:**
1. **Close other instances**
- Ensure only one Voicebox instance is running
2. **Restart app**
- Close and reopen Voicebox
3. **Check file permissions**
- Ensure database file is writable
- Check directory permissions
## Development Issues
### Build fails
**Solutions:**
1. **Check Rust installation**
```bash
rustc --version
rustup update
```
2. **Check Tauri dependencies**
```bash
cd tauri
bun install
```
3. **Clean build**
```bash
cd tauri/src-tauri
cargo clean
cd ../..
bun run build
```
### API client generation fails
**Solutions:**
1. **Start backend server**
```bash
bun run dev:server
```
2. **Check OpenAPI endpoint**
```bash
curl http://localhost:8000/openapi.json
```
3. **Regenerate client**
```bash
bun run generate:api
```
## Still Having Issues?
1. **Check existing issues**
- Search GitHub issues for similar problems
- Check closed issues for solutions
2. **Create new issue**
- Include:
- OS and version
- Voicebox version
- Steps to reproduce
- Error messages/logs
- Screenshots (if applicable)
3. **Get help**
- Check documentation in `docs/`
- Review `backend/README.md` for API details
- See `CONTRIBUTING.md` for development help
---
For more help, open an issue on [GitHub](https://github.com/jamiepine/voicebox/issues).