Add F5-TTS as tts-1-f5 engine (additive, alongside tts-1-qwen)
This commit is contained in:
parent
bfc5260dfc
commit
2df34f85cc
6 changed files with 511 additions and 5 deletions
12
Makefile
12
Makefile
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
CONTAINER_NAME ?= uncloseai-speech-server-1
|
||||
|
||||
.PHONY: help deploy restart logs test clean stop start voices voices-qwen voices-piper voices-xtts voices-kokoro test-kokoro voices-silero test-silero voices-chatterbox test-chatterbox push-all hydrate load-test test-qwen venv venv-run local local-cpu
|
||||
.PHONY: help deploy restart logs test clean stop start voices voices-qwen voices-piper voices-xtts voices-kokoro test-kokoro voices-silero test-silero voices-chatterbox test-chatterbox push-all hydrate load-test test-qwen test-f5 venv venv-run local local-cpu
|
||||
|
||||
help:
|
||||
@echo "Raccoon TTS Mission - Development Commands"
|
||||
|
|
@ -24,6 +24,7 @@ help:
|
|||
@echo "Testing:"
|
||||
@echo " make test - Test TTS endpoint (Qwen3-TTS)"
|
||||
@echo " make test-qwen - Test Qwen3-TTS voice cloning"
|
||||
@echo " make test-f5 - Test F5-TTS voice cloning"
|
||||
@echo " make hydrate - Test all configured voices"
|
||||
@echo " make load-test - Concurrent load test"
|
||||
@echo ""
|
||||
|
|
@ -118,6 +119,15 @@ test-qwen:
|
|||
@echo ""
|
||||
@echo "Saved to /tmp/qwen_test.mp3"
|
||||
|
||||
test-f5:
|
||||
@echo "Testing F5-TTS endpoint..."
|
||||
curl -X POST http://localhost:8000/v1/audio/speech \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"tts-1-f5","voice":"aria","input":"Raccoon mission TTS test with F5 flow matching"}' \
|
||||
-o /tmp/f5_test.mp3
|
||||
@echo ""
|
||||
@echo "Saved to /tmp/f5_test.mp3"
|
||||
|
||||
test-kokoro:
|
||||
@echo "Testing Kokoro fast synthesis..."
|
||||
curl -X POST http://localhost:8000/v1/audio/speech \
|
||||
|
|
|
|||
|
|
@ -125,6 +125,66 @@ make test-qwen # Test Qwen3-TTS explicitly
|
|||
|
||||
---
|
||||
|
||||
### F5-TTS ✅ (also enabled by default)
|
||||
|
||||
**Status:** INTEGRATED as tts-1-f5 (additive, alongside tts-1-qwen)
|
||||
**Project:** SWivid/F5-TTS (community-maintained, gated HuggingFace checkpoint)
|
||||
**License:** MIT (model + code)
|
||||
**Model:** F5-TTS_v1
|
||||
|
||||
**Why Integrated:**
|
||||
- Empirical benchmark (Richard, 2026-05-23): faster inference + better voice clones than Qwen3-TTS on the same reference clips
|
||||
- Smaller model (~336M params vs Qwen3-TTS 1.7B) — lower VRAM, fits comfortably on modest GPUs
|
||||
- Flow-matching architecture, zero-shot cloning, no fine-tuning needed
|
||||
- 24kHz output, matches Qwen3-TTS sample rate (drop-in voice swap for clients)
|
||||
|
||||
**Model Specs:**
|
||||
- Parameters: ~336M
|
||||
- Sample Rate: 24kHz
|
||||
- Input: Text + Reference Audio (3+ seconds) + Reference Transcript
|
||||
- Languages: English (primary); community fine-tunes available for others
|
||||
- Size: ~1.5GB (F5-TTS_v1 + Vocos vocoder)
|
||||
|
||||
**Model Source:**
|
||||
- HuggingFace: `SWivid/F5-TTS` (**gated** — accept license at https://huggingface.co/SWivid/F5-TTS)
|
||||
- Auto-downloaded on first use; requires `HF_TOKEN` env var
|
||||
|
||||
**Integration:**
|
||||
- Used for `tts-1-f5` model (additive default)
|
||||
- Voice cloning with `ref_audio` + `ref_text` (same shape as tts-1-qwen)
|
||||
- Reuses the same 40 LibriSpeech voices as tts-1-qwen
|
||||
|
||||
**Example Config:**
|
||||
```yaml
|
||||
tts-1-f5:
|
||||
aria:
|
||||
ref_audio: cloned-voices/aria.wav
|
||||
ref_text: "BUT THE WINDOWS ARE PATCHED WITH WOODEN PANES AND THE DOOR I THINK IS LIKE THE GATE IT IS NEVER OPENED"
|
||||
language: English
|
||||
```
|
||||
|
||||
**Tuning Knobs (engine-specific, not OpenAI-compatible):**
|
||||
- `nfe_step` (default 32) — ODE step count; higher = better quality, slower
|
||||
- `cfg_strength` (default 2.0) — classifier-free guidance strength
|
||||
- `speed` (default 1.0) — pitch-preserving speed multiplier
|
||||
- Does NOT support `temperature` / `top_p` / `top_k` (flow-matching, not autoregressive)
|
||||
|
||||
**Makefile Targets:**
|
||||
```bash
|
||||
make test-f5 # Test F5-TTS voice cloning
|
||||
```
|
||||
|
||||
**Hardware Requirements:**
|
||||
- GPU: NVIDIA with 4GB+ VRAM (lighter than Qwen3-TTS)
|
||||
- CPU: Works but many× realtime
|
||||
- MPS (Apple Silicon): supported, ~1.5–2× realtime per VoiceClone benchmarks
|
||||
|
||||
**Source of Inspiration:** [MonumentalSystems/VoiceClone](https://github.com/MonumentalSystems/VoiceClone) — a single-file F5-TTS web app that proved the engine on our reference workload. Our wrapper mirrors their `F5TTS.infer()` call pattern.
|
||||
|
||||
**Raccoon Priority:** ⭐⭐⭐⭐⭐ (Empirically beats current default, MIT, lower VRAM)
|
||||
|
||||
---
|
||||
|
||||
### 1. Piper TTS (disabled by default) ✅
|
||||
|
||||
> 📖 **See [detailed documentation](models/piper-tts.md)** for comprehensive technical specs and integration guide
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ loguru
|
|||
# Qwen3-TTS - state-of-the-art TTS with voice cloning (Apache 2.0)
|
||||
# 1.7B params, 10 languages, 97ms latency, 12Hz tokenizer
|
||||
qwen-tts>=0.0.5
|
||||
# F5-TTS - flow-matching zero-shot voice cloning (MIT, SWivid/F5-TTS)
|
||||
# 336M params, 24kHz output, no fine-tuning needed
|
||||
# Checked 2026-05-23: 1.1.20 is latest stable
|
||||
# Note: gated checkpoint on HuggingFace; requires HF_TOKEN env var + license accept
|
||||
f5-tts==1.1.20
|
||||
# OHF-Voice fork doesn't have installable Python package yet
|
||||
# Stick with PyPI piper-tts but use absolute paths in config
|
||||
# piper-tts>=1.2.0
|
||||
|
|
|
|||
|
|
@ -9,4 +9,9 @@ WORKERS=1
|
|||
#PRELOAD_MODEL=xtts
|
||||
#PRELOAD_MODEL=xtts_v2.0.2
|
||||
#EXTRA_ARGS=--log-level DEBUG --unload-timer 300
|
||||
#USE_ROCM=1
|
||||
#USE_ROCM=1
|
||||
|
||||
# F5-TTS gated checkpoint requires a HuggingFace token + license accept.
|
||||
# Visit https://huggingface.co/SWivid/F5-TTS, accept the license, then set
|
||||
# this in your local speech.env (NOT here — sample.env is committed).
|
||||
#HF_TOKEN=
|
||||
182
speech.py
182
speech.py
|
|
@ -52,6 +52,20 @@ except ImportError:
|
|||
torch = None
|
||||
Qwen3TTSModel = None
|
||||
|
||||
# Try to import F5-TTS dependencies (SWivid/F5-TTS, MIT-licensed flow-matching TTS)
|
||||
try:
|
||||
import torch
|
||||
from f5_tts.api import F5TTS
|
||||
F5_TTS_AVAILABLE = True
|
||||
except ImportError:
|
||||
F5_TTS_AVAILABLE = False
|
||||
if torch is None:
|
||||
try:
|
||||
import torch
|
||||
except ImportError:
|
||||
torch = None
|
||||
F5TTS = None
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def lifespan(app):
|
||||
# Startup: Initialize voice caches in each worker process
|
||||
|
|
@ -107,6 +121,10 @@ async def lifespan(app):
|
|||
model_info["engine"] = "qwen3-tts"
|
||||
model_info["description"] = "State-of-the-art TTS with voice cloning (1.7B params, 10 languages)"
|
||||
model_info["sample_rate"] = 24000
|
||||
elif model_id == 'tts-1-f5':
|
||||
model_info["engine"] = "f5-tts"
|
||||
model_info["description"] = "Flow-matching zero-shot voice cloning (336M params, MIT)"
|
||||
model_info["sample_rate"] = 24000
|
||||
|
||||
models_data.append(model_info)
|
||||
|
||||
|
|
@ -145,6 +163,7 @@ kokoro_pipeline = None
|
|||
kokoro_lang = None
|
||||
qwen_model = None
|
||||
qwen_voice_prompts = {} # Cache for voice clone prompts
|
||||
f5_model = None
|
||||
|
||||
# Default args for worker processes (will be overridden in __main__)
|
||||
class DefaultArgs:
|
||||
|
|
@ -180,6 +199,7 @@ voices_cache = None
|
|||
silero_load_semaphore = asyncio.Semaphore(1) # Only one Silero model load at a time
|
||||
kokoro_load_semaphore = asyncio.Semaphore(1) # Only one Kokoro model load at a time
|
||||
qwen_load_semaphore = asyncio.Semaphore(1) # Only one Qwen model load at a time
|
||||
f5_load_semaphore = asyncio.Semaphore(1) # Only one F5-TTS model load at a time
|
||||
|
||||
def unload_model():
|
||||
import torch, gc
|
||||
|
|
@ -491,6 +511,72 @@ class qwen3_wrapper():
|
|||
logger.error(f"Qwen3-TTS generation failed: {e}")
|
||||
raise
|
||||
|
||||
class f5_wrapper():
|
||||
"""Wrapper for F5-TTS model (SWivid/F5-TTS, MIT)
|
||||
|
||||
Flow-matching zero-shot voice cloning:
|
||||
- ~336M params, smaller than Qwen3-TTS (1.7B)
|
||||
- 24kHz output, matches Qwen3-TTS sample rate
|
||||
- Reference audio + transcript, no fine-tuning
|
||||
- No temperature/top_p/top_k — uses cfg_strength + nfe_step instead
|
||||
"""
|
||||
def __init__(self, device='cuda'):
|
||||
self.device = device
|
||||
self.sample_rate = 24000 # f5_tts.infer.utils_infer.target_sample_rate
|
||||
|
||||
logger.info(f"Loading F5-TTS model on device '{device}'")
|
||||
|
||||
try:
|
||||
from f5_tts.api import F5TTS
|
||||
self.model = F5TTS(device=device)
|
||||
logger.info(f"Successfully loaded F5-TTS model on {device}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load F5-TTS model: {e}")
|
||||
raise
|
||||
|
||||
def tts(self, text, ref_audio, ref_text, speed=1.0, nfe_step=32, cfg_strength=2.0):
|
||||
"""Generate speech from text using F5-TTS voice cloning.
|
||||
|
||||
Args:
|
||||
text: Text to synthesize
|
||||
ref_audio: Path to reference audio file
|
||||
ref_text: Transcript of reference audio
|
||||
speed: Speed multiplier (1.0 = normal)
|
||||
nfe_step: Number of ODE steps (32 = default, balance quality/speed)
|
||||
cfg_strength: Classifier-free guidance strength
|
||||
|
||||
Returns:
|
||||
Audio data as bytes (float32 PCM at 24kHz)
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
logger.info(f"F5-TTS generating: text length={len(text)}")
|
||||
|
||||
try:
|
||||
wav, sr, _spec = self.model.infer(
|
||||
ref_file=ref_audio,
|
||||
ref_text=ref_text,
|
||||
gen_text=text,
|
||||
nfe_step=nfe_step,
|
||||
cfg_strength=cfg_strength,
|
||||
speed=speed,
|
||||
show_info=lambda *a, **k: None,
|
||||
progress=None,
|
||||
)
|
||||
|
||||
if hasattr(wav, 'detach'):
|
||||
wav = wav.detach().to('cpu', dtype=torch.float32).numpy()
|
||||
audio = np.asarray(wav, dtype=np.float32).flatten()
|
||||
|
||||
self.sample_rate = sr
|
||||
logger.info(f"F5-TTS generated {len(audio)} samples at {sr}Hz")
|
||||
|
||||
return audio.tobytes()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"F5-TTS generation failed: {e}")
|
||||
raise
|
||||
|
||||
def default_exists(filename: str):
|
||||
if not os.path.exists(filename):
|
||||
fpath, ext = os.path.splitext(filename)
|
||||
|
|
@ -613,7 +699,7 @@ def build_ffmpeg_args(response_format, input_format, sample_rate):
|
|||
async def list_models():
|
||||
"""List all available TTS models (OpenAI-compatible format)"""
|
||||
# Return minimal OpenAI-compatible model list (no extra fields)
|
||||
# Only tts-1-qwen is enabled by default
|
||||
# tts-1-qwen and tts-1-f5 enabled by default
|
||||
return {
|
||||
"object": "list",
|
||||
"data": [
|
||||
|
|
@ -622,6 +708,12 @@ async def list_models():
|
|||
"object": "model",
|
||||
"created": 1700000000,
|
||||
"owned_by": "uncloseai"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-f5",
|
||||
"object": "model",
|
||||
"created": 1700000000,
|
||||
"owned_by": "uncloseai"
|
||||
}
|
||||
# Other models disabled by default:
|
||||
# {
|
||||
|
|
@ -705,6 +797,10 @@ async def list_voices():
|
|||
model_info["engine"] = "qwen3-tts"
|
||||
model_info["description"] = "State-of-the-art TTS with voice cloning (1.7B params, 10 languages)"
|
||||
model_info["sample_rate"] = 24000
|
||||
elif model_id == 'tts-1-f5':
|
||||
model_info["engine"] = "f5-tts"
|
||||
model_info["description"] = "Flow-matching zero-shot voice cloning (336M params, MIT)"
|
||||
model_info["sample_rate"] = 24000
|
||||
|
||||
models_data.append(model_info)
|
||||
|
||||
|
|
@ -764,6 +860,8 @@ async def generate_speech(request: GenerateSpeechRequest):
|
|||
media_type = "audio/pcm;rate=24000"
|
||||
elif model == 'tts-1-qwen': # qwen3-tts
|
||||
media_type = "audio/pcm;rate=24000"
|
||||
elif model == 'tts-1-f5': # f5-tts
|
||||
media_type = "audio/pcm;rate=24000"
|
||||
else:
|
||||
raise BadRequestError(f"Invalid response_format: '{response_format}'", param='response_format')
|
||||
|
||||
|
|
@ -1174,9 +1272,86 @@ async def generate_speech(request: GenerateSpeechRequest):
|
|||
out_writer_worker = threading.Thread(target=out_writer, daemon=True)
|
||||
out_writer_worker.start()
|
||||
|
||||
return StreamingResponse(content=ffmpeg_proc.stdout, media_type=media_type)
|
||||
# Use F5-TTS for tts-1-f5
|
||||
elif model == 'tts-1-f5':
|
||||
global f5_model
|
||||
|
||||
if not F5_TTS_AVAILABLE:
|
||||
raise ServiceUnavailableError("F5-TTS is not available. Install with: pip install f5-tts")
|
||||
|
||||
voice_map = map_voice_to_speaker(voice, 'tts-1-f5')
|
||||
ref_audio = voice_map.get('ref_audio')
|
||||
ref_text = voice_map.get('ref_text')
|
||||
|
||||
if not (ref_audio and ref_text):
|
||||
raise BadRequestError(f"Voice '{voice}' requires ref_audio and ref_text configuration", param='voice')
|
||||
|
||||
# Load F5 model if not already loaded
|
||||
if f5_model is None:
|
||||
async with f5_load_semaphore:
|
||||
if f5_model is None:
|
||||
device = args.xtts_device if args.xtts_device != 'none' else 'cpu'
|
||||
logger.info(f"Loading F5-TTS model on device '{device}'")
|
||||
f5_model = await asyncio.to_thread(f5_wrapper, device=device)
|
||||
|
||||
# Split text into sentences for streaming (first audio arrives faster)
|
||||
sentences = simple_sentence_split(input_text, max_length=500)
|
||||
logger.info(f"Split text into {len(sentences)} sentences for F5-TTS streaming")
|
||||
|
||||
# F5-TTS outputs float32 PCM at 24kHz
|
||||
ffmpeg_args = build_ffmpeg_args(response_format, input_format="f32le", sample_rate="24000")
|
||||
|
||||
# F5-TTS accepts speed natively; only apply atempo as a fallback when ffmpeg can do it cheaper
|
||||
# (we pass speed to the model below, leaving ffmpeg speed at 1.0)
|
||||
|
||||
ffmpeg_args.extend(["-"])
|
||||
ffmpeg_proc = subprocess.Popen(ffmpeg_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
|
||||
in_q = queue.Queue()
|
||||
|
||||
def generator():
|
||||
"""Process sentences sequentially and feed to queue"""
|
||||
try:
|
||||
for idx, sentence in enumerate(sentences):
|
||||
logger.debug(f"F5-TTS processing sentence {idx+1}/{len(sentences)}: {len(sentence)} chars")
|
||||
audio_bytes = f5_model.tts(
|
||||
text=sentence,
|
||||
ref_audio=ref_audio,
|
||||
ref_text=ref_text,
|
||||
speed=speed,
|
||||
)
|
||||
in_q.put(audio_bytes)
|
||||
logger.debug(f"F5-TTS: queued sentence {idx+1}/{len(sentences)}")
|
||||
except Exception as e:
|
||||
logger.error(f"F5-TTS streaming error: {e}")
|
||||
finally:
|
||||
in_q.put(None)
|
||||
logger.info(f"F5-TTS streaming complete: {len(sentences)} sentences processed")
|
||||
|
||||
def out_writer():
|
||||
"""Write audio from queue to ffmpeg stdin"""
|
||||
try:
|
||||
while True:
|
||||
chunk = in_q.get()
|
||||
if chunk is None:
|
||||
break
|
||||
ffmpeg_proc.stdin.write(chunk)
|
||||
except Exception as e:
|
||||
logger.error(f"F5-TTS ffmpeg write error: {e}")
|
||||
ffmpeg_proc.kill()
|
||||
finally:
|
||||
ffmpeg_proc.stdin.close()
|
||||
|
||||
generator_worker = threading.Thread(target=generator, daemon=True)
|
||||
generator_worker.start()
|
||||
|
||||
out_writer_worker = threading.Thread(target=out_writer, daemon=True)
|
||||
out_writer_worker.start()
|
||||
|
||||
return StreamingResponse(content=ffmpeg_proc.stdout, media_type=media_type)
|
||||
else:
|
||||
raise BadRequestError("No such model, must be tts-1-qwen (default), tts-1, tts-1-hd, tts-1-silero, or tts-1-kokoro.", param='model')
|
||||
raise BadRequestError("No such model, must be tts-1-qwen (default), tts-1-f5, tts-1, tts-1-hd, tts-1-silero, or tts-1-kokoro.", param='model')
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
@ -1203,8 +1378,9 @@ if __name__ == "__main__":
|
|||
elif args.preload:
|
||||
xtts = xtts_wrapper(args.preload, device=args.xtts_device, unload_timer=args.unload_timer)
|
||||
|
||||
# Register only Qwen by default (other models disabled)
|
||||
# Register Qwen + F5 by default (other models disabled)
|
||||
app.register_model('tts-1-qwen')
|
||||
app.register_model('tts-1-f5')
|
||||
# To enable other models, uncomment below:
|
||||
# app.register_model('tts-1')
|
||||
# app.register_model('tts-1-hd')
|
||||
|
|
|
|||
|
|
@ -266,3 +266,253 @@ tts-1-qwen:
|
|||
# alloy:
|
||||
# model: xtts
|
||||
# speaker: voices/alloy.wav
|
||||
|
||||
# ===== F5-TTS voice mappings =====
|
||||
# Same 40 LibriSpeech speakers as tts-1-qwen, reused for F5-TTS (flow-matching).
|
||||
# F5-TTS uses ref_audio + ref_text; identical to Qwen3-TTS reference format.
|
||||
|
||||
tts-1-f5:
|
||||
|
||||
# female - speaker 2094
|
||||
aria:
|
||||
ref_audio: cloned-voices/aria.wav
|
||||
ref_text: "BUT THE WINDOWS ARE PATCHED WITH WOODEN PANES AND THE DOOR I THINK IS LIKE THE GATE IT IS NEVER OPENED"
|
||||
language: English
|
||||
|
||||
# female - speaker 3575
|
||||
clara:
|
||||
ref_audio: cloned-voices/clara.wav
|
||||
ref_text: "BUT IT IS NOT WITH A VIEW TO DISTINCTION THAT YOU SHOULD CULTIVATE THIS TALENT IF YOU CONSULT YOUR OWN HAPPINESS"
|
||||
language: English
|
||||
|
||||
# female - speaker 2961
|
||||
elena:
|
||||
ref_audio: cloned-voices/elena.wav
|
||||
ref_text: "MANY IF NOT ALL THE ELEMENTS OF THE PRE SOCRATIC PHILOSOPHY ARE INCLUDED IN THE TIMAEUS"
|
||||
language: English
|
||||
|
||||
# female - speaker 8463
|
||||
grace:
|
||||
ref_audio: cloned-voices/grace.wav
|
||||
ref_text: "AS TO HIS AGE AND ALSO THE NAME OF HIS MASTER JACOB'S STATEMENT VARIED SOMEWHAT FROM THE ADVERTISEMENT"
|
||||
language: English
|
||||
|
||||
# female - speaker 1995
|
||||
hazel:
|
||||
ref_audio: cloned-voices/hazel.wav
|
||||
ref_text: "I BELIEVE IN THE TRAINING OF PEOPLE TO THEIR HIGHEST CAPACITY THE ENGLISHMAN HERE HEARTILY SECONDED HIM"
|
||||
language: English
|
||||
|
||||
# female - speaker 1284
|
||||
iris:
|
||||
ref_audio: cloned-voices/iris.wav
|
||||
ref_text: "GOLD IS THE MOST COMMON METAL IN THE LAND OF OZ AND IS USED FOR MANY PURPOSES BECAUSE IT IS SOFT AND PLIABLE"
|
||||
language: English
|
||||
|
||||
# female - speaker 5142
|
||||
luna:
|
||||
ref_audio: cloned-voices/luna.wav
|
||||
ref_text: "THE DOOR OPENED AGAIN WHILE I WAS STILL STUDYING THE TWO BROTHERS WITHOUT I HONESTLY CONFESS BEING VERY FAVORABLY IMPRESSED BY EITHER OF THEM"
|
||||
language: English
|
||||
|
||||
# female - speaker 4446
|
||||
maya:
|
||||
ref_audio: cloned-voices/maya.wav
|
||||
ref_text: "HE HAD PRECONCEIVED IDEAS ABOUT EVERYTHING AND HIS IDEA ABOUT AMERICANS WAS THAT THEY SHOULD BE ENGINEERS OR MECHANICS"
|
||||
language: English
|
||||
|
||||
# female - speaker 1221
|
||||
ruby:
|
||||
ref_audio: cloned-voices/ruby.wav
|
||||
ref_text: "YEA HIS HONOURABLE WORSHIP IS WITHIN BUT HE HATH A GODLY MINISTER OR TWO WITH HIM AND LIKEWISE A LEECH"
|
||||
language: English
|
||||
|
||||
# female - speaker 4507
|
||||
sage:
|
||||
ref_audio: cloned-voices/sage.wav
|
||||
ref_text: "NOW WHEN HAS HORROR EVER EXCLUDED STUDY"
|
||||
language: English
|
||||
|
||||
# female - speaker 3729
|
||||
sofia:
|
||||
ref_audio: cloned-voices/sofia.wav
|
||||
ref_text: "I HAD A NAME I BELIEVE IN MY YOUNG DAYS BUT I HAVE FORGOTTEN IT SINCE I HAVE BEEN IN SERVICE"
|
||||
language: English
|
||||
|
||||
# female - speaker 121
|
||||
amber:
|
||||
ref_audio: cloned-voices/amber.wav
|
||||
ref_text: "HAY FEVER A HEART TROUBLE CAUSED BY FALLING IN LOVE WITH A GRASS WIDOW"
|
||||
language: English
|
||||
|
||||
# female - speaker 237
|
||||
brooke:
|
||||
ref_audio: cloned-voices/brooke.wav
|
||||
ref_text: "FRANK READ ENGLISH SLOWLY AND THE MORE HE READ ABOUT THIS DIVORCE CASE THE ANGRIER HE GREW"
|
||||
language: English
|
||||
|
||||
# female - speaker 1580
|
||||
cora:
|
||||
ref_audio: cloned-voices/cora.wav
|
||||
ref_text: "THE ALTERNATIVE WAS THAT SOMEONE PASSING HAD OBSERVED THE KEY IN THE DOOR HAD KNOWN THAT I WAS OUT AND HAD ENTERED TO LOOK AT THE PAPERS"
|
||||
language: English
|
||||
|
||||
# female - speaker 3570
|
||||
diana:
|
||||
ref_audio: cloned-voices/diana.wav
|
||||
ref_text: "THE WEARERS OF UNIFORMS AND LIVERIES MAY BE ROUGHLY DIVIDED INTO TWO CLASSES THE FREE AND THE SERVILE OR THE NOBLE AND THE IGNOBLE"
|
||||
language: English
|
||||
|
||||
# female - speaker 4970
|
||||
eden:
|
||||
ref_audio: cloned-voices/eden.wav
|
||||
ref_text: "RUTH SAT QUITE STILL FOR A TIME WITH FACE INTENT AND FLUSHED IT WAS OUT NOW"
|
||||
language: English
|
||||
|
||||
# female - speaker 4992
|
||||
faye:
|
||||
ref_audio: cloned-voices/faye.wav
|
||||
ref_text: "HE GIVE UP HIS POSITION AND SHUT THE FAMILY UP IN THAT TOMB OF A HOUSE SO T HE COULD STUDY HIS BOOKS"
|
||||
language: English
|
||||
|
||||
# female - speaker 5683
|
||||
gemma:
|
||||
ref_audio: cloned-voices/gemma.wav
|
||||
ref_text: "DO YOU KNOW LAKE OH I REALLY CAN'T TELL BUT HE'LL SOON TIRE OF COUNTRY LIFE"
|
||||
language: English
|
||||
|
||||
# female - speaker 6829
|
||||
hope:
|
||||
ref_audio: cloned-voices/hope.wav
|
||||
ref_text: "MISS DE GRAF SAID KENNETH NOTICING THE BOY'S FACE CRITICALLY AS HE STOOD WHERE THE LIGHT FROM THE PASSAGE FELL UPON IT"
|
||||
language: English
|
||||
|
||||
# female - speaker 8555
|
||||
ivy:
|
||||
ref_audio: cloned-voices/ivy.wav
|
||||
ref_text: "OVER THE TRACK LINED CITY STREET THE YOUNG MEN THE GRINNING MEN PASS"
|
||||
language: English
|
||||
|
||||
# male - speaker 6930
|
||||
atlas:
|
||||
ref_audio: cloned-voices/atlas.wav
|
||||
ref_text: "IT IS YOU WHO ARE MISTAKEN RAOUL I HAVE READ HIS DISTRESS IN HIS EYES IN HIS EVERY GESTURE AND ACTION THE WHOLE DAY"
|
||||
language: English
|
||||
|
||||
# male - speaker 1320
|
||||
caleb:
|
||||
ref_audio: cloned-voices/caleb.wav
|
||||
ref_text: "FOUR OR FIVE OF THE LATTER ONLY LINGERED ABOUT THE DOOR OF THE PRISON OF UNCAS WARY BUT CLOSE OBSERVERS OF THE MANNER OF THEIR CAPTIVE"
|
||||
language: English
|
||||
|
||||
# male - speaker 5639
|
||||
felix:
|
||||
ref_audio: cloned-voices/felix.wav
|
||||
ref_text: "SHE SAW THAT THE BED WAS GILDED AND SO RICH THAT IT SEEMED THAT OF A PRINCE RATHER THAN OF A PRIVATE GENTLEMAN"
|
||||
language: English
|
||||
|
||||
# male - speaker 260
|
||||
hugo:
|
||||
ref_audio: cloned-voices/hugo.wav
|
||||
ref_text: "CRIED ALICE AGAIN FOR THIS TIME THE MOUSE WAS BRISTLING ALL OVER AND SHE FELT CERTAIN IT MUST BE REALLY OFFENDED"
|
||||
language: English
|
||||
|
||||
# male - speaker 7729
|
||||
jasper:
|
||||
ref_audio: cloned-voices/jasper.wav
|
||||
ref_text: "THAT SUMMER'S EMIGRATION HOWEVER BEING MAINLY FROM THE FREE STATES GREATLY CHANGED THE RELATIVE STRENGTH OF THE TWO PARTIES"
|
||||
language: English
|
||||
|
||||
# male - speaker 7127
|
||||
kai:
|
||||
ref_audio: cloned-voices/kai.wav
|
||||
ref_text: "UPON THIS MADAME DEIGNED TO TURN HER EYES LANGUISHINGLY TOWARDS THE COMTE OBSERVING"
|
||||
language: English
|
||||
|
||||
# male - speaker 8230
|
||||
leo:
|
||||
ref_audio: cloned-voices/leo.wav
|
||||
ref_text: "THE BEHAVIOURIST WHO ATTEMPTS TO MAKE PSYCHOLOGY A RECORD OF BEHAVIOUR HAS TO TRUST HIS MEMORY IN MAKING THE RECORD"
|
||||
language: English
|
||||
|
||||
# male - speaker 7176
|
||||
marcus:
|
||||
ref_audio: cloned-voices/marcus.wav
|
||||
ref_text: "IN THE OLD BADLY MADE PLAY IT WAS FREQUENTLY NECESSARY FOR ONE OF THE CHARACTERS TO TAKE THE AUDIENCE INTO HIS CONFIDENCE"
|
||||
language: English
|
||||
|
||||
# male - speaker 8455
|
||||
owen:
|
||||
ref_audio: cloned-voices/owen.wav
|
||||
ref_text: "I DID NOT MEAN SAID CAPTAIN BATTLEAX TO TOUCH UPON PUBLIC SUBJECTS AT SUCH A MOMENT AS THIS"
|
||||
language: English
|
||||
|
||||
# male - speaker 2830
|
||||
theo:
|
||||
ref_audio: cloned-voices/theo.wav
|
||||
ref_text: "I KNEW NOTHING OF THE DOCTRINE OF FAITH BECAUSE WE WERE TAUGHT SOPHISTRY INSTEAD OF CERTAINTY AND NOBODY UNDERSTOOD SPIRITUAL BOASTING"
|
||||
language: English
|
||||
|
||||
# male - speaker 61
|
||||
archer:
|
||||
ref_audio: cloned-voices/archer.wav
|
||||
ref_text: "WHAT IS THE TUMULT AND RIOTING CRIED OUT THE SQUIRE AUTHORITATIVELY AND HE BLEW TWICE ON A SILVER WHISTLE WHICH HUNG AT HIS BELT"
|
||||
language: English
|
||||
|
||||
# male - speaker 672
|
||||
blake:
|
||||
ref_audio: cloned-voices/blake.wav
|
||||
ref_text: "IN AUTUMN THE WOOD CUTTERS ALWAYS CAME AND FELLED SOME OF THE LARGEST TREES"
|
||||
language: English
|
||||
|
||||
# male - speaker 908
|
||||
cole:
|
||||
ref_audio: cloned-voices/cole.wav
|
||||
ref_text: "LIKE THE DOVES VOICE LIKE TRANSIENT DAY LIKE MUSIC IN THE AIR AH"
|
||||
language: English
|
||||
|
||||
# male - speaker 1089
|
||||
dane:
|
||||
ref_audio: cloned-voices/dane.wav
|
||||
ref_text: "THE PRIDE OF THAT DIM IMAGE BROUGHT BACK TO HIS MIND THE DIGNITY OF THE OFFICE HE HAD REFUSED"
|
||||
language: English
|
||||
|
||||
# male - speaker 1188
|
||||
ezra:
|
||||
ref_audio: cloned-voices/ezra.wav
|
||||
ref_text: "BUT IN THIS VIGNETTE COPIED FROM TURNER YOU HAVE THE TWO PRINCIPLES BROUGHT OUT PERFECTLY"
|
||||
language: English
|
||||
|
||||
# male - speaker 2300
|
||||
finn:
|
||||
ref_audio: cloned-voices/finn.wav
|
||||
ref_text: "WHY IF WE ERECT A STATION AT THE FALLS IT IS A GREAT ECONOMY TO GET IT UP TO THE CITY"
|
||||
language: English
|
||||
|
||||
# male - speaker 4077
|
||||
grant:
|
||||
ref_audio: cloned-voices/grant.wav
|
||||
ref_text: "AT THE INCEPTION OF PLURAL MARRIAGE AMONG THE LATTER DAY SAINTS THERE WAS NO LAW NATIONAL OR STATE AGAINST ITS PRACTISE"
|
||||
language: English
|
||||
|
||||
# male - speaker 5105
|
||||
heath:
|
||||
ref_audio: cloned-voices/heath.wav
|
||||
ref_text: "AND WHAT DEMONSTRATION DO YOU OFFER ASKED SERVADAC EAGERLY THAT IT WILL NOT HAPPEN"
|
||||
language: English
|
||||
|
||||
# male - speaker 7021
|
||||
ivan:
|
||||
ref_audio: cloned-voices/ivan.wav
|
||||
ref_text: "THEN TURNING TO JANE SHE ASKED IN A SOMEWHAT ALTERED TONE HAS SHE BEEN A GOOD GIRL JANE"
|
||||
language: English
|
||||
|
||||
# male - speaker 8224
|
||||
jude:
|
||||
ref_audio: cloned-voices/jude.wav
|
||||
ref_text: "THE KING STOOD UP AND CALLED FOR THAT PSALM WHICH BEGINS WITH THESE WORDS"
|
||||
language: English
|
||||
|
||||
# Other TTS engines (disabled by default)
|
||||
# Uncomment and configure to enable
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue