Pick a voice on the left
to edit it here
No matching sources found.${errorText?" Source errors: "+escHtml(errorText):""}
${more} more matches. Narrow the search or filters to see them.
Add at least one source URL, then scrape again.
Scrape failed: ${escHtml(e.message)}
Check that the TTS Voice Creator backend is restarted and that at least one source URL is reachable.
Table View Mode
Click a row to exit table view and edit.
${results.length-failed.length} / ${results.length} passed.${failed.length?" Failed voices likely need a redesign.":""}
Set the path where your .wav voice files live inside the container.
Map a host folder via docker-compose:
- /your/host/path:/voices:rw
or set VOICE_HOST_DIR=/your/host/path in the stack env.
Create your first voice from a recording or download ready-made voices.
Compare the saved reference WAV with a fresh synthesis of the same reference text. Restart TTS first after editing a voice, otherwise the backend may still use a cached version.
Preview first. Saving creates a new active WAV voice from the current reference text. Same-voice style only works when the selected backend knows this voice and honors instruct; CustomVoice is style-aware; Base/Streaming are fastest but often ignore style.
This permanently removes the selected voice${plural} from your library. This cannot be undone.
No saved rehearsals yet.
Parse a script below or drop a file to start.
[tags] (e.g. [whisper], [excited], [laughing]). You can also type a custom tone like [professional broadcast tone] \u2014 S2 supports free-form descriptions. Fish-Speech S2 \u2197`),warn.hidden=!1;else if(!b.style_aware&&hasTone){const styleAware=all.find(x=>x.style_aware&&x.uses_wav)||all.find(x=>x.style_aware);txtEl&&(txtEl.innerHTML=styleAware?`| Tone control | Voice stays identical |
|---|
Qwen3TTS tone is sent as the per-line style/instruct text, so this is the right path for directed delivery.
':"";txtEl&&(txtEl.innerHTML=wavBackend?`| Tone control | Voice stays identical |
|---|
No clips in this session.
';return}list.innerHTML=rehState.clips.map((clip,idx)=>{const line=rehState.lines[clip.lineIndex]||{text:"\u2014",speaker:clip.speaker},c=rehState.cast[clip.speaker]||{color:"#89b4fa"},typeLabel=clip.type==="me"?"\u{1F3A4} Recorded":clip.type==="tts"?"\u{1F50A} Synthesized":"\u23ED Skipped",audioHtml=clip.blob?``:"",dlHtml=clip.blob?``:"";return`Open a document in the Reader tab and click "Cast as audiobook" to start extracting characters.
This stage will show the live passage-by-passage extraction view, prompt editor, and generated sheets once you start a cast.
${escHtml(text)}
Saved on the server${opts.browsing?"":", in case the browser\u2019s own download went somewhere you don\u2019t check"} \u2014 come back and download any of these again any time, without re-exporting.
${_clRecords.length?"No characters match your filter.":"No characters yet."}
Run Character sheets from Read Aloud or the Script Rehearser to populate your library.
No books yet.
Open Read Aloud, import a PDF or text, and save it to your library.
No theater plays yet.
Open Script Rehearsal \u2192 Import / Export to add a script, or cast a book as an audiobook.
No characters yet.
Open a book in Read Aloud, cast it as an audiobook, then click Cast Characters to generate character sheets \u2014 or import an existing cast from SillyTavern.
| '+th("alpha","Name")+th("gender","Geschlecht")+th("age","Alter","Estimated age")+th("lines","Zeilen","Anzahl Zeilen")+th("language","Sprache")+th("align","Gut/B\xF6se","Moralische Gesinnung")+th("voice","Stimme")+" | Tags | Book / Script |
|---|
Used in every voice design (and image) prompt for this book, so a fantasy story doesn't end up with 1920s-general portraits or English voices in a German book just because one character's own sheet was too sparse to tell.
"'+escHtml(reuse.voiceId)+'" is already used for '+escHtml(rec.name)+' in "'+escHtml(reuse.book)+'". Reuse it for series consistency, or design a brand-new voice just for this book?
Edit the description, then generate a new voice from it. This replaces '+(rec.voice?"the current voice":"this character\u2019s voice")+'.
Optional \u2014 let the AI fill out full character profiles (appearance, backstory, voice notes) for reference. Skip this if you just want to cast voices quickly.