Supertonic 3 Expression Tags: How to Use Text Shortcuts in Neural TTS
Supertonic 3 automatically expands three expression tags—@ to "at", e.g., to "for example,", and i.e., to "that is,"—during preprocessing before sending text to the neural TTS model.
Supertonic 3 by supertone-inc/supertonic is a neural text-to-speech engine that normalizes common textual shortcuts before tokenization. The library's UnicodeProcessor handles expression tags automatically across all language bindings, converting shorthand symbols into spoken words to improve pronunciation accuracy.
Available Expression Tags in Supertonic 3
The UnicodeProcessor (implemented in every language binding) recognizes three expression tags and expands them before the text reaches the neural model:
@→ expands toat(handles email addresses and social handles)e.g.,→ expands tofor example,(Latin abbreviation for exempli gratia)i.e.,→ expands tothat is,(Latin abbreviation for id est)
These mappings are defined in the expr_replacements dictionary (Python) or exprReplacements object (JavaScript) within each language binding's helper file.
How Expression Tags Work Internally
The expansion happens automatically during the preprocessing phase in the UnicodeProcessor class.
The Preprocessing Pipeline
According to the source code in py/helper.py (lines 69-77) and web/helper.js (lines 72-78), the processor executes these steps in order:
- Unicode Normalisation – Applies
NFKDnormalization to decompose characters. - Emoji and Punctuation Cleaning – Strips Unicode emoji ranges and replaces various punctuation marks.
- Expression Tag Replacement – Substitutes the three entries in
expr_replacements(orexprReplacements) with their expanded forms. - Language Wrapping – Wraps the cleaned string in
<lang>tags (e.g.,<en>text</en>), wherelangis one of the values inAVAILABLE_LANGS.
The language tags themselves are not expression tags; they are required model input format markers added after expression normalization (see the line text = f"<{lang}>" + text + f"</{lang}>" in the Python helper).
Using Expression Tags in Your Code
Because replacements are performed automatically by the UnicodeProcessor, you do not need manual preprocessing. Simply include the tags in your raw input text.
JavaScript (Web) Implementation
In web/helper.js, the UnicodeProcessor handles the expansion automatically:
import { loadTextToSpeech, loadVoiceStyle } from './helper.js';
// Load model assets (ONNX files, indexer, configurations)
const { textToSpeech } = await loadTextToSpeech('/onnx_dir');
// Load a voice style (optional)
const style = await loadVoiceStyle(['/styles/style1.json']);
// Input text containing expression tags
const raw = "Contact us @ support@example.com. e.g., we can help you. i.e., you will get a response.";
// Invoke TTS—the processor replaces tags automatically
const { wav } = await textToSpeech.call(
raw, // text with expression tags
'en', // language code
style, // voice style
50 // total diffusion steps
);
// wav contains the audio waveform ready for playback
Python Implementation
The Python implementation in py/helper.py provides identical functionality:
from py.helper import load_text_to_speech, load_voice_style
# Load model assets
tts = load_text_to_speech('/path/to/onnx')
# Load a voice style (optional)
style = load_voice_style(['/path/to/style.json'])
# Input text with expression tags
raw = "Send an email @ support@example.com. e.g., you can ask questions. i.e., we reply quickly."
# Synthesize speech—expression tags expand internally
wav, duration = tts(raw, 'en', style, total_step=50)
# wav is a NumPy array of PCM samples
Other Language Bindings
All Supertonic 3 language bindings expose a UnicodeProcessor (or equivalent) that runs the same replacement logic:
- Rust:
rust/src/helper.rs - Go:
go/helper.go(lines 384+) - Java:
java/Helper.java(lines 177+) - C++:
cpp/helper.cpp(lines 113+) - C#:
csharp/Helper.cs(lines 166+)
In each implementation, supply the raw string containing @, e.g.,, or i.e., directly to the TTS function. The processor substitutes these automatically before handing text to the model.
Expression Tag Implementation Files
The replacement logic is defined in these canonical source files across the supertone-inc/supertonic repository:
- JavaScript:
web/helper.js(lines 72-78) – contains theexprReplacementsmap - Python:
py/helper.py(lines 69-77) – implementsUnicodeProcessor._preprocess_textwithexpr_replacements - Rust:
rust/src/helper.rs– mirrors the same replacement logic - Go:
go/helper.go(lines 384+) – defines theexprReplacementstable - Java:
java/Helper.java(lines 177+) – identical expression tag handling - C++:
cpp/helper.cpp(lines 113+) – same mapping - C#:
csharp/Helper.cs(lines 166+) – same mapping
These files serve as the canonical source of truth for expression tag behavior across the entire Supertonic 3 codebase.
Summary
- Supertonic 3 supports three expression tags:
@,e.g.,, andi.e., - The
UnicodeProcessorautomatically expands these toat,for example,, andthat is,respectively - Replacement occurs during preprocessing in all language bindings (Python, JavaScript, Rust, Go, Java, C++, C#)
- No manual intervention required—simply include tags in raw input text
- Language wrapping tags (
<en>,<ja>, etc.) are separate from expression tags and added after normalization
Frequently Asked Questions
Do I need to manually preprocess text before sending it to Supertonic 3?
No. The UnicodeProcessor class handles expression tag expansion automatically during the preprocessing pipeline. Simply include @, e.g.,, or i.e., in your input string, and the library will replace them before tokenization.
Are language tags like <en> considered expression tags?
No. Language tags such as <en> and </en> are required model input format markers that wrap the entire text after expression normalization. They are distinct from expression tags and are added automatically by the processor.
Can I add custom expression tags to Supertonic 3?
The current implementation in web/helper.js and py/helper.py hardcodes only three expression tags (@, e.g.,, i.e.,) in the expr_replacements (or exprReplacements) dictionary. To add custom tags, you would need to modify the source code in the respective language binding.
Do all Supertonic 3 language bindings support the same expression tags?
Yes. All official language bindings—Python, JavaScript (Web), Rust, Go, Java, C++, and C#—implement identical UnicodeProcessor logic with the same three expression tag mappings, ensuring consistent behavior across platforms.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →