Welcome to any script writing author out there!
Convert formatted script files into fully voiced audio using Cartesia Sonic-3 — a high-quality cloud text-to-speech engine with expressive voices, an emotion system, and native laughter generation.
Get it here: https://reactorcore.itch.io/script-to-voice-generator-cartesia
Made by Reactorcore — https://linktr.ee/reactorcore
Script to Voice Generator reads a formatted .txt or .md script file and:
- Converts each dialogue line to speech using Cartesia Sonic-3 TTS (any voice from your Cartesia account).
- Saves individual clips for each line — both clean (TTS only) and effects-processed.
- Merges all clips into a single audio file, with smart pauses based on punctuation.
- Produces both a raw merge and a loudness-normalized merge.
- Generates a reference sheet listing every clip filename and its spoken text.
Multiple speakers are supported. Each speaker gets their own voice, emotion, pitch, speed,
and audio effects settings, stored in character_profiles.json so they're remembered between sessions.
- Windows 11 — built and tested on Windows 11.
- Windows 10 — untested, use at your own risk.
- Linux / macOS — the compiled
.exeis Windows-only. No Linux or macOS build is available. - Internet connection — required for TTS generation (Cartesia is a cloud API).
Cartesia API key — Required for TTS generation.
- Go to play.cartesia.ai and create an account.
- Open the Settings tab (Tab 4) in the app.
- Follow the instructions to create and paste your API key.
Cartesia's free tier gives you 20,000 model credits per month — roughly enough for a solid amount of audio before you'd need a paid plan.
FFMPEG — Required for audio effects and merging.
- Automatic installer (recommended): https://reactorcore.itch.io/ffmpeg-to-path-installer
- Manual install: https://ffmpeg.org/download.html — add to system PATH after installing.
Python 3.x — Required to run from source (not needed if using the compiled .exe).
Use build_exe.bat to build to a single .exe in one click.
Launch the app and go to Tab 4 — Settings. Paste your Cartesia API key and click Save. Voices will load automatically.
Scripts are .txt or .md files. Each spoken line uses the format:
SpeakerID: Dialogue text goes here.
Example:
# My Short Film
Alex: Hey, are you okay?
Jordan: {emotion: tired} Yeah, I'm fine. Just tired.
(1.0s)
Alex: You sure? You look pale.
Jordan: I said I'm fine.
See Script Format below for full syntax details.
- Launch the program and click Open Script File.
- The parser checks for formatting errors and lists them in the log.
- Fix any errors in your text editor and click Reload Script.
- When the parse log shows no errors, click Continue →.
Each detected speaker gets a panel with:
- Voice — Choose from any voice in your Cartesia account. Voices are fetched automatically when the app loads with a valid API key. The best voices for expressive delivery are: Leo, Jace, Kyle, Gavin, Maya, Tessa, Dana, Marian.
- Emotion — Guides Sonic-3's emotional delivery for this speaker (56 options). Default: neutral. Match the emotion to your character's overall register.
- Speed — Speaking rate from 0.6× to 1.5× (Cartesia native speed parameter).
- Pitch — Multiplier from ×0.5 to ×2.0 (FFMPEG rubberband pitch shift). Default ×1.0 = no shift.
- Level — 5–100% relative volume. 100% = full normalized output (default). Reduce to make a speaker quieter in the mix.
- Yell Impact — Slows down single-word exclamatory lines (e.g.
YES!). Makes such lines sound more deliberate and impactful. Set per speaker. - Audio Effects — Radio, Reverb, Distortion, Telephone, Robot Voice, Cheap Mic, Underwater, Megaphone, Worn Tape, Intercom, Alien Voice, Cave, and Pitch Shift. Most effects have Off / Mild / Medium / Strong levels.
Use Test Voice to generate a quick preview clip and hear the settings immediately.
Settings auto-save to character_profiles.json on every change, so known speakers
are recalled automatically next session.
- Enter a Project Name (used as a filename prefix, 20 chars max).
- Choose an Output Folder.
- Click Generate All and confirm.
The generation log shows progress. When done, all files appear in the output folder:
output_folder/
├── clips_clean/ ← Raw TTS clips (no FFMPEG effects)
│ └── project_0001_Speaker_line-text.mp3
├── clips_effect/ ← Effects-processed clips (peak-normalized)
│ └── project_0001_Speaker_line-text.mp3
├── sfx/ ← Processed SFX copies (only if SFX effects active)
├── !project_merged_pure.mp3 ← Merged audio, no normalization
├── !project_merged_loudnorm.mp3 ← Merged audio, loudness-normalized
└── project_reference.txt ← Line-by-line reference sheet
SpeakerID: Spoken text goes here.
- SpeakerID must be 20 characters or fewer. Allowed: letters, numbers, spaces, hyphens, underscores.
- All text after the first colon is spoken. Additional colons in the line are fine.
- Lines over 4000 characters throw a parse error.
ARIA: {emotion: angry} You never listen!
ARIA: {emotion: sad} I know. I'm sorry.
ARIA: Back to the Tab 2 default emotion here.
Place {emotion: X} immediately after the SpeakerID, before the dialogue text. It overrides the Tab 2 emotion setting for that line only. The generation log notes the override when it fires.
Critical rule: The emotion must match the dialogue content. Mismatched emotion degrades output quality.
The 6 primary emotions give the most reliable results: neutral, angry, excited, content, sad, scared
All 56 values: neutral, happy, excited, enthusiastic, elated, euphoric, triumphant, amazed, surprised, flirtatious, curious, content, peaceful, serene, calm, grateful, affectionate, trust, sympathetic, anticipation, mysterious, proud, confident, angry, mad, outraged, frustrated, agitated, threatened, disgusted, contempt, envious, sarcastic, ironic, distant, skeptical, sad, dejected, melancholic, disappointed, hurt, guilty, bored, tired, rejected, nostalgic, wistful, apologetic, hesitant, insecure, confused, resigned, anxious, panicked, alarmed, scared, contemplative, determined
Alex: I can't believe it worked. [laughter]
Jordan: [laughter] Neither can I.
[laughter] triggers AI-generated laughter inline. Place it anywhere in a dialogue line. More nonverbalisms are coming from Cartesia — [laughter] is currently the only one available.
Alex: I know... <break time="0.8s"/> I just can't do it.
Jordan: <speed ratio="1.3"/>Go go go!
Alex: <spell>NATO</spell> protocol.
| Tag | What it does |
|---|---|
<break time="1s"/> |
Mid-sentence pause (inside the clip) |
<break time="200ms"/> |
Short pause in milliseconds |
<speed ratio="1.3"/> |
Speed up or slow down this section |
<volume ratio="0.6"/> |
Quieter section inline |
<spell>TEXT</spell> |
Spell out letters individually (for acronyms, callsigns) |
Note: <break> is a mid-sentence API pause. STVG's (1.5s) syntax is a between-clip merger pause — they are different tools.
# Scene title
## Sub-scene
Treated as metadata. Sets the script title. Not voiced.
// This is a comment
/* Multi-line
comment */
Not voiced. Useful for stage directions, notes, or commented-out lines.
(1.5s)
(pause 2.0)
(0.8)
Any line that is only parentheses containing a number inserts a silent pause in the merged audio. The number is in seconds.
{play filename.mp3, c1, loop}
{stop c1}
{stop all}
{play explosion.wav, c2, once}
Sound effect events are placed in the merge timeline at the correct position. Sound effect files must exist in the SFX folder specified in Tab 2.
Note: If a sound effect is the very last item in your script, it needs a pause after it to actually be heard in the merged audio.
Add a (pause) line equal to or longer than the sound effect's duration immediately after the {play} line. Without it, the base audio ends at the same moment the SFX starts, and the SFX gets cut off.
Like this:
Rei: Signing off.
{play cloth.wav, c1, once}
(2.0s)
Supported formats — Any audio format FFMPEG can read: .mp3, .wav, .ogg, .flac, .aac, .m4a, and others.
The filename in your script must match the actual file exactly (including extension).
SpeakerID: (( This line is an inner thought. ))
Wrapping dialogue in double parentheses marks it as an inner thought. Inner thought lines are voiced with a special filtering effect configured in Tab 4 (Dissociated, Whisper, or Dreamlike presets, or Custom). The filter runs on top of all the speaker's regular effects.
[laughter]on a dialogue line triggers AI-generated laughter at that point.[brackets]generally pass through to Sonic-3 unchanged. They are stripped from the reference sheet text.<angle bracket SSML tags>pass through to the API unchanged.**bold**,_italic_, and~~strikethrough~~markers are stripped before TTS (Sonic-3 does not interpret these).//after dialogue text starts an inline comment; everything after it is stripped. A space before//is required (so URLs are not accidentally stripped).
Cartesia API — Enter your API key here. Voices load automatically once a valid key is saved. Use "View Usage Dashboard" to open play.cartesia.ai and check your credit usage.
Pronunciation Dict ID — Optional. Create a pronunciation dictionary at play.cartesia.ai to fix mispronounced words or proper names. Paste the dictionary ID here and it will be applied to every generation request.
Silence Trim — Controls how leading/trailing silence is removed from each TTS clip. Default: trim beginning and end. Options: Off, Beginning only, End only, Beginning + End, All silence.
Merged Audio Pauses — Adjust the pause duration added after each punctuation type (period, comma, exclamation, question, hyphen, ellipsis, etc.).
Contextual Modifiers — Fine-tune how pause lengths are modified by context: speaker changes, short lines, long lines, inner thought padding, same-speaker reduction, first/last line padding.
Inner Thoughts Effect — Choose from Whisper, Dreamlike, Dissociated presets or configure custom highpass/lowpass/echo parameters for the inner thought audio filter.
| Effect | Description |
|---|---|
| Radio Filter | Walkie-talkie / comms radio effect. Bandpass + phaser + compression. |
| Reverb | Spatial depth. Configurable echo chains. |
| Distortion | Aggressive, gritty clipping and bit crushing. |
| Telephone | Lo-fi compressed sound. Narrow bandpass + bit crushing. |
| Robot Voice | Ring modulator for mechanical / robotic character. |
| Cheap Mic | Degraded quality, poor recording simulation. |
| Underwater | Muffled, wet, submerged sound. Lowpass + flanger. |
| Megaphone | Projected bullhorn. Treble-boosted, punchy, bandpassed. |
| Worn Tape | VHS/cassette degradation. Wow-flutter, lo-fi analog warble. |
| Intercom | Hallway speaker box. Flat, compressed, confined. Adds crackling static noise. |
| Alien Voice | Non-human vocal quality. Three variants: Insectoid, Dimensional, Warble. |
| Cave | Physical stone space reverb. Three variants: Tunnel, Cave, Abyss. |
| Pitch Shift | FFMPEG rubberband pitch shift. Multiplier ×0.5–×2.0. Works independently of speed. |
Most effects have Off / Mild / Medium / Strong presets. Alien and Cave use named variants instead. Effects are combinable.
-
Best expressive voices — Leo, Jace, Kyle, Gavin, Maya, Tessa, Dana, Marian are Cartesia's most emotive voices. They sit at the top of the voice list in Tab 2. Start here for emotional scenes.
-
Match emotion to content — The Emotion dropdown in Tab 2 guides Sonic-3's delivery. Mismatched emotion (e.g.
excitedon sad dialogue) degrades output. Neutral is always safe. -
Use
[laughter]— Sonic-3 generates natural-sounding laughter inline. Drop[laughter]anywhere in a line. It's one of Sonic-3's best features — use it freely. -
<break>for mid-sentence pauses — Use<break time="0.8s"/>inside a line for a pause within the sentence. Use(1.5)on its own line for silence between lines. They're different tools. -
Per-line emotion overrides — Use
{emotion: X}after a SpeakerID to change emotion for one line. Useful for a character who shifts from calm to angry mid-scene. -
<spell>for acronyms — Wrap any string in<spell>TEXT</spell>to have Sonic-3 read it letter by letter. Useful for callsigns, acronyms, or IDs. -
Pitch for pitch shifting — The pitch slider in Tab 2 uses FFMPEG rubberband pitch shifting. It is independent of speaking speed.
-
Test each voice before generating everything. The Test Voice button in Tab 2 saves a preview clip and opens it immediately.
-
Cheap Mic at Mild is a subtle effect that adds a hint of realism. Worth trying as a default.
-
Prompt templates — The
!docs/prompt_templates/folder has templates for using AI chatbots to write scripts or generate voice line banks. Open them in any text editor.
| File | Contents |
|---|---|
!docs/guides/Script_Writing_Guide.md |
Writing for Sonic-3 TTS, pacing, SSML tags, laughter, emotion system, AI-assisted workflow |
!docs/guides/Audio_Effects_Guide.md |
Full reference for all effects, preset levels, FFMPEG pipeline, Yell Impact, troubleshooting |
Ready-to-load .md script files — open any of them in Tab 1 to see the format in action.
| File | What it demonstrates |
|---|---|
example_tiny.md |
Minimal 2-line script |
example_small.md |
Short 2-character scene with SFX, pause, and comments |
example_full_drama.md |
Full multi-character drama with SFX channels, inner thoughts, and scene structure |
example_monologue.md |
Single narrator, no character interaction |
example_meditation.md |
Atmospheric piece with long pauses and inner thought lines |
example_oneliners.md |
Voice bank format — one character, many independent lines by category |
example_game_scenes.md |
Multi-scene game dialogue with tactical characters, SFX, and inner thoughts |
Fill-in-the-blank prompts for generating scripts with an AI chatbot. Copy, fill in characters/scenario, paste to a chatbot, save the output as a .md file, load in Tab 1.
| File | Use case |
|---|---|
cohesive_script.md |
Continuous scene — characters talk to each other |
separate_voice_lines.md |
Voice bank — independent lines per category |
game_scene_pack.md |
Single game scene with character roles, SFX, and inner thoughts |
narrator_monologue.md |
Single narrator — story, documentary, speech, essay |
podcast_interview.md |
Two-person host/guest conversation |
ambient_narration.md |
Slow, atmospheric, mood-driven spoken word |
No voices in Tab 2 — Check that your API key is entered and saved in Tab 4. The app fetches voices from Cartesia on startup. If the key is invalid or missing, the voice list will be empty.
FFMPEG not found — Install FFMPEG and make sure it is in your system PATH. Use the automatic installer at https://reactorcore.itch.io/ffmpeg-to-path-installer then restart the program.
Parse errors on load — The parse log in Tab 1 lists every error with line numbers. Fix them in your text editor and click Reload Script.
Voice too quiet — The post-effects normalization pass ensures consistent loudness. If a speaker still sounds quiet relative to others, their Level slider may be below 100%.
Missing voice lines in output — Check the generation log in Tab 3 for per-line errors. An API error or FFMPEG issue on a specific line will be noted.
Test Voice not opening — The file is saved to output_test/ in the program folder.
Open it manually if the auto-open fails.
Generation fails / API errors — Check your Cartesia credit balance at play.cartesia.ai. Verify that your API key is correct. The app will report the specific error in the generation log.
- Cartesia Sonic-3 TTS — Cloud TTS engine
- ttkbootstrap — Modern themed tkinter UI
- FFMPEG — Audio processing and merging
- Script to Voice Generator — By Reactorcore
Check out everything else I do: https://linktr.ee/reactorcore
