Custom Text Transforms
Text transforms let you preprocess text before it reaches the TTS engine. They run after slang expansion and pronunciation overrides — giving you the last say on what gets spoken.
Adding a Transform
const voice = new VoiceRouter({
runtime,
transforms: [myTransform],
});
A transform is a function: (text: string, ctx: TextTransformContext) => string
The context includes personaMode, so you can vary behavior by character mood.
Examples
Strip Markdown
const stripMarkdown = (text: string) => {
let t = text;
t = t.replace(/\*{1,3}([^*]+)\*{1,3}/g, '$1'); // bold/italic
t = t.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); // links
t = t.replace(/^#{1,6}\s+/gm, ''); // headers
t = t.replace(/`([^`]+)`/g, '$1'); // inline code
return t;
};
Collapse Excited Punctuation
const calmPunctuation = (text: string) => {
return text.replace(/([!?.]){2,}/g, '$1');
// "That's amazing!!!" -> "That's amazing!"
};
Persona-Aware Pacing
const addPacing = (text: string, ctx: { personaMode: string }) => {
if (ctx.personaMode === "calm") {
// Add breath pauses for a calm character
return text.replace(/\. /g, ". ... ");
}
return text;
};
Add to Router at Runtime
const unsub = voice.addTransform(myTransform);
// Later: unsub() to remove it
Transform Order
- Emoji stripping (built-in, emits
emotion_state) - Sentence chunking (built-in)
- Slang expansion
- Pronunciation overrides
- Your custom transforms (in array order)
- Deduplication check
- Sent to runtime