17 Commits

Author SHA1 Message Date
Jinhyeok Yang
4ae3de90e7 Add RobustSpeechFlow paper citation to README
Added a new section for the RobustSpeechFlow paper, including a summary and citation.
2026-05-22 11:15:09 +09:00
Yechan Yu
13535a7090 Merge pull request #149 from omarelkhal/docs/add-aftertone-built-with
docs: add Aftertone to Built with Supertonic
2026-05-21 11:25:13 +09:00
Yechan Yu
4a687ea7ea Merge pull request #143 from NgoQuocViet2001/ai/trending-readme-speed-arg
docs(readme): document `--speed` flag in Go/Rust/Java/Swift args tables
2026-05-21 10:01:45 +09:00
haeon
2b54f70a27 docs: mention Supertonic 3 managed services 2026-05-20 18:52:45 +09:00
Omar El Khal
f8270b660a docs: add Aftertone to Built with Supertonic
Aftertone is a separate MIT project that runs local post-reply TTS for
coding agents using Supertonic 3 ONNX weights from Hugging Face.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 03:52:46 +02:00
NgoQuocViet2001
83e9881f31 docs(readme): document --speed flag in Go/Rust/Java/Swift args tables
The --speed parameter was announced in each language README's
"Update News" entry dated 2025.11.19 and is already parsed by the
example code in every language ({go,rust,java,swift}/example_onnx.*),
but the "Available Arguments" reference table is missing the row in
4 of the 8 language READMEs. The Python, Node.js, C#, and C++ READMEs
already list it.

Add the missing row in each affected table, verbatim with the wording
already used in the other 4 READMEs:

  | --speed | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |

Go uses single-dash to match the surrounding rows in its own table.
2026-05-19 10:13:29 +07:00
haeon
67175af735 docs: mention Python HTTP server 2026-05-18 19:08:46 +09:00
haeon
98a301fc62 Update README for Supertonic 3 Voice Builder 2026-05-18 15:22:56 +09:00
Juheon
5379cc4e42 Merge pull request #114 from fbdp1202/docs/update-readme-supertonic-3
docs: revamp README for Supertonic 3
2026-05-16 18:24:10 +09:00
fbdp1202
26c1f17ee1 docs: annotate Quick Start with wav/duration shapes and soundfile alternative
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:35:33 +09:00
fbdp1202
912c54b435 fix: Supertonic 3 compatibility across all language examples
- README Quick Start: format `duration[0]` instead of the ndarray itself
  (numpy refuses `f"{ndarray:.2f}"`; matches official `dur[0]:.2f` pattern)
- py/example_pypi.py: print synthesized duration to mirror the docstring example
- Add `"na"` to AVAILABLE_LANGS / Languages.Available / availableLangs
  across all 11 runtimes (Python/Node/Web/Java/C++/C#/Go/Swift/Rust/Flutter/iOS)
  so the language-agnostic fallback advertised in the README actually passes
  per-runtime lang validation before being sent to the v3 ONNX duration predictor

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:22:42 +09:00
Yechan Yu
f8bd509733 Fix Docs url 2026-05-15 19:38:32 +09:00
fbdp1202
12cd844e2c docs: revamp README for Supertonic 3
- Move shields.io badges below banner, keep only latest v3 set
- Add Trendshift badge (centered)
- Add  Highlights section absorbing former "Why Supertonic?" content
- List 31 supported languages with `lang="na"` note for unknown-language input
- Rename runtime examples section to "Programming Language Support"
- Add Minimax-MLS-test detailed WER/CER table (collapsible) with VoxCPM2, OmniVoice, Qwen3-TTS, Supertonic 2/3; mark ar/hi/ja/ko as CER
- Add "Models & Versions" comparison table covering v1/v2/v3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:25:37 +09:00
haeon
0a98c9f127 supertonic 3 2026-05-06 23:09:06 +02:00
ANLGBOY
6fc89ea89e add voice builder 2026-01-22 19:09:06 +09:00
ANLGBOY
b7f677a765 add TLDRL 2026-01-15 14:32:03 +09:00
ANLGBOY
cf29a310f2 add chrome extension 2026-01-15 13:43:41 +09:00
49 changed files with 660 additions and 423 deletions

11
.gitignore vendored
View File

@@ -1,13 +1,11 @@
assets/*
assets/.git
assets/.gitignore
assets/.gitattributes
assets/
*.onnx
onnx
# Output files
results
results_v3_sdk/
# Python
__pycache__
@@ -21,6 +19,11 @@ __pycache__
venv/
ENV/
env/
.dotnet/
.m2/
.uv-cache/
.clang-module-cache/
.swift-home/
# Node.js
node_modules/

425
README.md
View File

@@ -1,81 +1,101 @@
# Supertonic — Lightning Fast, On-Device TTS
[![v2 Demo](https://img.shields.io/badge/🤗%20v2-Demo-yellow)](https://huggingface.co/spaces/Supertone/supertonic-2)
[![v2 Models](https://img.shields.io/badge/🤗%20v2-Models-blue)](https://huggingface.co/Supertone/supertonic-2)
[![v1 Demo](https://img.shields.io/badge/🤗%20v1%20(old)-Demo-lightgrey)](https://huggingface.co/spaces/Supertone/supertonic#interactive-demo)
[![v1 Models](https://img.shields.io/badge/🤗%20v1%20(old)-Models-lightgrey)](https://huggingface.co/Supertone/supertonic)
# Supertonic — Lightning Fast, On-Device, Accurate TTS
<p align="center">
<img src="img/supertonic_preview_0.1.jpg" alt="Supertonic Banner">
<img src="img/Supertonic3_HeroImage.png" alt="Supertonic 3 Banner">
</p>
**Supertonic** is a lightning-fast, on-device text-to-speech system designed for **extreme performance** with minimal computational overhead. Powered by ONNX Runtime, it runs entirely on your device—no cloud, no API calls, no privacy concerns.
[![GitHub | Official Repo](https://img.shields.io/badge/GitHub-Official%20Repo-black?logo=github)](https://github.com/supertone-inc/supertonic)
[![Models](https://img.shields.io/badge/🤗%20Hugging%20Face-Models-blue)](https://huggingface.co/Supertone/supertonic-3)
[![Runs Locally via WebGPU](https://img.shields.io/badge/🤗%20Hugging%20Face-Demo-yellow)](https://huggingface.co/spaces/Supertone/supertonic-3)
[![DemoPage | Audio Samples](https://img.shields.io/badge/DemoPage-Audio%20Samples-F5D90A?labelColor=0B0C0E)](https://supertonic3.github.io/)
[![Voice Builder | Cloning Demo](https://img.shields.io/badge/Voice%20Builder-Cloning%20Demo-3457D5?logo=soundcloud&logoColor=white)](https://supertonic.supertone.ai/voice-builder)
[![GitHub | Python Package](https://img.shields.io/badge/GitHub-Python%20Package-black?logo=github)](https://github.com/supertone-inc/supertonic-py)
[![Docs | Python PyPI](https://img.shields.io/badge/Docs-Python%20PyPI-blue?logo=readthedocs&logoColor=white)](https://supertone-inc.github.io/supertonic-py/)
<p align="center">
<a href="https://trendshift.io/repositories/15657" target="_blank"><img src="https://trendshift.io/api/badge/repositories/15657" alt="supertone-inc%2Fsupertonic | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
**Supertonic** is a lightning-fast, on-device multilingual text-to-speech system designed for local inference with minimal overhead. Powered by ONNX Runtime, it runs entirely on your device—no cloud, no API calls, no privacy concerns.
### ✨ Highlights
-**Blazingly Fast** — Low-latency, real-time synthesis across desktop, browser, mobile, and edge — fast enough to turn an entire webpage into audio in under a second
- 🌍 **31-Language Multilingual** — Synthesize directly from text across 31 languages, or pass `lang="na"` to let Supertonic process the text language-agnostically when you don't know the input language — no separate language adapters needed
- 🪶 **99M-Parameter Open-Weight Model** — A compact, fully open-weight checkpoint — a fraction of the size of 0.7B2B class open TTS systems — for smaller downloads, faster cold starts, and lower memory footprint
- 📱 **Edge-Device Ready** — Runs locally on desktop, mobile, browsers, and resource-constrained hardware like Raspberry Pi or e-readers, with zero network dependency, complete privacy, and no GPU required
- 🔊 **44.1kHz High-Quality Audio** — Outputs studio-grade 44.1kHz 16-bit WAV directly, ready for production playback without any external upsampler
- 🎭 **Expression Tags** — 10 inline tags (e.g. `<laugh>`, `<breath>`, `<sigh>`) bring natural human nuance into generated speech without prompt engineering or reference audio
- 🛠️ **Multi-Runtime SDKs** — Ready-to-use examples through ONNX Runtime across Python, Node.js, Browser (WebGPU), Java, C++, C#, Go, Swift, iOS, Rust, and Flutter
### 🌍 Supported Languages (31)
Arabic (`ar`), Bulgarian (`bg`), Croatian (`hr`), Czech (`cs`), Danish (`da`), Dutch (`nl`), English (`en`), Estonian (`et`), Finnish (`fi`), French (`fr`), German (`de`), Greek (`el`), Hindi (`hi`), Hungarian (`hu`), Indonesian (`id`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Latvian (`lv`), Lithuanian (`lt`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Slovak (`sk`), Slovenian (`sl`), Spanish (`es`), Swedish (`sv`), Turkish (`tr`), Ukrainian (`uk`), Vietnamese (`vi`)
> **Not sure which language your text is in?** Pass `lang="na"` and Supertonic will handle the input in a language-agnostic way — no explicit language tag required.
### 📰 Update News
- **2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
- **2026.05.20** - **Supertonic 3** is now officially supported in **[Supertone Play](https://play.supertone.ai/)** and the **[Supertone API](https://www.supertone.ai/ko/api)**. Visit Play or the API if you want a managed content creation workflow with diverse preset voices and zero-shot voice cloning.
- **2026.05.18** - Python SDK v1.3.1 adds **`supertonic serve`**, a local HTTP server with native `/v1/tts` and OpenAI-compatible `/v1/audio/speech` endpoints. See the [serve documentation](https://supertone-inc.github.io/supertonic-py/cli/serve/).
- **2026.05.18** - **[Voice Builder](https://supertonic.supertone.ai/voice-builder)** now supports **Supertonic 3**. Create a permanent custom voice profile for Supertonic and download version-specific JSON files for both Supertonic 2 and Supertonic 3. If you already created a Supertonic 2 voice, the matching Supertonic 3 JSON is now available from [My Page](https://supertonic.supertone.ai/my-page).
- **2026.04.29** - 🎉 **Supertonic 3** released with **31-language support**, improved reading accuracy, fewer repeat/skip failures, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
- **2026.01.22** - **[Voice Builder](https://supertonic.supertone.ai/voice-builder)** is now live! Turn your voice into a deployable, edge-native TTS with permanent ownership.
- **2026.01.06** - 🎉 **Supertonic 2** released with 5-language support. The v2 code path is preserved on the [`release/supertonic-2`](https://github.com/supertone-inc/supertonic/tree/release/supertonic-2) branch.
- **2025.12.10** - Added `supertonic` PyPI package! Install via `pip install supertonic`. For details, visit [supertonic-py documentation](https://supertone-inc.github.io/supertonic-py)
- **2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
- **2025.12.08** - Optimized ONNX models via [OnnxSlim](https://github.com/inisis/OnnxSlim) now available on [Hugging Face Models](https://huggingface.co/Supertone/supertonic)
- **2025.11.24** - Added Flutter SDK support with macOS compatibility
### Table of Contents
- [Demo](#demo)
- [Why Supertonic?](#why-supertonic)
- [Language Support](#language-support)
- [Getting Started](#getting-started)
- [Performance](#performance)
- [Built with Supertonic](#built-with-supertonic)
- [Citation](#citation)
- [License](#license)
## Demo
### Raspberry Pi
Watch Supertonic running on a **Raspberry Pi**, demonstrating on-device, real-time text-to-speech synthesis:
https://github.com/user-attachments/assets/ea66f6d6-7bc5-4308-8a88-1ce3e07400d2
### E-Reader
Experience Supertonic on an **Onyx Boox Go 6** e-reader in airplane mode, achieving an average RTF of 0.3× with zero network dependency:
https://github.com/user-attachments/assets/64980e58-ad91-423a-9623-78c2ffc13680
---
> 🎧 **Try it now**: Experience Supertonic in your browser with our [**Interactive Demo**](https://huggingface.co/spaces/Supertone/supertonic-2), or get started with pre-trained models from [**Hugging Face Hub**](https://huggingface.co/Supertone/supertonic-2)
## Quick Start
## Why Supertonic?
Install the Python SDK and generate speech immediately. On the first run, Supertonic downloads the model assets from Hugging Face automatically.
- **⚡ Blazingly Fast**: Generates speech up to **167× faster than real-time** on consumer hardware (M4 Pro)—unmatched by any other TTS system
- **🪶 Ultra Lightweight**: Only **66M parameters**, optimized for efficient on-device performance with minimal footprint
- **📱 On-Device Capable**: **Complete privacy** and **zero latency**—all processing happens locally on your device
- **🎨 Natural Text Handling**: Seamlessly processes numbers, dates, currency, abbreviations, and complex expressions without pre-processing
- **⚙️ Highly Configurable**: Adjust inference steps, batch processing, and other parameters to match your specific needs
- **🧩 Flexible Deployment**: Deploy seamlessly across servers, browsers, and edge devices with multiple runtime backends.
```bash
pip install supertonic
```
## Language Support
### Python
We provide ready-to-use TTS inference examples across multiple ecosystems:
```python
from supertonic import TTS
| Language/Platform | Path | Description |
|-------------------|------|-------------|
| [**Python**](py/) | `py/` | ONNX Runtime inference |
| [**Node.js**](nodejs/) | `nodejs/` | Server-side JavaScript |
| [**Browser**](web/) | `web/` | WebGPU/WASM inference |
| [**Java**](java/) | `java/` | Cross-platform JVM |
| [**C++**](cpp/) | `cpp/` | High-performance C++ |
| [**C#**](csharp/) | `csharp/` | .NET ecosystem |
| [**Go**](go/) | `go/` | Go implementation |
| [**Swift**](swift/) | `swift/` | macOS applications |
| [**iOS**](ios/) | `ios/` | Native iOS apps |
| [**Rust**](rust/) | `rust/` | Memory-safe systems |
| [**Flutter**](flutter/) | `flutter/` | Cross-platform apps |
# First run downloads the model from Hugging Face automatically.
tts = TTS(auto_download=True)
> For detailed usage instructions, please refer to the README.md in each language directory.
style = tts.get_voice_style(voice_name="M1")
text = "Supertonic is a lightning fast, on-device TTS system."
wav, duration = tts.synthesize(
text=text,
lang="en", # Language code (e.g., "en", "ko", "na" for language-agnostic)
voice_style=style, # Voice style object
total_steps=8, # Quality: 5 (low) to 12 (high), default 8 (medium)
speed=1.05, # Speed: 0.7 (slow) to 2.0 (fast)
)
# wav: numpy array of shape (1, num_samples,) with dtype=np.float32, sampled at 44100 Hz
# duration: numpy array of shape (1,) containing the duration of the generated audio in seconds
tts.save_audio(wav, "output.wav")
# import soundfile as sf
# sf.write("output.wav", wav.squeeze(), 44100)
print(f"Generated {duration[0]:.2f}s of audio")
```
### Local HTTP Server
The Python SDK can also run Supertonic as a local HTTP service. This is useful when you want to call Supertonic from tools that already speak HTTP, such as local agents, browser extensions, Electron apps, workflow automation tools, or OpenAI-compatible audio clients.
```bash
pip install 'supertonic[serve]'
supertonic serve --host 127.0.0.1 --port 7788
```
Once running, use the native `POST /v1/tts` endpoint or the OpenAI-compatible `POST /v1/audio/speech` endpoint. The server also exposes interactive OpenAPI docs at `http://127.0.0.1:7788/docs`. See the [supertonic-py serve guide](https://supertone-inc.github.io/supertonic-py/cli/serve/) for request examples, batch synthesis, and custom Voice Builder JSON import.
## Getting Started
@@ -95,18 +115,30 @@ Before running the examples, download the ONNX models and preset voices, and pla
> - Generic: see `https://git-lfs.com` for installers
```bash
git clone https://huggingface.co/Supertone/supertonic-2 assets
git lfs install
git clone https://huggingface.co/Supertone/supertonic-3 assets
```
### Quick Start
Some language examples need native runtimes:
- **Go**: install the ONNX Runtime C library. On macOS, `brew install onnxruntime` is enough; the Go example auto-detects Homebrew paths.
- **Java**: use a JDK, not just a JRE. On macOS, `brew install openjdk@17` works.
- **C#**: targets .NET 9 and allows major-version roll-forward, so .NET 9 or newer runtimes can run it.
Then run the Python example:
**Python Example** ([Details](py/))
```bash
cd py
uv sync
uv run example_onnx.py
```
This generates `outputs/output.wav` using the default preset voice.
### Other Runtime Examples
<details>
<summary><b>Run Supertonic in other languages and platforms</b></summary>
**Node.js Example** ([Details](nodejs/))
```bash
cd nodejs
@@ -170,95 +202,148 @@ cd ios/ExampleiOSApp
xcodegen generate
open ExampleiOSApp.xcodeproj
```
- In Xcode: Targets → ExampleiOSApp → Signing: select your Team
- Choose your iPhone as run destination → Build & Run
### Technical Details
- **Runtime**: ONNX Runtime for cross-platform inference (CPU-optimized; GPU mode is not tested)
- **Browser Support**: onnxruntime-web for client-side inference
- **Batch Processing**: Supports batch inference for improved throughput
- **Audio Output**: Outputs 16-bit WAV files
## Performance
We evaluated Supertonic's performance (with 2 inference steps) using two key metrics across input texts of varying lengths: Short (59 chars), Mid (152 chars), and Long (266 chars).
**Metrics:**
- **Characters per Second**: Measures throughput by dividing the number of input characters by the time required to generate audio. Higher is better.
- **Real-time Factor (RTF)**: Measures the time taken to synthesize audio relative to its duration. Lower is better (e.g., RTF of 0.1 means it takes 0.1 seconds to generate one second of audio).
### Characters per Second
| System | Short (59 chars) | Mid (152 chars) | Long (266 chars) |
|--------|-----------------|----------------|-----------------|
| **Supertonic** (M4 pro - CPU) | 912 | 1048 | 1263 |
| **Supertonic** (M4 pro - WebGPU) | 996 | 1801 | 2509 |
| **Supertonic** (RTX4090) | 2615 | 6548 | 12164 |
| `API` [ElevenLabs Flash v2.5](https://elevenlabs.io/docs/api-reference/text-to-speech/convert) | 144 | 209 | 287 |
| `API` [OpenAI TTS-1](https://platform.openai.com/docs/guides/text-to-speech) | 37 | 55 | 82 |
| `API` [Gemini 2.5 Flash TTS](https://ai.google.dev/gemini-api/docs/speech-generation) | 12 | 18 | 24 |
| `API` [Supertone Sona speech 1](https://docs.supertoneapi.com/en/api-reference/endpoints/text-to-speech) | 38 | 64 | 92 |
| `Open` [Kokoro](https://github.com/hexgrad/kokoro/) | 104 | 107 | 117 |
| `Open` [NeuTTS Air](https://github.com/neuphonic/neutts-air) | 37 | 42 | 47 |
> **Notes:**
> `API` = Cloud-based API services (measured from Seoul)
> `Open` = Open-source models
> Supertonic (M4 pro - CPU) and (M4 pro - WebGPU): Tested with ONNX
> Supertonic (RTX4090): Tested with PyTorch model
> Kokoro: Tested on M4 Pro CPU with ONNX
> NeuTTS Air: Tested on M4 Pro CPU with Q8-GGUF
### Real-time Factor
| System | Short (59 chars) | Mid (152 chars) | Long (266 chars) |
|--------|-----------------|----------------|-----------------|
| **Supertonic** (M4 pro - CPU) | 0.015 | 0.013 | 0.012 |
| **Supertonic** (M4 pro - WebGPU) | 0.014 | 0.007 | 0.006 |
| **Supertonic** (RTX4090) | 0.005 | 0.002 | 0.001 |
| `API` [ElevenLabs Flash v2.5](https://elevenlabs.io/docs/api-reference/text-to-speech/convert) | 0.133 | 0.077 | 0.057 |
| `API` [OpenAI TTS-1](https://platform.openai.com/docs/guides/text-to-speech) | 0.471 | 0.302 | 0.201 |
| `API` [Gemini 2.5 Flash TTS](https://ai.google.dev/gemini-api/docs/speech-generation) | 1.060 | 0.673 | 0.541 |
| `API` [Supertone Sona speech 1](https://docs.supertoneapi.com/en/api-reference/endpoints/text-to-speech) | 0.372 | 0.206 | 0.163 |
| `Open` [Kokoro](https://github.com/hexgrad/kokoro/) | 0.144 | 0.124 | 0.126 |
| `Open` [NeuTTS Air](https://github.com/neuphonic/neutts-air) | 0.390 | 0.338 | 0.343 |
<details>
<summary><b>Additional Performance Data (5-step inference)</b></summary>
<br>
**Characters per Second (5-step)**
| System | Short (59 chars) | Mid (152 chars) | Long (266 chars) |
|--------|-----------------|----------------|-----------------|
| **Supertonic** (M4 pro - CPU) | 596 | 691 | 850 |
| **Supertonic** (M4 pro - WebGPU) | 570 | 1118 | 1546 |
| **Supertonic** (RTX4090) | 1286 | 3757 | 6242 |
**Real-time Factor (5-step)**
| System | Short (59 chars) | Mid (152 chars) | Long (266 chars) |
|--------|-----------------|----------------|-----------------|
| **Supertonic** (M4 pro - CPU) | 0.023 | 0.019 | 0.018 |
| **Supertonic** (M4 pro - WebGPU) | 0.024 | 0.012 | 0.010 |
| **Supertonic** (RTX4090) | 0.011 | 0.004 | 0.002 |
In Xcode: Targets → ExampleiOSApp → Signing: select your Team, then choose your iPhone as run destination and build.
</details>
### Natural Text Handling
---
Supertonic is designed to handle complex, real-world text inputs that contain numbers, currency symbols, abbreviations, dates, and proper nouns.
### Technical Details
> 🎧 **View audio samples more easily**: Check out our [**Interactive Demo**](https://huggingface.co/spaces/Supertone/supertonic#text-handling) for a better viewing experience of all audio examples
- **Runtime**: ONNX Runtime for cross-platform inference
- **Browser Support**: onnxruntime-web for client-side inference
- **Batch Processing**: Supports batch inference for improved throughput
- **Audio Output**: Outputs 44.1kHz 16-bit WAV files
## Performance Highlights
Supertonic 3 is designed for practical on-device inference: compact enough to run locally, while staying competitive with much larger open TTS systems.
### Reading Accuracy
<p align="center">
<img src="img/metrics/s3_vs_measured_wer_range_voxcpm2.png" alt="Supertonic 3 reading accuracy compared with measured model ranges and VoxCPM2">
</p>
Evaluated on the **[Minimax-MLS-test](https://huggingface.co/datasets/MiniMaxAI/TTS-MLS-Test) benchmark**, Supertonic 3 stays within a competitive WER/CER range against much larger open TTS models such as VoxCPM2, while preserving a lightweight on-device deployment path. Asterisked languages (`*`) use CER; the others use WER.
<details>
<summary><b>📊 Detailed per-language results (WER / CER*)</b></summary>
<br>
| Lang | VoxCPM2 | OmniVoice | Qwen3-TTS | Supertonic 2 | **Supertonic 3** |
|---|:---:|:---:|:---:|:---:|:---:|
| arabic\* | 4.14 | 1.74 | — | — | **2.14** |
| czech | 23.73 | 2.40 | — | — | **3.02** |
| dutch | 0.84 | 0.77 | — | — | **1.47** |
| english | 2.11 | 2.02 | 2.25 | 2.52 | **2.06** |
| finnish | 2.29 | 3.94 | — | — | **5.40** |
| french | 4.41 | 4.74 | 3.82 | 5.09 | **4.89** |
| german | 0.85 | 0.96 | 0.52 | — | **0.86** |
| greek | 3.22 | 2.96 | — | — | **3.54** |
| hindi\* | 5.85 | 5.14 | — | — | **5.34** |
| indonesian | 1.25 | 1.67 | — | — | **1.34** |
| italian | 1.74 | 1.29 | 1.40 | — | **1.75** |
| japanese\* | 3.35 | 3.81 | 3.67 | — | **4.61** |
| korean\* | 4.70 | 3.22 | 4.07 | 3.65 | **3.26** |
| polish | 1.30 | 0.64 | — | — | **1.63** |
| portuguese | 1.74 | 1.40 | 1.21 | 1.52 | **2.48** |
| romanian | 22.39 | 2.29 | — | — | **2.19** |
| russian | 3.31 | 4.53 | 4.48 | — | **3.99** |
| spanish | 1.34 | 0.99 | 0.75 | 1.81 | **1.13** |
| turkish | 0.88 | 2.18 | — | — | **1.00** |
| ukrainian | 5.85 | 0.71 | — | — | **1.23** |
| vietnamese | 1.48 | 0.79 | — | — | **4.49** |
> Lower is better. `*` indicates CER (character error rate); all other rows use WER (word error rate). Dashes (`—`) indicate the model does not officially support the language or no result is available.
</details>
### Supertonic 2 to Supertonic 3
<p align="center">
<img src="img/metrics/supertonic2_vs_3_comparison.png" alt="Supertonic 2 and Supertonic 3 comparison">
</p>
Compared with Supertonic 2, Supertonic 3 reduces repeat and skip failures, improves speaker similarity across the shared-language set, and expands language coverage from 5 to 31 languages. It keeps the v2-compatible public ONNX interface, so existing integrations can move to v3 with the same inference contract.
### Runtime Footprint
<p align="center">
<img src="img/metrics/runtime_cpu_gpu_latency_memory.png" alt="Supertonic CPU runtime compared with GPU baselines">
</p>
Supertonic 3 runs fast on CPU, even compared with larger baselines measured on A100 GPU, and uses substantially less memory. The open-weight fixed-voice setting does not require a GPU, which makes local, browser, and edge deployment much easier.
### Model Size
<p align="center">
<img src="img/metrics/model_size_comparison.png" alt="Model size comparison">
</p>
At about 99M parameters across the public ONNX assets, Supertonic 3 is much smaller than 0.7B to 2B class open TTS systems. The smaller model size is a practical advantage for download size, startup time, and on-device inference.
## Voice Cloning
This open-weight repository focuses on fixed-voice, local TTS and does not include an official voice-cloning pipeline. If you want to bring your own voice to local Supertonic deployment, [Voice Builder](https://supertonic.supertone.ai/voice-builder) turns a short reference recording into version-specific JSON files for Supertonic 2 and Supertonic 3, so the same custom voice can move with you across supported Supertonic versions.
For a managed creation workflow, **Supertonic 3 is now officially available in [Supertone Play](https://play.supertone.ai/) and the [Supertone API](https://www.supertone.ai/ko/api)**. Use them when you want hosted content creation tools, diverse commercially usable preset voices, zero-shot voice cloning, or API-based integration without managing local model files. You can also listen to Supertonic 3 zero-shot samples on the [official showcase](https://supertonic3.github.io/).
## Demo
> **Try it now**: Experience Supertonic in your browser with our [**Interactive Demo**](https://huggingface.co/spaces/Supertone/supertonic-3), or get started with pre-trained models from [**Hugging Face Hub**](https://huggingface.co/Supertone/supertonic-3)
### Raspberry Pi
Watch Supertonic running on a **Raspberry Pi**, demonstrating on-device, real-time text-to-speech synthesis:
https://github.com/user-attachments/assets/ea66f6d6-7bc5-4308-8a88-1ce3e07400d2
### E-Reader
Experience Supertonic on an **Onyx Boox Go 6** e-reader in airplane mode, achieving an average RTF of 0.3× with zero network dependency:
https://github.com/user-attachments/assets/64980e58-ad91-423a-9623-78c2ffc13680
### Chrome Extension
Turns any webpage into audio in under one second, delivering lightning-fast, on-device text-to-speech with zero network dependency—free, private, and effortless:
https://github.com/user-attachments/assets/cc8a45fc-5c3e-4b2c-8439-a14c3d00d91c
## Programming Language Support
We provide ready-to-use TTS inference examples across multiple ecosystems:
| Language/Platform | Path | Description |
|-------------------|------|-------------|
| [**Python**](py/) | `py/` | ONNX Runtime inference |
| [**Node.js**](nodejs/) | `nodejs/` | Server-side JavaScript |
| [**Browser**](web/) | `web/` | WebGPU/WASM inference |
| [**Java**](java/) | `java/` | Cross-platform JVM |
| [**C++**](cpp/) | `cpp/` | High-performance C++ |
| [**C#**](csharp/) | `csharp/` | .NET ecosystem |
| [**Go**](go/) | `go/` | Go implementation |
| [**Swift**](swift/) | `swift/` | macOS applications |
| [**iOS**](ios/) | `ios/` | Native iOS apps |
| [**Rust**](rust/) | `rust/` | Memory-safe systems |
| [**Flutter**](flutter/) | `flutter/` | Cross-platform apps |
> For detailed usage instructions, please refer to the README.md in each language directory.
## Natural Text Handling
Supertonic is designed to handle complex, real-world text inputs that contain natural prose, punctuation, abbreviations, and proper nouns.
> 🎧 **View audio samples more easily**: Check out our [**Interactive Demo**](https://huggingface.co/spaces/Supertone/supertonic-3) for a better viewing experience of all audio examples
**Overview of Test Cases:**
| Category | Key Challenges | Supertonic | ElevenLabs | OpenAI | Gemini | Microsoft |
|:--------:|:--------------:|:----------:|:----------:|:------:|:------:|:---------:|
| Financial Expression | Decimal currency, abbreviated magnitudes (M, K), currency symbols, currency codes | ✅ | ❌ | ❌ | ❌ | ❌ |
| Time and Date | Time notation, abbreviated weekdays/months, date formats | ✅ | ❌ | ❌ | ❌ | ❌ |
| Phone Number | Area codes, hyphens, extensions (ext.) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Technical Unit | Decimal numbers with units, abbreviated technical notations | ✅ | ❌ | ❌ | ❌ | ❌ |
@@ -288,33 +373,7 @@ Supertonic is designed to handle complex, real-world text inputs that contain nu
</details>
<details>
<summary><b>Example 2: Time and Date</b></summary>
<br>
**Text:**
> "The train delay was announced at **4:45 PM** on **Wed, Apr 3, 2024** due to track maintenance."
**Challenges:**
- Time expression with PM notation (4:45 PM)
- Abbreviated weekday (Wed)
- Abbreviated month (Apr)
- Full date format (Apr 3, 2024)
**Audio Samples:**
| System | Result | Audio Sample |
|--------|--------|--------------|
| **Supertonic** | ✅ | [🎧 Play Audio](https://drive.google.com/file/d/1ehkZU8eiizBenG2DgR5tzBGQBvHS0Uaj/view?usp=sharing) |
| ElevenLabs Flash v2.5 | ❌ | [🎧 Play Audio](https://drive.google.com/file/d/1ta3r6jFyebmA-sT44l8EaEQcMLVmuOEr/view?usp=sharing) |
| OpenAI TTS-1 | ❌ | [🎧 Play Audio](https://drive.google.com/file/d/1sskmem9AzHAQ3Hv8DRSZoqX_pye-CXuU/view?usp=sharing) |
| Gemini 2.5 Flash TTS | ❌ | [🎧 Play Audio](https://drive.google.com/file/d/1zx9X8oMsLMXW0Zx_SURoqjju-By2yh_n/view?usp=sharing) |
| VibeVoice Realtime 0.5B | ❌ | [🎧 Play Audio](https://drive.google.com/file/d/1ZpGEstZr4hA0EdAWBMCUFFWuAkIpYsVh/view?usp=sharing) |
</details>
<details>
<summary><b>Example 3: Phone Number</b></summary>
<summary><b>Example 2: Phone Number</b></summary>
<br>
@@ -340,7 +399,7 @@ Supertonic is designed to handle complex, real-world text inputs that contain nu
</details>
<details>
<summary><b>Example 4: Technical Unit</b></summary>
<summary><b>Example 3: Technical Unit</b></summary>
<br>
@@ -371,16 +430,31 @@ Supertonic is designed to handle complex, real-world text inputs that contain nu
| Project | Description | Links |
|---------|-------------|-------|
| **TLDRL** | Free, on-device TTS extension for reading any webpage | [Chrome](https://chromewebstore.google.com/detail/tldrl-lightning-tts-power/mdbiaajonlkomihpcaffhkagodbcgbme) |
| **Read Aloud** | Open-source TTS browser extension | [Chrome](https://chromewebstore.google.com/detail/read-aloud-a-text-to-spee/hdhinadidafjejdhmfkjgnolgimiaplp) · [Edge](https://microsoftedge.microsoft.com/addons/detail/read-aloud-a-text-to-spe/pnfonnnmfjnpfgagnklfaccicnnjcdkm) · [GitHub](https://github.com/ken107/read-aloud) |
| **PageEcho** | E-Book reader app for iOS | [App Store](https://apps.apple.com/us/app/pageecho/id6755965837) |
| **VoiceChat** | On-device voice-to-voice LLM chatbot in the browser | [Demo](https://huggingface.co/spaces/RickRossTN/ai-voice-chat) · [GitHub](https://github.com/irelate-ai/voice-chat) |
| **OmniAvatar** | Talking avatar video generator from photo + speech | [Demo](https://huggingface.co/spaces/alexnasa/OmniAvatar) |
| **CopiloTTS** | Kotlin Multiplatform TTS SDK via ONNX Runtime | [GitHub](https://github.com/sigmadeltasoftware/CopiloTTS) |
| **Aftertone** | Local post-reply TTS for Cursor & Claude Code (Supertonic 3 ONNX, on-device daemon) | [GitHub](https://github.com/omarelkhal/aftertone) · [Demo](https://github.com/omarelkhal/aftertone/releases/download/demo-asset/demo.mp4) |
| **Voice Mixer** | PyQt5 tool for mixing and modifying voice styles | [GitHub](https://github.com/Topping1/Supertonic-Voice-Mixer) |
| **Supertonic MNN** | Lightweight library based on MNN (fp32/fp16/int8) | [GitHub](https://github.com/vra/supertonic-mnn) · [PyPI](https://pypi.org/project/supertonic-mnn/) |
| **Transformers.js** | Hugging Face's JS library with Supertonic support | [GitHub PR](https://github.com/huggingface/transformers.js/pull/1459) · [Demo](https://huggingface.co/spaces/webml-community/Supertonic-TTS-WebGPU) |
| **Pinokio** | 1-click localhost cloud for Mac, Windows, and Linux | [Pinokio](https://pinokio.co/) · [GitHub](https://github.com/SUP3RMASS1VE/SuperTonic-TTS) |
## Models & Versions
| | **Supertonic 3** | Supertonic 2 | Supertonic 1 |
|---|:---:|:---:|:---:|
| **Status** | 🟢 Latest | Stable | Legacy |
| **Parameters** | ~99M | ~66M | ~66M |
| **Languages** | 31 | 5 | 1 (en) |
| **Expression Tags** | ✅ 10 tags | — | — |
| **Code** | [main](https://github.com/supertone-inc/supertonic) | [release/supertonic-2](https://github.com/supertone-inc/supertonic/tree/release/supertonic-2) | — |
| **Weights** | [🤗 HF](https://huggingface.co/Supertone/supertonic-3) | [🤗 HF](https://huggingface.co/Supertone/supertonic-2) | [🤗 HF](https://huggingface.co/Supertone/supertonic) |
| **Interactive Demo** | [🤗 Space](https://huggingface.co/spaces/Supertone/supertonic-3) | [🤗 Space](https://huggingface.co/spaces/Supertone/supertonic-2) | [🤗 Space](https://huggingface.co/spaces/Supertone/supertonic#interactive-demo) |
| **Audio Samples** | [DemoPage](https://supertonic3.github.io/) | — | [DemoPage](https://supertonictts.github.io/) |
## Citation
The following papers describe the core technologies used in Supertonic. If you use this system in your research or find these techniques useful, please consider citing the relevant papers:
@@ -427,13 +501,28 @@ This paper describes the self-purification technique for training flow matching
}
```
### RobustSpeechFlow: Learning Robust Text-to-Speech Trajectories via Augmentation-based Contrastive Flow Matching
This paper describes the RobustSpeechFlow technique for improving the robustness and quality of text-to-speech generation by optimizing flow-matching trajectories against data variability
```bibtex
@misc{yang2026robustspeechflowlearningrobusttexttospeech,
title={RobustSpeechFlow: Learning Robust Text-to-Speech Trajectories via Augmentation-based Contrastive Flow Matching},
author={Jinhyeok Yang and Hyeongju Kim and Yechan Yu and Joon Byun and Frederik Bous and Juheon Lee},
year={2026},
eprint={2605.22083},
archivePrefix={arXiv},
primaryClass={cs.SD},
url={https://arxiv.org/abs/2605.22083},
}
```
## License
This project's sample code is released under the MIT License. - see the [LICENSE](https://github.com/supertone-inc/supertonic?tab=MIT-1-ov-file) for details.
The accompanying model is released under the OpenRAIL-M License. - see the [LICENSE](https://huggingface.co/Supertone/supertonic-2/blob/main/LICENSE) file for details.
The accompanying model is released under the OpenRAIL-M License. - see the [LICENSE](https://huggingface.co/Supertone/supertonic-3/blob/main/LICENSE) file for details.
This model was trained using PyTorch, which is licensed under the BSD 3-Clause License but is not redistributed with this project. - see the [LICENSE](https://docs.pytorch.org/FBGEMM/general/License.html) for details.
Copyright (c) 2026 Supertone Inc.

View File

@@ -4,7 +4,7 @@ High-performance text-to-speech inference using ONNX Runtime.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -51,8 +51,10 @@ vcpkg integrate install
## Building
```bash
cd cpp && mkdir build && cd build
cmake .. && cmake --build . --config Release
cd cpp
mkdir -p build && cd build
cmake ..
cmake --build . --config Release
./example_onnx
```
@@ -65,17 +67,17 @@ Run inference with default settings:
```
This will use:
- Voice style: `../assets/voice_styles/M1.json`
- Voice style: `../../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
Process multiple voice styles and texts at once:
```bash
./example_onnx \
--voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json \
--voice-style ../../assets/voice_styles/M1.json,../../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 좋아서 한참을 멈춰 서서 들었어요." \
--lang en,ko \
--batch
@@ -93,19 +95,19 @@ Increase denoising steps for better quality:
```bash
./example_onnx \
--total-step 10 \
--voice-style ../assets/voice_styles/M1.json \
--voice-style ../../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
For long texts, the system automatically chunks the text into manageable segments and generates a single audio file:
```bash
./example_onnx \
--voice-style ../assets/voice_styles/M1.json \
--voice-style ../../assets/voice_styles/M1.json \
--text "Once upon a time, in a small village nestled between rolling hills, there lived a young artist named Clara. Every morning, she would wake up before dawn to capture the first light of day. The golden rays streaming through her window inspired countless paintings. Her work was known throughout the region for its vibrant colors and emotional depth. People from far and wide came to see her gallery, and many said her paintings could tell stories that words never could."
```
@@ -121,19 +123,19 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str | `../assets/voice_styles/M1.json` | Voice style file path(s) (comma-separated for batch) |
| `--voice-style` | str | `../../assets/voice_styles/M1.json` | Voice style file path(s) (comma-separated for batch) |
| `--text` | str | (long default text) | Text(s) to synthesize (pipe-separated for batch) |
| `--lang` | str | `en` | Language(s) for text(s): `en`, `ko`, `es`, `pt`, `fr` (comma-separated for batch) |
| `--lang` | str | `en` | Language(s) for text(s); see the main README for all 31 codes (comma-separated for batch) |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (disables automatic text chunking) |
## Notes
- **Batch Processing**: The number of `--voice-style` files must match the number of `--text` entries
- **Multilingual Support**: Use `--lang` to specify language(s). Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify language(s). Available: 31 languages; see the main README for the full list
- **Long-Form Inference**: Without `--batch` flag, long texts are automatically chunked and combined into a single audio file with natural pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer

View File

@@ -8,11 +8,11 @@
namespace fs = std::filesystem;
struct Args {
std::string onnx_dir = "../assets/onnx";
int total_step = 5;
std::string onnx_dir = "../../assets/onnx";
int total_step = 8;
float speed = 1.05f;
int n_test = 4;
std::vector<std::string> voice_style = {"../assets/voice_styles/M1.json"};
std::vector<std::string> voice_style = {"../../assets/voice_styles/M1.json"};
std::vector<std::string> text = {
"This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
};

View File

@@ -12,7 +12,7 @@
using json = nlohmann::json;
// Available languages for multilingual TTS
const std::vector<std::string> AVAILABLE_LANGS = {"en", "ko", "es", "pt", "fr"};
const std::vector<std::string> AVAILABLE_LANGS = {"en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"};
// Global tensor buffers for memory management
static std::vector<std::vector<float>> g_tensor_buffers_float;
@@ -190,7 +190,7 @@ std::string UnicodeProcessor::preprocessText(const std::string& text, const std:
}
}
if (!valid_lang) {
throw std::runtime_error("Invalid language: " + lang + ". Available: en, ko, es, pt, fr");
throw std::runtime_error("Invalid language: " + lang + ". See AVAILABLE_LANGS for supported codes.");
}
// Wrap text with language tags
@@ -695,7 +695,7 @@ TextToSpeech::SynthesisResult TextToSpeech::call(
throw std::runtime_error("Single speaker text to speech only supports single style");
}
int max_len = (lang == "ko") ? 120 : 300;
int max_len = (lang == "ko" || lang == "ja") ? 120 : 300;
auto text_list = chunkText(text, max_len);
std::vector<float> wav_cat;
float dur_cat = 0.0f;

View File

@@ -10,11 +10,11 @@ namespace Supertonic
class Args
{
public bool UseGpu { get; set; } = false;
public string OnnxDir { get; set; } = "assets/onnx";
public int TotalStep { get; set; } = 5;
public string OnnxDir { get; set; } = "../assets/onnx";
public int TotalStep { get; set; } = 8;
public float Speed { get; set; } = 1.05f;
public int NTest { get; set; } = 4;
public List<string> VoiceStyle { get; set; } = new List<string> { "assets/voice_styles/M1.json" };
public List<string> VoiceStyle { get; set; } = new List<string> { "../assets/voice_styles/M1.json" };
public List<string> Text { get; set; } = new List<string>
{
"This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."

View File

@@ -13,7 +13,7 @@ namespace Supertonic
// Available languages for multilingual TTS
public static class Languages
{
public static readonly string[] Available = { "en", "ko", "es", "pt", "fr" };
public static readonly string[] Available = { "en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na" };
}
// ============================================================================
@@ -440,7 +440,7 @@ namespace Supertonic
throw new ArgumentException("Single speaker text to speech only supports single style");
}
int maxLen = lang == "ko" ? 120 : 300;
int maxLen = (lang == "ko" || lang == "ja") ? 120 : 300;
var textList = Helper.ChunkText(text, maxLen);
var wavCat = new List<float>();
float durCat = 0.0f;

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using `ExampleONNX.cs`.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -19,9 +19,11 @@ This guide provides examples for running TTS inference using `ExampleONNX.cs`.
## Installation
### Prerequisites
- .NET 9.0 SDK or later
- .NET 9.0 SDK/runtime, or a newer .NET runtime with major-version roll-forward
- [Download .NET SDK](https://dotnet.microsoft.com/download)
The project targets `net9.0` and sets `RollForward=Major`, so systems with only a newer runtime such as .NET 10 can still run the example.
### Install dependencies
```bash
dotnet restore
@@ -36,17 +38,17 @@ dotnet run
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
Process multiple voice styles and texts at once:
```bash
dotnet run -- \
--voice-style assets/voice_styles/M1.json,assets/voice_styles/F1.json \
--voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 좋아서 한참을 멈춰 서서 들었어요." \
--lang en,ko \
--batch
@@ -64,19 +66,19 @@ Increase denoising steps for better quality:
```bash
dotnet run -- \
--total-step 10 \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
For long texts, the system automatically chunks the text into manageable segments and generates a single audio file:
```bash
dotnet run -- \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Once upon a time, in a small village nestled between rolling hills, there lived a young artist named Clara. Every morning, she would wake up before dawn to capture the first light of day. The golden rays streaming through her window inspired countless paintings. Her work was known throughout the region for its vibrant colors and emotional depth. People from far and wide came to see her gallery, and many said her paintings could tell stories that words never could."
```
@@ -93,20 +95,20 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (not supported yet) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s) (comma-separated) |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s) (comma-separated) |
| `--text` | str+ | (long default text) | Text(s) to synthesize (pipe-separated: `|`) |
| `--lang` | str+ | `en` | Language(s) for text(s): `en`, `ko`, `es`, `pt`, `fr` (comma-separated) |
| `--lang` | str+ | `en` | Language(s) for text(s); see the main README for all 31 codes (comma-separated) |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (disables automatic text chunking) |
## Notes
- **Batch Processing**: The number of `--voice-style` files must match the number of `--text` entries
- **Multilingual Support**: Use `--lang` to specify language(s). Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify language(s). Available: 31 languages; see the main README for the full list
- **Long-Form Inference**: Without `--batch` flag, long texts are automatically chunked and combined into a single audio file with natural pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer
- **GPU Support**: GPU mode is not supported yet
@@ -134,4 +136,3 @@ csharp/
└── results/ # Output directory (created automatically)
```

View File

@@ -5,6 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<LangVersion>13.0</LangVersion>
<Nullable>enable</Nullable>
<RollForward>Major</RollForward>
</PropertyGroup>
<ItemGroup>
@@ -14,4 +15,3 @@
</Project>

View File

@@ -1,13 +1,13 @@
# Supertonic Flutter Example
This example demonstrates how to use Supertonic 2 in a Flutter application using ONNX Runtime.
This example demonstrates how to use Supertonic 3 in a Flutter application using ONNX Runtime.
> **Note:** This project uses the `flutter_onnxruntime` package ([https://pub.dev/packages/flutter_onnxruntime](https://pub.dev/packages/flutter_onnxruntime)). At the moment, only the macOS platform has been tested. Although the flutter_onnxruntime package supports several other platforms, they have not been tested in this project yet and may require additional verification.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -17,12 +17,7 @@ This example demonstrates how to use Supertonic 2 in a Flutter application using
## Multilingual Support
Supertonic 2 supports multiple languages. Select the appropriate language from the dropdown:
- **English (en)**: Default language
- **한국어 (ko)**: Korean
- **Español (es)**: Spanish
- **Português (pt)**: Portuguese
- **Français (fr)**: French
Supertonic 3 supports 31 languages. Select the appropriate language from the dropdown; see the main README for the full code list.
## Requirements
@@ -35,4 +30,3 @@ flutter clean
flutter pub get
flutter run -d macos
```

View File

@@ -12,7 +12,7 @@ final logger = Logger(
);
// Available languages for multilingual TTS
const List<String> availableLangs = ['en', 'ko', 'es', 'pt', 'fr'];
const List<String> availableLangs = ['en', 'ko', 'ja', 'ar', 'bg', 'cs', 'da', 'de', 'el', 'es', 'et', 'fi', 'fr', 'hi', 'hr', 'hu', 'id', 'it', 'lt', 'lv', 'nl', 'pl', 'pt', 'ro', 'ru', 'sk', 'sl', 'sv', 'tr', 'uk', 'vi', 'na'];
bool isValidLang(String lang) => availableLangs.contains(lang);
@@ -285,7 +285,7 @@ class TextToSpeech {
Future<Map<String, dynamic>> call(
String text, String lang, Style style, int totalStep,
{double speed = 1.05, double silenceDuration = 0.3}) async {
final maxLen = lang == 'ko' ? 120 : 300;
final maxLen = (lang == 'ko' || lang == 'ja') ? 120 : 300;
final chunks = _chunkText(text, maxLen: maxLen);
final langList = List.filled(chunks.length, lang);
List<double>? wavCat;

View File

@@ -14,7 +14,7 @@ class SupertonicApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Supertonic 2',
title: 'Supertonic 3',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
@@ -42,7 +42,7 @@ class _TTSPageState extends State<TTSPage> {
bool _isLoading = false;
bool _isGenerating = false;
String _status = 'Not initialized';
int _totalSteps = 5;
int _totalSteps = 8;
double _speed = 1.05;
String _selectedLang = 'en';
bool _isPlaying = false;
@@ -210,7 +210,7 @@ class _TTSPageState extends State<TTSPage> {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Supertonic 2'),
title: const Text('Supertonic 3'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
@@ -323,13 +323,10 @@ class _TTSPageState extends State<TTSPage> {
child: DropdownButton<String>(
value: _selectedLang,
isExpanded: true,
items: const [
DropdownMenuItem(value: 'en', child: Text('English')),
DropdownMenuItem(value: 'ko', child: Text('한국어')),
DropdownMenuItem(value: 'es', child: Text('Español')),
DropdownMenuItem(value: 'pt', child: Text('Português')),
DropdownMenuItem(value: 'fr', child: Text('Français')),
],
items: availableLangs
.map((lang) =>
DropdownMenuItem(value: lang, child: Text(lang)))
.toList(),
onChanged: _isLoading || _isGenerating
? null
: (value) => setState(() => _selectedLang = value!),

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using `example_onnx.go`.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -30,6 +30,8 @@ This project uses Go modules for dependency management.
brew install onnxruntime
```
The Go example auto-detects Homebrew ONNX Runtime paths on both Apple Silicon and Intel Macs.
**Linux:**
```bash
# Download ONNX Runtime from GitHub releases
@@ -48,7 +50,7 @@ go mod download
### Configure ONNX Runtime Library Path (Optional)
If the ONNX Runtime library is not in a standard location, set the environment variable:
If the ONNX Runtime library is not in a standard or Homebrew location, set the environment variable:
**Automatic Detection (Recommended):**
@@ -77,10 +79,10 @@ go run example_onnx.go helper.go
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
@@ -88,7 +90,7 @@ Process multiple voice styles and texts at once:
```bash
go run example_onnx.go helper.go \
--batch \
-voice-style "assets/voice_styles/M1.json,assets/voice_styles/F1.json" \
-voice-style "../assets/voice_styles/M1.json,../assets/voice_styles/F1.json" \
-text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요." \
-lang "en,ko"
```
@@ -104,12 +106,12 @@ Increase denoising steps for better quality:
```bash
go run example_onnx.go helper.go \
-total-step 10 \
-voice-style "assets/voice_styles/M1.json" \
-voice-style "../assets/voice_styles/M1.json" \
-text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
@@ -117,7 +119,7 @@ The system automatically chunks long texts into manageable segments, synthesizes
```bash
go run example_onnx.go helper.go \
-voice-style "assets/voice_styles/M1.json" \
-voice-style "../assets/voice_styles/M1.json" \
-text "This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues."
```
@@ -134,18 +136,19 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `-use-gpu` | flag | false | Use GPU for inference (default: CPU) |
| `-onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `-total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `-onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `-total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `-speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `-n-test` | int | 4 | Number of times to generate each sample |
| `-voice-style` | str | `assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `-voice-style` | str | `../assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `-text` | str | (long default text) | Text(s) to synthesize, pipe-separated |
| `-lang` | str | `en` | Language(s) for synthesis, comma-separated (en, ko, es, pt, fr) |
| `-lang` | str | `en` | Language(s) for synthesis, comma-separated; see the main README for all 31 codes |
| `-save-dir` | str | `results` | Output directory |
| `--batch` | flag | false | Enable batch mode (multiple text-style pairs, disables automatic chunking) |
## Notes
- **Multilingual Support**: Use `-lang` to specify the language for each text. Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `-lang` to specify the language for each text. Available: 31 languages; see the main README for the full list
- **Batch Processing**: When using `--batch`, the number of `-voice-style`, `-text`, and `-lang` entries must match
- **Automatic Chunking**: Without `--batch`, long texts are automatically split and concatenated with 0.3s pauses
- **Quality vs Speed**: Higher `-total-step` values produce better quality but take longer
@@ -162,4 +165,3 @@ Then run it:
```bash
./tts_example -voice-style "../assets/voice_styles/M1.json" -text "Hello world"
```

View File

@@ -28,17 +28,17 @@ func parseArgs() *Args {
args := &Args{}
flag.BoolVar(&args.useGPU, "use-gpu", false, "Use GPU for inference (default: CPU)")
flag.StringVar(&args.onnxDir, "onnx-dir", "assets/onnx", "Path to ONNX model directory")
flag.IntVar(&args.totalStep, "total-step", 5, "Number of denoising steps")
flag.StringVar(&args.onnxDir, "onnx-dir", "../assets/onnx", "Path to ONNX model directory")
flag.IntVar(&args.totalStep, "total-step", 8, "Number of denoising steps")
flag.Float64Var(&args.speed, "speed", 1.05, "Speech speed factor (higher = faster)")
flag.IntVar(&args.nTest, "n-test", 4, "Number of times to generate")
flag.StringVar(&args.saveDir, "save-dir", "results", "Output directory")
flag.BoolVar(&args.batch, "batch", false, "Enable batch mode (multiple text-style pairs)")
var voiceStyleStr, textStr, langStr string
flag.StringVar(&voiceStyleStr, "voice-style", "assets/voice_styles/M1.json", "Voice style file path(s), comma-separated")
flag.StringVar(&voiceStyleStr, "voice-style", "../assets/voice_styles/M1.json", "Voice style file path(s), comma-separated")
flag.StringVar(&textStr, "text", "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen.", "Text(s) to synthesize, pipe-separated")
flag.StringVar(&langStr, "lang", "en", "Language(s) for synthesis, comma-separated (en, ko, es, pt, fr)")
flag.StringVar(&langStr, "lang", "en", "Language(s) for synthesis, comma-separated")
flag.Parse()

View File

@@ -19,7 +19,7 @@ import (
)
// Available languages for multilingual TTS
var AvailableLangs = []string{"en", "ko", "es", "pt", "fr"}
var AvailableLangs = []string{"en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"}
// Config structures
type SpecProcessorConfig struct {
@@ -801,7 +801,7 @@ func (tts *TextToSpeech) _infer(textList []string, langList []string, style *Sty
// Call synthesizes speech from a single text with automatic chunking
func (tts *TextToSpeech) Call(text string, lang string, style *Style, totalStep int, speed float32, silenceDuration float32) ([]float32, float32, error) {
maxLen := 300
if lang == "ko" {
if lang == "ko" || lang == "ja" {
maxLen = 120
}
chunks := chunkText(text, maxLen)
@@ -919,18 +919,29 @@ func LoadTextToSpeech(onnxDir string, useGPU bool, cfg Config) (*TextToSpeech, e
// InitializeONNXRuntime initializes ONNX Runtime environment
func InitializeONNXRuntime() error {
libPath := os.Getenv("ONNXRUNTIME_LIB_PATH")
if libPath == "" {
candidates := []string{
"/opt/homebrew/opt/onnxruntime/lib/libonnxruntime.dylib",
"/usr/local/opt/onnxruntime/lib/libonnxruntime.dylib",
"/opt/homebrew/lib/libonnxruntime.dylib",
"/usr/local/lib/libonnxruntime.dylib",
"/usr/local/lib/libonnxruntime.so",
"/usr/lib/libonnxruntime.so",
}
for _, candidate := range candidates {
if _, err := os.Stat(candidate); err == nil {
libPath = candidate
break
}
}
if libPath == "" {
libPath = "/usr/local/lib/libonnxruntime.so"
if _, err := os.Stat("/usr/local/lib/libonnxruntime.dylib"); err == nil {
libPath = "/usr/local/lib/libonnxruntime.dylib"
} else if _, err := os.Stat("/usr/lib/libonnxruntime.so"); err == nil {
libPath = "/usr/lib/libonnxruntime.so"
}
}
ort.SetSharedLibraryPath(libPath)
if err := ort.InitializeEnvironment(); err != nil {
return fmt.Errorf("failed to initialize ONNX Runtime: %w\nHint: Set ONNXRUNTIME_LIB_PATH environment variable", err)
return fmt.Errorf("failed to initialize ONNX Runtime: %w\nHint: install ONNX Runtime (macOS: brew install onnxruntime) or set ONNXRUNTIME_LIB_PATH", err)
}
return nil
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 KiB

After

Width:  |  Height:  |  Size: 558 KiB

BIN
img/voicebuilder_img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

View File

@@ -12,7 +12,7 @@ struct ContentView: View {
Spacer()
VStack(spacing: 12) {
Text("Supertonic 2 iOS Demo")
Text("Supertonic 3 iOS Demo")
.font(.title2.weight(.semibold))
.foregroundColor(.primary)

View File

@@ -6,17 +6,71 @@ final class TTSService {
enum Language: String, CaseIterable {
case en = "en"
case ko = "ko"
case ja = "ja"
case ar = "ar"
case bg = "bg"
case cs = "cs"
case da = "da"
case de = "de"
case el = "el"
case es = "es"
case pt = "pt"
case et = "et"
case fi = "fi"
case fr = "fr"
case hi = "hi"
case hr = "hr"
case hu = "hu"
case id = "id"
case it = "it"
case lt = "lt"
case lv = "lv"
case nl = "nl"
case pl = "pl"
case pt = "pt"
case ro = "ro"
case ru = "ru"
case sk = "sk"
case sl = "sl"
case sv = "sv"
case tr = "tr"
case uk = "uk"
case vi = "vi"
case na = "na"
var displayName: String {
switch self {
case .en: return "English"
case .ko: return "한국어"
case .ja: return "日本語"
case .ar: return "العربية"
case .bg: return "Bulgarian"
case .cs: return "Czech"
case .da: return "Danish"
case .de: return "Deutsch"
case .el: return "Greek"
case .es: return "Español"
case .pt: return "Português"
case .et: return "Estonian"
case .fi: return "Finnish"
case .fr: return "Français"
case .hi: return "Hindi"
case .hr: return "Croatian"
case .hu: return "Hungarian"
case .id: return "Indonesian"
case .it: return "Italian"
case .lt: return "Lithuanian"
case .lv: return "Latvian"
case .nl: return "Dutch"
case .pl: return "Polish"
case .pt: return "Português"
case .ro: return "Romanian"
case .ru: return "Russian"
case .sk: return "Slovak"
case .sl: return "Slovenian"
case .sv: return "Swedish"
case .tr: return "Turkish"
case .uk: return "Ukrainian"
case .vi: return "Vietnamese"
case .na: return "Auto (language-agnostic)"
}
}
}

View File

@@ -4,7 +4,7 @@ import AVFoundation
@MainActor
final class TTSViewModel: ObservableObject {
@Published var text: String = "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
@Published var nfe: Double = 5
@Published var nfe: Double = 8
@Published var voice: TTSService.Voice = .male
@Published var language: TTSService.Language = .en
@Published var isGenerating: Bool = false

View File

@@ -1,10 +1,10 @@
# Supertonic iOS Example App
A minimal iOS demo that runs Supertonic 2 (ONNX Runtime) on-device. The app shows:
A minimal iOS demo that runs Supertonic 3 (ONNX Runtime) on-device. The app shows:
- Multiline text input
- NFE (denoising steps) slider
- Voice toggle (M/F)
- Language selector (en, ko, es, pt, fr)
- Language selector for 31 supported languages
- Generate & Play buttons
- RTF display (Elapsed / Audio seconds)
@@ -12,7 +12,7 @@ All ONNX models/configs are reused from `Supertonic/assets/onnx`, and voice styl
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -61,18 +61,13 @@ These references are defined in `project.yml` and added to the app bundle by Xco
## App Controls
- **Text**: Multiline `TextEditor`
- **NFE**: Denoising steps (default 5)
- **NFE**: Denoising steps (default 8)
- **Voice**: M/F voice style selector
- **Language**: Language selector (English, 한국어, Español, Português, Français)
- **Language**: Language selector for 31 supported languages
- **Generate**: Runs end-to-end synthesis
- **Play/Stop**: Controls playback of the last output
- **RTF**: Shows Elapsed / Audio seconds for quick performance intuition
## Multilingual Support
Supertonic 2 supports multiple languages. Select the appropriate language for your input text:
- **English (en)**: Default language
- **한국어 (ko)**: Korean
- **Español (es)**: Spanish
- **Português (pt)**: Portuguese
- **Français (fr)**: French
Supertonic 3 supports 31 languages. Select the appropriate language for your input text; see the main README for the full code list.

View File

@@ -13,11 +13,11 @@ public class ExampleONNX {
*/
static class Args {
boolean useGpu = false;
String onnxDir = "assets/onnx";
int totalStep = 5;
String onnxDir = "../assets/onnx";
int totalStep = 8;
float speed = 1.05f;
int nTest = 4;
List<String> voiceStyle = Arrays.asList("assets/voice_styles/M1.json");
List<String> voiceStyle = Arrays.asList("../assets/voice_styles/M1.json");
List<String> text = Arrays.asList(
"This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
);

View File

@@ -22,7 +22,7 @@ import java.util.regex.Matcher;
* Available languages for multilingual TTS
*/
class Languages {
public static final List<String> AVAILABLE = Arrays.asList("en", "ko", "es", "pt", "fr");
public static final List<String> AVAILABLE = Arrays.asList("en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na");
public static boolean isValid(String lang) {
return AVAILABLE.contains(lang);
@@ -450,7 +450,7 @@ class TextToSpeech {
*/
public TTSResult call(String text, String lang, Style style, int totalStep, float speed, float silenceDuration, OrtEnvironment env)
throws OrtException {
int maxLen = lang.equals("ko") ? 120 : 300;
int maxLen = (lang.equals("ko") || lang.equals("ja")) ? 120 : 300;
List<String> chunks = Helper.chunkText(text, maxLen);
List<Float> wavCat = new ArrayList<>();
@@ -952,4 +952,3 @@ public class Helper {
return result;
}
}

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using `ExampleONNX.java`.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -22,9 +22,17 @@ This project uses [Maven](https://maven.apache.org/) for dependency management.
### Prerequisites
- Java 11 or higher
- Java Development Kit (JDK) 11 or higher, not just a JRE
- Maven 3.6 or higher
On macOS with Homebrew:
```bash
brew install openjdk@17 maven
export JAVA_HOME="$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home"
export PATH="$(brew --prefix openjdk@17)/bin:$PATH"
```
### Install dependencies
```bash
@@ -40,16 +48,16 @@ mvn exec:java
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
Process multiple voice styles and texts at once:
```bash
mvn exec:java -Dexec.args="--batch --voice-style assets/voice_styles/M1.json,assets/voice_styles/F1.json --text 'The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요.' --lang en,ko"
mvn exec:java -Dexec.args="--batch --voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json --text 'The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요.' --lang en,ko"
```
This will:
@@ -61,18 +69,18 @@ This will:
### Example 3: High Quality Inference
Increase denoising steps for better quality:
```bash
mvn exec:java -Dexec.args="--total-step 10 --voice-style assets/voice_styles/M1.json --text 'Increasing the number of denoising steps improves the output fidelity and overall quality.'"
mvn exec:java -Dexec.args="--total-step 10 --voice-style ../assets/voice_styles/M1.json --text 'Increasing the number of denoising steps improves the output fidelity and overall quality.'"
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
The system automatically chunks long texts into manageable segments, synthesizes each segment separately, and concatenates them with natural pauses (0.3 seconds by default) into a single audio file. This happens by default when you don't use the `--batch` flag:
```bash
mvn exec:java -Dexec.args="--voice-style assets/voice_styles/M1.json --text 'This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues.'"
mvn exec:java -Dexec.args="--voice-style ../assets/voice_styles/M1.json --text 'This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues.'"
```
This will:
@@ -110,21 +118,21 @@ java -jar target/tts-example.jar --total-step 10 --text "Your custom text here"
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (default: CPU) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `--text` | str+ | (long default text) | Text(s) to synthesize, pipe-separated |
| `--lang` | str+ | `en` | Language(s) for synthesis, comma-separated (en, ko, es, pt, fr) |
| `--lang` | str+ | `en` | Language(s) for synthesis, comma-separated; see the main README for all 31 codes |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (multiple text-style pairs, disables automatic chunking) |
## Notes
- **Multilingual Support**: Use `--lang` to specify the language for each text. Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify the language for each text. Available: 31 languages; see the main README for the full list
- **Batch Processing**: When using `--batch`, the number of `--voice-style`, `--text`, and `--lang` entries must match
- **Automatic Chunking**: Without `--batch`, long texts are automatically split and concatenated with 0.3s pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer
- **GPU Support**: GPU mode is not supported yet
- **Voice Styles**: Uses pre-extracted voice style JSON files for fast inference

View File

@@ -4,7 +4,7 @@ Node.js implementation for TTS inference. Uses ONNX Runtime to generate speech f
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -33,7 +33,7 @@ npm install
### Example 1: Default Inference
Run inference with default settings:
```bash
npm start
node example_onnx.js
```
Or:
@@ -42,17 +42,17 @@ node example_onnx.js
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
Process multiple voice styles and texts at once:
```bash
node example_onnx.js \
--voice-style "assets/voice_styles/M1.json,assets/voice_styles/F1.json" \
--voice-style "../assets/voice_styles/M1.json,../assets/voice_styles/F1.json" \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 좋아서 한참을 멈춰 서서 들었어요." \
--lang "en,ko" \
--batch
@@ -70,19 +70,19 @@ Increase denoising steps for better quality:
```bash
node example_onnx.js \
--total-step 10 \
--voice-style "assets/voice_styles/M1.json" \
--voice-style "../assets/voice_styles/M1.json" \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
For long texts, the system automatically chunks the text into manageable segments and generates a single audio file:
```bash
node example_onnx.js \
--voice-style "assets/voice_styles/M1.json" \
--voice-style "../assets/voice_styles/M1.json" \
--text "Once upon a time, in a small village nestled between rolling hills, there lived a young artist named Clara. Every morning, she would wake up before dawn to capture the first light of day. The golden rays streaming through her window inspired countless paintings. Her work was known throughout the region for its vibrant colors and emotional depth. People from far and wide came to see her gallery, and many said her paintings could tell stories that words never could."
```
@@ -99,20 +99,20 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (not supported yet) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s). Separate multiple files with commas |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s). Separate multiple files with commas |
| `--text` | str+ | (long default text) | Text(s) to synthesize. Separate multiple texts with pipes |
| `--lang` | str+ | `en` | Language(s) for text(s): `en`, `ko`, `es`, `pt`, `fr`. Separate multiple with commas |
| `--lang` | str+ | `en` | Language(s) for text(s); see the main README for all 31 codes. Separate multiple with commas |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (disables automatic text chunking) |
## Notes
- **Batch Processing**: The number of voice style files must match the number of texts. Use commas to separate files and pipes to separate texts
- **Multilingual Support**: Use `--lang` to specify language(s). Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify language(s). Available: 31 languages; see the main README for the full list
- **Long-Form Inference**: Without `--batch` flag, long texts are automatically chunked and combined into a single audio file with natural pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer
- **GPU Support**: GPU mode is not supported yet

View File

@@ -13,11 +13,11 @@ const __dirname = path.dirname(__filename);
function parseArgs() {
const args = {
useGpu: false,
onnxDir: 'assets/onnx',
totalStep: 5,
onnxDir: '../assets/onnx',
totalStep: 8,
speed: 1.05,
nTest: 4,
voiceStyle: ['assets/voice_styles/M1.json'],
voiceStyle: ['../assets/voice_styles/M1.json'],
text: ['This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen.'],
lang: ['en'],
saveDir: 'results',

View File

@@ -5,7 +5,7 @@ import * as ort from 'onnxruntime-node';
const __filename = fileURLToPath(import.meta.url);
const AVAILABLE_LANGS = ["en", "ko", "es", "pt", "fr"];
const AVAILABLE_LANGS = ["en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"];
/**
* Unicode text processor
@@ -275,7 +275,7 @@ class TextToSpeech {
if (style.ttl.dims[0] !== 1) {
throw new Error('Single speaker text to speech only supports single style');
}
const maxLen = lang === 'ko' ? 120 : 300;
const maxLen = (lang === 'ko' || lang === 'ja') ? 120 : 300;
const textList = chunkText(text, maxLen);
let wavCat = null;
let durCat = 0;

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using `example_onnx.py`.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added `supertonic` PyPI package! Install via `pip install supertonic` for a streamlined experience. This is a separate usage method from the ONNX examples in this directory. For more details, visit [supertonic-py documentation](https://supertone-inc.github.io/supertonic-py) and see `example_pypi.py` for usage.
@@ -46,17 +46,17 @@ uv run example_onnx.py
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
Process multiple voice styles and texts at once:
```bash
uv run example_onnx.py \
--voice-style assets/voice_styles/M1.json assets/voice_styles/F1.json \
--voice-style ../assets/voice_styles/M1.json ../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange." "오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 좋아서 한참을 멈춰 서서 들었어요." \
--lang en ko \
--batch
@@ -74,19 +74,19 @@ Increase denoising steps for better quality:
```bash
uv run example_onnx.py \
--total-step 10 \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
For long texts, the system automatically chunks the text into manageable segments and generates a single audio file:
```bash
uv run example_onnx.py \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Once upon a time, in a small village nestled between rolling hills, there lived a young artist named Clara. Every morning, she would wake up before dawn to capture the first light of day. The golden rays streaming through her window inspired countless paintings. Her work was known throughout the region for its vibrant colors and emotional depth. People from far and wide came to see her gallery, and many said her paintings could tell stories that words never could."
```
@@ -103,13 +103,13 @@ Control the speed of speech synthesis:
```bash
# Faster speech (speed > 1.0)
uv run example_onnx.py \
--voice-style assets/voice_styles/F2.json \
--voice-style ../assets/voice_styles/F2.json \
--text "This text will be synthesized at a faster pace." \
--speed 1.2
# Slower speech (speed < 1.0)
uv run example_onnx.py \
--voice-style assets/voice_styles/M2.json \
--voice-style ../assets/voice_styles/M2.json \
--text "This text will be synthesized at a slower, more deliberate pace." \
--speed 0.9
```
@@ -125,20 +125,20 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (with CPU fallback) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s) |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s) |
| `--text` | str+ | (long default text) | Text(s) to synthesize |
| `--lang` | str+ | `en` | Language(s) for text(s): `en`, `ko`, `es`, `pt`, `fr` |
| `--lang` | str+ | `en` | Language(s) for text(s); see the main README for all 31 codes |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (disables automatic text chunking) |
## Notes
- **Batch Processing**: The number of `--voice-style` files must match the number of `--text` entries
- **Multilingual Support**: Use `--lang` to specify language(s). Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify language(s). Available: 31 languages; see the main README for the full list
- **Long-Form Inference**: Without `--batch` flag, long texts are automatically chunked and combined into a single audio file with natural pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer
- **GPU Support**: GPU mode is not supported yet

View File

@@ -18,13 +18,13 @@ def parse_args():
parser.add_argument(
"--onnx-dir",
type=str,
default="assets/onnx",
default="../assets/onnx",
help="Path to ONNX model directory",
)
# Synthesis parameters
parser.add_argument(
"--total-step", type=int, default=5, help="Number of denoising steps"
"--total-step", type=int, default=8, help="Number of denoising steps"
)
parser.add_argument(
"--speed",
@@ -44,7 +44,7 @@ def parse_args():
"--voice-style",
type=str,
nargs="+",
default=["assets/voice_styles/M1.json"],
default=["../assets/voice_styles/M1.json"],
help="Voice style file path(s). Can specify multiple files for batch processing",
)
parser.add_argument(

View File

@@ -14,3 +14,4 @@ wav, duration = tts.synthesize(text, voice_style=style)
# Save to file
tts.save_audio(wav, "results/example_pypi.wav")
print(f"Generated {duration[0]:.2f}s of audio")

View File

@@ -10,7 +10,7 @@ import onnxruntime as ort
import re
AVAILABLE_LANGS = ["en", "ko", "es", "pt", "fr"]
AVAILABLE_LANGS = ["en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"]
class UnicodeProcessor:
@@ -226,7 +226,7 @@ class TextToSpeech:
assert (
style.ttl.shape[0] == 1
), "Single speaker text to speech only supports single style"
max_len = 120 if lang == "ko" else 300
max_len = 120 if lang in ("ko", "ja") else 300
text_list = chunk_text(text, max_len=max_len)
wav_cat = None
dur_cat = None

View File

@@ -8,7 +8,7 @@ edition = "2021"
ort = "2.0.0-rc.7"
# Array processing (like NumPy)
ndarray = { version = "0.16", features = ["rayon"] }
ndarray = { version = "0.17", features = ["rayon"] }
rand = "0.8"
rand_distr = "0.4"
@@ -41,4 +41,3 @@ libc = "0.2"
[[bin]]
name = "example_onnx"
path = "src/example_onnx.rs"

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using Rust.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -47,10 +47,10 @@ cargo run --release --bin example_onnx
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
@@ -59,14 +59,14 @@ Process multiple voice styles and texts at once:
# Using cargo run
cargo run --release --bin example_onnx -- \
--batch \
--voice-style assets/voice_styles/M1.json,assets/voice_styles/F1.json \
--voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요." \
--lang en,ko
# Or using the binary directly
./target/release/example_onnx \
--batch \
--voice-style assets/voice_styles/M1.json,assets/voice_styles/F1.json \
--voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요." \
--lang en,ko
```
@@ -83,18 +83,18 @@ Increase denoising steps for better quality:
# Using cargo run
cargo run --release --bin example_onnx -- \
--total-step 10 \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
# Or using the binary directly
./target/release/example_onnx \
--total-step 10 \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
@@ -103,12 +103,12 @@ The system automatically chunks long texts into manageable segments, synthesizes
```bash
# Using cargo run
cargo run --release --bin example_onnx -- \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues."
# Or using the binary directly
./target/release/example_onnx \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues."
```
@@ -125,18 +125,19 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (default: CPU) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s), comma-separated |
| `--text` | str+ | (long default text) | Text(s) to synthesize, pipe-separated |
| `--lang` | str+ | `en` | Language(s) for synthesis, comma-separated (en, ko, es, pt, fr) |
| `--lang` | str+ | `en` | Language(s) for synthesis, comma-separated; see the main README for all 31 codes |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (multiple text-style pairs, disables automatic chunking) |
## Notes
- **Multilingual Support**: Use `--lang` to specify the language for each text. Available: `en` (English), `ko` (Korean), `es` (Spanish), `pt` (Portuguese), `fr` (French)
- **Multilingual Support**: Use `--lang` to specify the language for each text. Available: 31 languages; see the main README for the full list
- **Batch Processing**: When using `--batch`, the number of `--voice-style`, `--text`, and `--lang` entries must match
- **Automatic Chunking**: Without `--batch`, long texts are automatically split and concatenated with 0.3s pauses
- **Quality vs Speed**: Higher `--total-step` values produce better quality but take longer

View File

@@ -19,11 +19,11 @@ struct Args {
use_gpu: bool,
/// Path to ONNX model directory
#[arg(long, default_value = "assets/onnx")]
#[arg(long, default_value = "../assets/onnx")]
onnx_dir: String,
/// Number of denoising steps
#[arg(long, default_value = "5")]
#[arg(long, default_value = "8")]
total_step: usize,
/// Speech speed factor (higher = faster)
@@ -35,14 +35,14 @@ struct Args {
n_test: usize,
/// Voice style file path(s)
#[arg(long, value_delimiter = ',', default_values_t = vec!["assets/voice_styles/M1.json".to_string()])]
#[arg(long, value_delimiter = ',', default_values_t = vec!["../assets/voice_styles/M1.json".to_string()])]
voice_style: Vec<String>,
/// Text(s) to synthesize
#[arg(long, value_delimiter = '|', default_values_t = vec!["This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen.".to_string()])]
text: Vec<String>,
/// Language(s) for synthesis (en, ko, es, pt, fr)
/// Language(s) for synthesis; see the main README for all supported codes
#[arg(long, value_delimiter = ',', default_values_t = vec!["en".to_string()])]
lang: Vec<String>,

View File

@@ -15,7 +15,7 @@ use rand_distr::{Distribution, Normal};
use regex::Regex;
// Available languages for multilingual TTS
pub const AVAILABLE_LANGS: &[&str] = &["en", "ko", "es", "pt", "fr"];
pub const AVAILABLE_LANGS: &[&str] = &["en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"];
pub fn is_valid_lang(lang: &str) -> bool {
AVAILABLE_LANGS.contains(&lang)
@@ -688,7 +688,7 @@ impl TextToSpeech {
speed: f32,
silence_duration: f32,
) -> Result<(Vec<f32>, f32)> {
let max_len = if lang == "ko" { 120 } else { 300 };
let max_len = if lang == "ko" || lang == "ja" { 120 } else { 300 };
let chunks = chunk_text(text, Some(max_len));
let mut wav_cat: Vec<f32> = Vec::new();

View File

@@ -4,7 +4,7 @@ This guide provides examples for running TTS inference using `example_onnx`.
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -38,10 +38,10 @@ Run inference with default settings:
```
This will use:
- Voice style: `assets/voice_styles/M1.json`
- Voice style: `../assets/voice_styles/M1.json`
- Text: "This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."
- Output directory: `results/`
- Total steps: 5
- Total steps: 8
- Number of generations: 4
### Example 2: Batch Inference
@@ -49,7 +49,7 @@ Process multiple voice styles and texts at once:
```bash
.build/release/example_onnx \
--batch \
--voice-style assets/voice_styles/M1.json,assets/voice_styles/F1.json \
--voice-style ../assets/voice_styles/M1.json,../assets/voice_styles/F1.json \
--text "The sun sets behind the mountains, painting the sky in shades of pink and orange.|오늘 아침에 공원을 산책했는데, 새소리와 바람 소리가 너무 기분 좋았어요." \
--lang en,ko
```
@@ -65,12 +65,12 @@ Increase denoising steps for better quality:
```bash
.build/release/example_onnx \
--total-step 10 \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "Increasing the number of denoising steps improves the output's fidelity and overall quality."
```
This will:
- Use 10 denoising steps instead of the default 5
- Use 10 denoising steps instead of the default 8
- Produce higher quality output at the cost of slower inference
### Example 4: Long-Form Inference
@@ -78,7 +78,7 @@ The system automatically chunks long texts into manageable segments, synthesizes
```bash
.build/release/example_onnx \
--voice-style assets/voice_styles/M1.json \
--voice-style ../assets/voice_styles/M1.json \
--text "This is a very long text that will be automatically split into multiple chunks. The system will process each chunk separately and then concatenate them together with natural pauses between segments. This ensures that even very long texts can be processed efficiently while maintaining natural speech flow and avoiding memory issues."
```
@@ -95,24 +95,19 @@ This will:
| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `--use-gpu` | flag | False | Use GPU for inference (default: CPU) |
| `--onnx-dir` | str | `assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 5 | Number of denoising steps (higher = better quality, slower) |
| `--onnx-dir` | str | `../assets/onnx` | Path to ONNX model directory |
| `--total-step` | int | 8 | Number of denoising steps (higher = better quality, slower) |
| `--speed` | float | 1.05 | Speech speed factor (higher = faster, lower = slower) |
| `--n-test` | int | 4 | Number of times to generate each sample |
| `--voice-style` | str+ | `assets/voice_styles/M1.json` | Voice style file path(s) |
| `--voice-style` | str+ | `../assets/voice_styles/M1.json` | Voice style file path(s) |
| `--text` | str+ | (long default text) | Text(s) to synthesize |
| `--lang` | str+ | `en` | Language(s) for synthesis (en, ko, es, pt, fr) |
| `--lang` | str+ | `en` | Language(s) for synthesis; see the main README for all 31 codes |
| `--save-dir` | str | `results` | Output directory |
| `--batch` | flag | False | Enable batch mode (multiple text-style-lang triplets, disables automatic chunking) |
## Multilingual Support
Supertonic 2 supports multiple languages. Use the `--lang` argument to specify the language:
- `en` - English (default)
- `ko` - Korean (한국어)
- `es` - Spanish (Español)
- `pt` - Portuguese (Português)
- `fr` - French (Français)
Supertonic 3 supports 31 languages. Use the `--lang` argument to specify the language; see the main README for the full code list.
## Notes

View File

@@ -3,11 +3,11 @@ import OnnxRuntimeBindings
struct Args {
var useGpu: Bool = false
var onnxDir: String = "assets/onnx"
var totalStep: Int = 5
var onnxDir: String = "../assets/onnx"
var totalStep: Int = 8
var speed: Float = 1.05
var nTest: Int = 4
var voiceStyle: [String] = ["assets/voice_styles/M1.json"]
var voiceStyle: [String] = ["../assets/voice_styles/M1.json"]
var text: [String] = ["This morning, I took a walk in the park, and the sound of the birds and the breeze was so pleasant that I stopped for a long time just to listen."]
var lang: [String] = ["en"]
var saveDir: String = "results"
@@ -32,7 +32,7 @@ func parseArgs() -> Args {
}
case "--total-step":
if i + 1 < arguments.count {
args.totalStep = Int(arguments[i + 1]) ?? 5
args.totalStep = Int(arguments[i + 1]) ?? 8
i += 1
}
case "--speed":

View File

@@ -4,7 +4,7 @@ import OnnxRuntimeBindings
// MARK: - Available Languages
let AVAILABLE_LANGS = ["en", "ko", "es", "pt", "fr"]
let AVAILABLE_LANGS = ["en", "ko", "ja", "ar", "bg", "cs", "da", "de", "el", "es", "et", "fi", "fr", "hi", "hr", "hu", "id", "it", "lt", "lv", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "tr", "uk", "vi", "na"]
func isValidLang(_ lang: String) -> Bool {
return AVAILABLE_LANGS.contains(lang)
@@ -701,7 +701,7 @@ class TextToSpeech {
}
func call(_ text: String, _ lang: String, _ style: Style, _ totalStep: Int, speed: Float = 1.05, silenceDuration: Float = 0.3) throws -> (wav: [Float], duration: Float) {
let maxLen = lang == "ko" ? 120 : 300
let maxLen = (lang == "ko" || lang == "ja") ? 120 : 300
let chunks = chunkText(text, maxLen: maxLen)
let langList = Array(repeating: lang, count: chunks.count)

View File

@@ -4,10 +4,16 @@
# This script runs inference tests for all supported languages except web
set -e # Exit on error
set -o pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
export UV_CACHE_DIR="${UV_CACHE_DIR:-$SCRIPT_DIR/.uv-cache}"
export CLANG_MODULE_CACHE_PATH="${CLANG_MODULE_CACHE_PATH:-$SCRIPT_DIR/.clang-module-cache}"
SWIFT_HOME="${SWIFT_HOME:-$SCRIPT_DIR/.swift-home}"
mkdir -p "$UV_CACHE_DIR" "$CLANG_MODULE_CACHE_PATH" "$SWIFT_HOME"
echo "=================================="
echo "Supertonic - Testing All Examples"
echo "=================================="
@@ -110,6 +116,28 @@ NC='\033[0m' # No Color
declare -a PASSED=()
declare -a FAILED=()
# Local toolchain fallbacks for Homebrew keg-only installs.
DOTNET_CMD="${DOTNET_CMD:-dotnet}"
if ! "$DOTNET_CMD" --list-runtimes 2>/dev/null | grep -q "Microsoft.NETCore.App 9\\."; then
if [ -x "/opt/homebrew/opt/dotnet@9/bin/dotnet" ]; then
DOTNET_CMD="/opt/homebrew/opt/dotnet@9/bin/dotnet"
export DOTNET_ROOT="${DOTNET_ROOT:-/opt/homebrew/opt/dotnet@9/libexec}"
elif [ -x "/usr/local/opt/dotnet@9/bin/dotnet" ]; then
DOTNET_CMD="/usr/local/opt/dotnet@9/bin/dotnet"
export DOTNET_ROOT="${DOTNET_ROOT:-/usr/local/opt/dotnet@9/libexec}"
fi
fi
if ! javac -version >/dev/null 2>&1; then
if [ -x "/opt/homebrew/opt/openjdk@17/bin/javac" ]; then
export JAVA_HOME="/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home"
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"
elif [ -x "/usr/local/opt/openjdk@17/bin/javac" ]; then
export JAVA_HOME="/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home"
export PATH="/usr/local/opt/openjdk@17/bin:$PATH"
fi
fi
# Helper function to show statistics
show_stats() {
local name=$1
@@ -181,10 +209,10 @@ if [ "$TEST_DEFAULT" = true ]; then
run_test "Python (default)" "py" "uv run example_onnx.py"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "Python (batch)" "py" "uv run example_onnx.py --batch --voice-style $BATCH_VOICE_STYLE_1 $BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1' '$BATCH_TEXT_2' --lang $BATCH_LANG_1 $BATCH_LANG_2"
run_test "Python (batch)" "py" "uv run example_onnx.py --batch --voice-style ../$BATCH_VOICE_STYLE_1 ../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1' '$BATCH_TEXT_2' --lang $BATCH_LANG_1 $BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "Python (long-form)" "py" "uv run example_onnx.py --voice-style $LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "Python (long-form)" "py" "uv run example_onnx.py --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -197,10 +225,10 @@ if [ "$TEST_DEFAULT" = true ]; then
run_test "JavaScript (default)" "nodejs" "node example_onnx.js"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "JavaScript (batch)" "nodejs" "node example_onnx.js --batch --voice-style $BATCH_VOICE_STYLE_1,$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "JavaScript (batch)" "nodejs" "node example_onnx.js --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "JavaScript (long-form)" "nodejs" "node example_onnx.js --voice-style $LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "JavaScript (long-form)" "nodejs" "node example_onnx.js --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -209,15 +237,20 @@ fi
echo -e "${YELLOW}Testing Go...${NC}"
echo "Cleaning Go cache..."
cd go && go clean && cd ..
export ONNXRUNTIME_LIB_PATH=$(brew --prefix onnxruntime 2>/dev/null)/lib/libonnxruntime.dylib
if [ -z "${ONNXRUNTIME_LIB_PATH:-}" ] && command -v brew >/dev/null 2>&1; then
ORT_PREFIX="$(brew --prefix onnxruntime 2>/dev/null || true)"
if [ -n "$ORT_PREFIX" ]; then
export ONNXRUNTIME_LIB_PATH="$ORT_PREFIX/lib/libonnxruntime.dylib"
fi
fi
if [ "$TEST_DEFAULT" = true ]; then
run_test "Go (default)" "go" "go run example_onnx.go helper.go"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "Go (batch)" "go" "go run example_onnx.go helper.go --batch -voice-style $BATCH_VOICE_STYLE_1,$BATCH_VOICE_STYLE_2 -text '$BATCH_TEXT_1|$BATCH_TEXT_2' -lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "Go (batch)" "go" "go run example_onnx.go helper.go --batch -voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 -text '$BATCH_TEXT_1|$BATCH_TEXT_2' -lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "Go (long-form)" "go" "go run example_onnx.go helper.go -voice-style $LONGFORM_VOICE_STYLE -text '$LONGFORM_TEXT'"
run_test "Go (long-form)" "go" "go run example_onnx.go helper.go -voice-style ../$LONGFORM_VOICE_STYLE -text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -230,10 +263,10 @@ if [ "$TEST_DEFAULT" = true ]; then
run_test "Rust (default)" "rust" "cargo run --release"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "Rust (batch)" "rust" "cargo run --release -- --batch --voice-style $BATCH_VOICE_STYLE_1,$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "Rust (batch)" "rust" "cargo run --release -- --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "Rust (long-form)" "rust" "cargo run --release -- --voice-style $LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "Rust (long-form)" "rust" "cargo run --release -- --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -241,15 +274,15 @@ fi
# ====================================
echo -e "${YELLOW}Testing C#...${NC}"
echo "Building C# project..."
cd csharp && dotnet clean && cd ..
cd csharp && DOTNET_CLI_HOME="$SCRIPT_DIR/.dotnet" "$DOTNET_CMD" clean && cd ..
if [ "$TEST_DEFAULT" = true ]; then
run_test "C# (default)" "csharp" "dotnet run --configuration Release"
run_test "C# (default)" "csharp" "DOTNET_CLI_HOME='$SCRIPT_DIR/.dotnet' '$DOTNET_CMD' run --configuration Release"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "C# (batch)" "csharp" "dotnet run --configuration Release -- --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "C# (batch)" "csharp" "DOTNET_CLI_HOME='$SCRIPT_DIR/.dotnet' '$DOTNET_CMD' run --configuration Release -- --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "C# (long-form)" "csharp" "dotnet run --configuration Release -- --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "C# (long-form)" "csharp" "DOTNET_CLI_HOME='$SCRIPT_DIR/.dotnet' '$DOTNET_CMD' run --configuration Release -- --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -257,15 +290,15 @@ fi
# ====================================
echo -e "${YELLOW}Testing Java...${NC}"
echo "Building Java project..."
cd java && mvn clean install -q && cd ..
cd java && mvn -Dmaven.repo.local="$SCRIPT_DIR/.m2/repository" clean install -q && cd ..
if [ "$TEST_DEFAULT" = true ]; then
run_test "Java (default)" "java" "mvn exec:java -q"
run_test "Java (default)" "java" "mvn -Dmaven.repo.local='$SCRIPT_DIR/.m2/repository' exec:java -q"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "Java (batch)" "java" "mvn exec:java -q -Dexec.args='--batch --voice-style $BATCH_VOICE_STYLE_1,$BATCH_VOICE_STYLE_2 --text \"$BATCH_TEXT_1|$BATCH_TEXT_2\" --lang $BATCH_LANG_1,$BATCH_LANG_2'"
run_test "Java (batch)" "java" "mvn -Dmaven.repo.local='$SCRIPT_DIR/.m2/repository' exec:java -q -Dexec.args='--batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text \"$BATCH_TEXT_1|$BATCH_TEXT_2\" --lang $BATCH_LANG_1,$BATCH_LANG_2'"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "Java (long-form)" "java" "mvn exec:java -q -Dexec.args='--voice-style $LONGFORM_VOICE_STYLE --text \"$LONGFORM_TEXT\"'"
run_test "Java (long-form)" "java" "mvn -Dmaven.repo.local='$SCRIPT_DIR/.m2/repository' exec:java -q -Dexec.args='--voice-style ../$LONGFORM_VOICE_STYLE --text \"$LONGFORM_TEXT\"'"
fi
# ====================================
@@ -273,15 +306,15 @@ fi
# ====================================
echo -e "${YELLOW}Testing Swift...${NC}"
echo "Building Swift project..."
cd swift && swift build -c release && cd ..
cd swift && HOME="$SWIFT_HOME" CLANG_MODULE_CACHE_PATH="$CLANG_MODULE_CACHE_PATH" swift build --disable-sandbox -c release && cd ..
if [ "$TEST_DEFAULT" = true ]; then
run_test "Swift (default)" "swift" ".build/release/example_onnx"
run_test "Swift (default)" "swift" "HOME='$SWIFT_HOME' CLANG_MODULE_CACHE_PATH='$CLANG_MODULE_CACHE_PATH' .build/release/example_onnx"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "Swift (batch)" "swift" ".build/release/example_onnx --batch --voice-style $BATCH_VOICE_STYLE_1,$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "Swift (batch)" "swift" "HOME='$SWIFT_HOME' CLANG_MODULE_CACHE_PATH='$CLANG_MODULE_CACHE_PATH' .build/release/example_onnx --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "Swift (long-form)" "swift" ".build/release/example_onnx --voice-style $LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "Swift (long-form)" "swift" "HOME='$SWIFT_HOME' CLANG_MODULE_CACHE_PATH='$CLANG_MODULE_CACHE_PATH' .build/release/example_onnx --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -289,15 +322,15 @@ fi
# ====================================
echo -e "${YELLOW}Testing C++...${NC}"
echo "Building C++ project..."
cd cpp && mkdir -p build && cd build && cmake .. && make && cd ../..
cmake -S cpp -B cpp/build && cmake --build cpp/build --config Release
if [ "$TEST_DEFAULT" = true ]; then
run_test "C++ (default)" "cpp/build" "./example_onnx"
fi
if [ "$TEST_BATCH" = true ]; then
run_test "C++ (batch)" "cpp/build" "./example_onnx --batch --voice-style ../$BATCH_VOICE_STYLE_1,../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
run_test "C++ (batch)" "cpp/build" "./example_onnx --batch --voice-style ../../$BATCH_VOICE_STYLE_1,../../$BATCH_VOICE_STYLE_2 --text '$BATCH_TEXT_1|$BATCH_TEXT_2' --lang $BATCH_LANG_1,$BATCH_LANG_2"
fi
if [ "$TEST_LONGFORM" = true ]; then
run_test "C++ (long-form)" "cpp/build" "./example_onnx --voice-style ../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
run_test "C++ (long-form)" "cpp/build" "./example_onnx --voice-style ../../$LONGFORM_VOICE_STYLE --text '$LONGFORM_TEXT'"
fi
# ====================================
@@ -327,4 +360,3 @@ else
echo -e "${GREEN}All tests passed! 🎉${NC}"
exit 0
fi

View File

@@ -4,7 +4,7 @@ This example demonstrates how to use Supertonic in a web browser using ONNX Runt
## 📰 Update News
**2026.01.06** - 🎉 **Supertonic 2** released with multilingual support! Now supports English (`en`), Korean (`ko`), Spanish (`es`), Portuguese (`pt`), and French (`fr`). [Demo](https://huggingface.co/spaces/Supertone/supertonic-2) | [Models](https://huggingface.co/Supertone/supertonic-2)
**2026.04.29** - 🎉 **Supertonic 3** released with 31-language support, improved reading accuracy, and v2-compatible public ONNX assets. [Demo](https://huggingface.co/spaces/Supertone/supertonic-3) | [Models](https://huggingface.co/Supertone/supertonic-3)
**2025.12.10** - Added [6 new voice styles](https://huggingface.co/Supertone/supertonic/tree/b10dbaf18b316159be75b34d24f740008fddd381) (M3, M4, M5, F3, F4, F5). See [Voices](https://supertone-inc.github.io/supertonic-py/voices/) for details
@@ -20,7 +20,7 @@ This example demonstrates how to use Supertonic in a web browser using ONNX Runt
- 🌐 Runs entirely in the browser (no server required for inference)
- 🚀 WebGPU support with automatic fallback to WebAssembly
- 🌍 Multilingual support: English (en), Korean (ko), Spanish (es), Portuguese (pt), French (fr)
- 🌍 Multilingual support: 31 languages
- ⚡ Pre-extracted voice styles for instant generation
- 🎨 Modern, responsive UI
- 🎭 Multiple voice style presets (5 Male, 5 Female)
@@ -58,14 +58,10 @@ This will start a local development server (usually at http://localhost:3000) an
- **Male 1-5 (M1-M5)**: Male voice styles
- **Female 1-5 (F1-F5)**: Female voice styles
3. **Select Language**: Choose the language that matches your input text
- **English (en)**: Default language
- **한국어 (ko)**: Korean
- **Español (es)**: Spanish
- **Português (pt)**: Portuguese
- **Français (fr)**: French
- Supertonic 3 supports 31 language codes; see the main README for the full list.
4. **Enter Text**: Type or paste the text you want to convert to speech
5. **Adjust Settings** (optional):
- **Total Steps**: More steps = better quality but slower (default: 5)
- **Total Steps**: More steps = better quality but slower (default: 8)
6. **Generate Speech**: Click the "Generate Speech" button
7. **View Results**:
- See the full input text
@@ -75,7 +71,7 @@ This will start a local development server (usually at http://localhost:3000) an
## Multilingual Support
Supertonic 2 supports multiple languages. Make sure to select the correct language for your input text to get the best results. The model will automatically handle text preprocessing and pronunciation for the selected language.
Supertonic 3 supports 31 languages. Make sure to select the correct language for your input text to get the best results. The model will automatically handle text preprocessing and pronunciation for the selected language.
## Technical Details

View File

@@ -1,7 +1,7 @@
import * as ort from 'onnxruntime-web';
// Available languages for multilingual TTS
export const AVAILABLE_LANGS = ['en', 'ko', 'es', 'pt', 'fr'];
export const AVAILABLE_LANGS = ['en', 'ko', 'ja', 'ar', 'bg', 'cs', 'da', 'de', 'el', 'es', 'et', 'fi', 'fr', 'hi', 'hr', 'hu', 'id', 'it', 'lt', 'lv', 'nl', 'pl', 'pt', 'ro', 'ru', 'sk', 'sl', 'sv', 'tr', 'uk', 'vi', 'na'];
export function isValidLang(lang) {
return AVAILABLE_LANGS.includes(lang);
@@ -272,7 +272,7 @@ export class TextToSpeech {
if (style.ttl.dims[0] !== 1) {
throw new Error('Single speaker text to speech only supports single style');
}
const maxLen = lang === 'ko' ? 120 : 300;
const maxLen = (lang === 'ko' || lang === 'ja') ? 120 : 300;
const textList = chunkText(text, maxLen);
const langList = new Array(textList.length).fill(lang);
let wavCat = [];

View File

@@ -3,13 +3,13 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Supertonic - Web Demo</title>
<title>Supertonic 3 - Web Demo</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div class="container">
<h1>🎤 Supertonic 2</h1>
<p class="subtitle">Multilingual Text-to-Speech with ONNX Runtime Web</p>
<h1>🎤 Supertonic 3</h1>
<p class="subtitle">31-language Text-to-Speech with ONNX Runtime Web</p>
<div id="statusBox" class="status-box">
<div class="status-text-wrapper">
@@ -46,9 +46,35 @@
<select id="langSelect">
<option value="en" selected>English (en)</option>
<option value="ko">한국어 (ko)</option>
<option value="ja">日本語 (ja)</option>
<option value="ar">العربية (ar)</option>
<option value="bg">Bulgarian (bg)</option>
<option value="cs">Czech (cs)</option>
<option value="da">Danish (da)</option>
<option value="de">Deutsch (de)</option>
<option value="el">Greek (el)</option>
<option value="es">Español (es)</option>
<option value="pt">Português (pt)</option>
<option value="et">Estonian (et)</option>
<option value="fi">Finnish (fi)</option>
<option value="fr">Français (fr)</option>
<option value="hi">Hindi (hi)</option>
<option value="hr">Croatian (hr)</option>
<option value="hu">Hungarian (hu)</option>
<option value="id">Indonesian (id)</option>
<option value="it">Italian (it)</option>
<option value="lt">Lithuanian (lt)</option>
<option value="lv">Latvian (lv)</option>
<option value="nl">Dutch (nl)</option>
<option value="pl">Polish (pl)</option>
<option value="pt">Português (pt)</option>
<option value="ro">Romanian (ro)</option>
<option value="ru">Russian (ru)</option>
<option value="sk">Slovak (sk)</option>
<option value="sl">Slovenian (sl)</option>
<option value="sv">Swedish (sv)</option>
<option value="tr">Turkish (tr)</option>
<option value="uk">Ukrainian (uk)</option>
<option value="vi">Vietnamese (vi)</option>
</select>
</div>
@@ -62,7 +88,7 @@
<div class="section">
<label for="totalStep">Total Steps (higher = better
quality):</label>
<input type="number" id="totalStep" value="5"
<input type="number" id="totalStep" value="8"
min="1" max="50">
</div>

View File

@@ -1,6 +1,38 @@
import { createReadStream, existsSync, statSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vite';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootAssetsDir = path.resolve(__dirname, '../assets');
function serveRootAssets() {
return {
name: 'serve-root-assets',
configureServer(server) {
server.middlewares.use('/assets', (req, res, next) => {
const urlPath = decodeURIComponent((req.url || '').split('?')[0]);
const filePath = path.resolve(rootAssetsDir, `.${urlPath}`);
if (!filePath.startsWith(rootAssetsDir) || !existsSync(filePath)) {
next();
return;
}
const stat = statSync(filePath);
if (!stat.isFile()) {
next();
return;
}
createReadStream(filePath).pipe(res);
});
}
};
}
export default defineConfig({
plugins: [serveRootAssets()],
server: {
port: 3000,
open: true