Add Pascal API and example for Supertonic TTS. - #3290
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds Supertonic English TTS support to the Pascal bindings: new Supertonic model config types, Pascal example program, run script, CI test step, and .gitignore entries; C-side config fields are populated from the new Pascal Supertonic config. Changes
Sequence Diagram(s)sequenceDiagram
participant Script as run-supertonic-en.sh
participant CI as GitHub Actions (pascal.yaml)
participant Build as Sherpa-ONNX Build/Install
participant Model as Supertonic Model (tarball)
participant Pascal as supertonic-en.pas
participant TTS as Sherpa-ONNX TTS runtime
participant FS as File System
CI->>Script: invoke run-supertonic-en.sh
Script->>Build: check/compile/install Sherpa-ONNX (CMake)
Script->>Model: download & extract model tarball
Script->>Pascal: compile `supertonic-en.pas` (fpc)
Script->>Pascal: set LD_LIBRARY_PATH / DYLD_LIBRARY_PATH
Script->>Pascal: execute `./supertonic-en`
Pascal->>TTS: Initialize TSherpaOnnxOfflineTts with Supertonic config
TTS->>Model: load Supertonic components (encoder, vocoder, etc.)
Pascal->>TTS: request generate audio from text
TTS->>FS: write WAV output (`supertonic-tts-en.wav`)
Script->>FS: cleanup `sherpa-onnx-supertonic-*`, `supertonic-en`
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces support for Supertonic TTS models to the sherpa-onnx Pascal API. It includes necessary code modifications to incorporate Supertonic models and provides an example for generating speech using the new API. This enhancement expands the TTS capabilities of sherpa-onnx. Highlights
Changelog
Ignored Files
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Pull request overview
Adds Pascal bindings and an executable example for running Sherpa-ONNX Offline TTS using Supertonic models.
Changes:
- Introduced Supertonic model config records in the Pascal API and wired them into the OfflineTts config marshaling.
- Added a Pascal example (
supertonic-en) plus a helper script to download models, build, and run it. - Updated CI and gitignore entries to build/run the new example and ignore the generated binary.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sherpa-onnx/pascal-api/sherpa_onnx.pas | Adds Supertonic config records, ToString, and marshaling into the C config. |
| pascal-api-examples/tts/supertonic-en.pas | New example program demonstrating Supertonic TTS usage. |
| pascal-api-examples/tts/run-supertonic-en.sh | New build/run script that downloads the Supertonic model and executes the example. |
| pascal-api-examples/tts/.gitignore | Ignores the newly built supertonic-en binary. |
| .github/workflows/pascal.yaml | Executes the new Supertonic example in CI and cleans up artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| class operator TSherpaOnnxOfflineTtsSupertonicModelConfig.Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Dest: TSherpaOnnxOfflineTtsSupertonicModelConfig); | ||
| begin | ||
| // No default initialization needed |
There was a problem hiding this comment.
This record contains managed fields (AnsiString). In Delphi/FPC, providing a custom class operator Initialize suppresses the compiler’s default initialization of managed fields; leaving it empty can result in invalid string reference counts and crashes/leaks on assignment/finalization. Initialize the fields explicitly (e.g., set each AnsiString to ''), or call the appropriate runtime initializer for the record before setting defaults.
| // No default initialization needed | |
| Dest.DurationPredictor := ''; | |
| Dest.TextEncoder := ''; | |
| Dest.VectorEstimator := ''; | |
| Dest.Vocoder := ''; | |
| Dest.TtsJson := ''; | |
| Dest.UnicodeIndexer := ''; | |
| Dest.VoiceStyle := ''; |
| SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
| SHERPA_ONNX_DIR=$(cd $SCRIPT_DIR/../.. && pwd) |
There was a problem hiding this comment.
Quote variable expansions to avoid word-splitting/globbing issues if the repository path contains spaces (e.g., cd \"$SCRIPT_DIR/../..\").
| kokoro-zh-en | ||
| kokoro-zh-en-playback | ||
| pocket-en | ||
| supertonic-en |
There was a problem hiding this comment.
The example script downloads and extracts a sherpa-onnx-supertonic-tts-* model directory under pascal-api-examples/tts/. Consider ignoring that extracted directory pattern as well to reduce the chance of accidentally committing large model artifacts (similar to how other example assets are typically handled).
| supertonic-en | |
| supertonic-en | |
| sherpa-onnx-supertonic-tts-* |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
pascal-api-examples/tts/supertonic-en.pas (1)
24-30: Extract model directory into a constant to reduce path drift risk.These repeated literals are easy to desync during version bumps.
♻️ Proposed refactor
function GetOfflineTts: TSherpaOnnxOfflineTts; var Config: TSherpaOnnxOfflineTtsConfig; +const + ModelDir = './sherpa-onnx-supertonic-tts-int8-2026-03-06'; begin - Config.Model.Supertonic.DurationPredictor := './sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx'; - Config.Model.Supertonic.TextEncoder := './sherpa-onnx-supertonic-tts-int8-2026-03-06/text_encoder.int8.onnx'; - Config.Model.Supertonic.VectorEstimator := './sherpa-onnx-supertonic-tts-int8-2026-03-06/vector_estimator.int8.onnx'; - Config.Model.Supertonic.Vocoder := './sherpa-onnx-supertonic-tts-int8-2026-03-06/vocoder.int8.onnx'; - Config.Model.Supertonic.TtsJson := './sherpa-onnx-supertonic-tts-int8-2026-03-06/tts.json'; - Config.Model.Supertonic.UnicodeIndexer := './sherpa-onnx-supertonic-tts-int8-2026-03-06/unicode_indexer.bin'; - Config.Model.Supertonic.VoiceStyle := './sherpa-onnx-supertonic-tts-int8-2026-03-06/voice.bin'; + Config.Model.Supertonic.DurationPredictor := ModelDir + '/duration_predictor.int8.onnx'; + Config.Model.Supertonic.TextEncoder := ModelDir + '/text_encoder.int8.onnx'; + Config.Model.Supertonic.VectorEstimator := ModelDir + '/vector_estimator.int8.onnx'; + Config.Model.Supertonic.Vocoder := ModelDir + '/vocoder.int8.onnx'; + Config.Model.Supertonic.TtsJson := ModelDir + '/tts.json'; + Config.Model.Supertonic.UnicodeIndexer := ModelDir + '/unicode_indexer.bin'; + Config.Model.Supertonic.VoiceStyle := ModelDir + '/voice.bin';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pascal-api-examples/tts/supertonic-en.pas` around lines 24 - 30, Introduce a single constant for the Supertonic model directory (e.g. SupertonicModelDir) and replace all repeated string literals used for Config.Model.Supertonic.* (DurationPredictor, TextEncoder, VectorEstimator, Vocoder, TtsJson, UnicodeIndexer, VoiceStyle) with path concatenations derived from that constant; update assignments in the file so each line uses the constant plus the filename (e.g. SupertonicModelDir + 'duration_predictor.int8.onnx') to centralize the directory value and avoid drift when bumping versions.pascal-api-examples/tts/run-supertonic-en.sh (1)
5-7: Anchor all file operations toSCRIPT_DIRto avoid CWD-dependent failures.
SCRIPT_DIRis computed, but model checks, tar extraction, compile input, and execution still depend on the caller’s current directory.♻️ Proposed fix
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) SHERPA_ONNX_DIR=$(cd $SCRIPT_DIR/../.. && pwd) +cd "$SCRIPT_DIR" @@ -if [ ! -f ./sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx ]; then +if [ ! -f "$SCRIPT_DIR/sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx" ]; then @@ -fpc \ +fpc \ -dSHERPA_ONNX_USE_SHARED_LIBS \ -Fu$SHERPA_ONNX_DIR/sherpa-onnx/pascal-api \ -Fl$SHERPA_ONNX_DIR/build/install/lib \ - ./supertonic-en.pas + "$SCRIPT_DIR/supertonic-en.pas" @@ -./supertonic-en +"$SCRIPT_DIR/supertonic-en"Also applies to: 28-31, 34-43
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pascal-api-examples/tts/run-supertonic-en.sh` around lines 5 - 7, The script computes SCRIPT_DIR but still performs file operations relative to the caller CWD; change all file/path usages (including SHERPA_ONNX_DIR assignment, model checks, tar extraction, compile inputs, and execution) to be anchored to SCRIPT_DIR by using either cd "$SCRIPT_DIR" at the top or by prefixing paths with "$SCRIPT_DIR/" (e.g., replace bare filenames and relative paths with "$SCRIPT_DIR/<path>"). Update the SHERPA_ONNX_DIR computation and every subsequent reference (tar extraction, model file checks, build/output paths, and program execution invocations) to use the anchored path so the script no longer depends on the current working directory.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pascal-api-examples/tts/run-supertonic-en.sh`:
- Around line 29-31: Replace the existing curl invocation "curl -SL -O
https://github.com/...sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2" with a
hardened curl command that fails on HTTP errors and bounds retries/timeouts
(e.g., add --fail --show-error --retry 3 --retry-delay 2 --connect-timeout 30
--max-time 1200) so the download exits non-zero on 4xx/5xx, retries transient
failures, and limits connection/total time; ensure the script still removes and
extracts the same tar file if the download succeeds.
---
Nitpick comments:
In `@pascal-api-examples/tts/run-supertonic-en.sh`:
- Around line 5-7: The script computes SCRIPT_DIR but still performs file
operations relative to the caller CWD; change all file/path usages (including
SHERPA_ONNX_DIR assignment, model checks, tar extraction, compile inputs, and
execution) to be anchored to SCRIPT_DIR by using either cd "$SCRIPT_DIR" at the
top or by prefixing paths with "$SCRIPT_DIR/" (e.g., replace bare filenames and
relative paths with "$SCRIPT_DIR/<path>"). Update the SHERPA_ONNX_DIR
computation and every subsequent reference (tar extraction, model file checks,
build/output paths, and program execution invocations) to use the anchored path
so the script no longer depends on the current working directory.
In `@pascal-api-examples/tts/supertonic-en.pas`:
- Around line 24-30: Introduce a single constant for the Supertonic model
directory (e.g. SupertonicModelDir) and replace all repeated string literals
used for Config.Model.Supertonic.* (DurationPredictor, TextEncoder,
VectorEstimator, Vocoder, TtsJson, UnicodeIndexer, VoiceStyle) with path
concatenations derived from that constant; update assignments in the file so
each line uses the constant plus the filename (e.g. SupertonicModelDir +
'duration_predictor.int8.onnx') to centralize the directory value and avoid
drift when bumping versions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6da59ba3-8b1a-4e4c-945c-1e780521bb38
📒 Files selected for processing (5)
.github/workflows/pascal.yamlpascal-api-examples/tts/.gitignorepascal-api-examples/tts/run-supertonic-en.shpascal-api-examples/tts/supertonic-en.passherpa-onnx/pascal-api/sherpa_onnx.pas
| curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | ||
| tar xvf sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | ||
| rm sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "run-supertonic-en.sh" -type fRepository: k2-fsa/sherpa-onnx
Length of output: 108
🏁 Script executed:
sed -n '29,31p' ./pascal-api-examples/tts/run-supertonic-en.shRepository: k2-fsa/sherpa-onnx
Length of output: 310
🌐 Web query:
curl -S flag behavior HTTP errors silent error handling
💡 Result:
-s, --silenthides the progress meter and error messages (but still prints the response body unless you redirect it). [1]-S, --show-erroronly matters when combined with-s: it re-enables printing an error message if curl fails. [1]- By default, HTTP 4xx/5xx are not “curl errors”—curl can return exit code
0even for404/500if the transfer succeeded. [2] - To make HTTP 4xx/5xx produce a non-zero exit code, use
-f, --fail(or--fail-with-body). [2] When curl exits non-zero it prints an error message unless--silentis used (and-sSis the common combo to stay quiet except on errors). [3]
Common “silent but fail on HTTP errors” pattern:
curl -fsS https://example.com/resourceSources: [1] curl man page (-s / -S) [2] curl FAQ on HTTP non-200 behavior and -f [3] everything.curl.dev on exit codes and --silent suppressing error output.
🌐 Web query:
curl --fail flag HTTP error codes differences
💡 Result:
- By default, curl returns exit code 0 even if the server replies with an HTTP error status (e.g., 404, 401). curl treats that as a successful transfer unless you tell it otherwise. [1]
-f, --fail: for HTTP status codes ≥ 400, curl exits non‑zero (specifically exit code 22) and suppresses the response body (“no output at all”); intended for scripts. Note: some non-success codes can “slip through,” especially with 401/407 in some auth scenarios. [2]--fail-with-body: same fail condition (HTTP ≥ 400) and exit code 22, but still outputs/saves the response body, which is useful for error details (JSON/HTML). [2]
So the key difference is: --fail hides the body; --fail-with-body keeps it—both fail on HTTP ≥ 400 with exit code 22. [2]
Harden model download: fail fast and bound network retries/timeouts.
The current curl -SL -O silently accepts HTTP errors (curl returns exit code 0 for 4xx/5xx responses by default) and has no retry/timeout limits, making downloads brittle in CI environments.
The proposed hardening adds:
--fail: exits non-zero on HTTP errors (≥400)--retry 3 --retry-delay 2: retries transient failures--connect-timeout 30 --max-time 1200: bounds network delays and total execution time
🛡️ Proposed hardening
- curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2
+ curl --fail --show-error --location \
+ --retry 3 --retry-delay 2 --connect-timeout 30 --max-time 1200 \
+ -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| tar xvf sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| rm sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| curl --fail --show-error --location \ | |
| --retry 3 --retry-delay 2 --connect-timeout 30 --max-time 1200 \ | |
| -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| tar xvf sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| rm sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pascal-api-examples/tts/run-supertonic-en.sh` around lines 29 - 31, Replace
the existing curl invocation "curl -SL -O
https://github.com/...sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2" with a
hardened curl command that fails on HTTP errors and bounds retries/timeouts
(e.g., add --fail --show-error --retry 3 --retry-delay 2 --connect-timeout 30
--max-time 1200) so the download exits non-zero on 4xx/5xx, retries transient
failures, and limits connection/total time; ensure the script still removes and
extracts the same tar file if the download succeeds.
There was a problem hiding this comment.
Code Review
This pull request adds support for the Supertonic TTS model to the Pascal API, including a new example. The changes look good, but I have a couple of suggestions to improve maintainability by reducing hardcoded, repeated strings in the new example files.
| if [ ! -f ./sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx ]; then | ||
| curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | ||
| tar xvf sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | ||
| rm sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | ||
| fi |
There was a problem hiding this comment.
The model name sherpa-onnx-supertonic-tts-int8-2026-03-06 is hardcoded and repeated multiple times. To improve maintainability and make it easier to update the model version in the future, consider defining it as a variable.
| if [ ! -f ./sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx ]; then | |
| curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| tar xvf sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| rm sherpa-onnx-supertonic-tts-int8-2026-03-06.tar.bz2 | |
| fi | |
| MODEL_DIR="sherpa-onnx-supertonic-tts-int8-2026-03-06" | |
| if [ ! -f ./$MODEL_DIR/duration_predictor.int8.onnx ]; then | |
| curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/$MODEL_DIR.tar.bz2 | |
| tar xvf $MODEL_DIR.tar.bz2 | |
| rm $MODEL_DIR.tar.bz2 | |
| fi |
| var | ||
| Config: TSherpaOnnxOfflineTtsConfig; | ||
| begin | ||
| Config.Model.Supertonic.DurationPredictor := './sherpa-onnx-supertonic-tts-int8-2026-03-06/duration_predictor.int8.onnx'; | ||
| Config.Model.Supertonic.TextEncoder := './sherpa-onnx-supertonic-tts-int8-2026-03-06/text_encoder.int8.onnx'; | ||
| Config.Model.Supertonic.VectorEstimator := './sherpa-onnx-supertonic-tts-int8-2026-03-06/vector_estimator.int8.onnx'; | ||
| Config.Model.Supertonic.Vocoder := './sherpa-onnx-supertonic-tts-int8-2026-03-06/vocoder.int8.onnx'; | ||
| Config.Model.Supertonic.TtsJson := './sherpa-onnx-supertonic-tts-int8-2026-03-06/tts.json'; | ||
| Config.Model.Supertonic.UnicodeIndexer := './sherpa-onnx-supertonic-tts-int8-2026-03-06/unicode_indexer.bin'; | ||
| Config.Model.Supertonic.VoiceStyle := './sherpa-onnx-supertonic-tts-int8-2026-03-06/voice.bin'; | ||
| Config.Model.NumThreads := 2; | ||
| Config.Model.Debug := True; | ||
| Config.MaxNumSentences := 1; |
There was a problem hiding this comment.
The model directory path './sherpa-onnx-supertonic-tts-int8-2026-03-06/' is hardcoded and repeated multiple times. To improve maintainability and make it easier to update the model version, you could define it as a constant and reuse it.
const
ModelDir = './sherpa-onnx-supertonic-tts-int8-2026-03-06/';
var
Config: TSherpaOnnxOfflineTtsConfig;
begin
Config.Model.Supertonic.DurationPredictor := ModelDir + 'duration_predictor.int8.onnx';
Config.Model.Supertonic.TextEncoder := ModelDir + 'text_encoder.int8.onnx';
Config.Model.Supertonic.VectorEstimator := ModelDir + 'vector_estimator.int8.onnx';
Config.Model.Supertonic.Vocoder := ModelDir + 'vocoder.int8.onnx';
Config.Model.Supertonic.TtsJson := ModelDir + 'tts.json';
Config.Model.Supertonic.UnicodeIndexer := ModelDir + 'unicode_indexer.bin';
Config.Model.Supertonic.VoiceStyle := ModelDir + 'voice.bin';
Config.Model.NumThreads := 2;
Config.Model.Debug := True;
Config.MaxNumSentences := 1;
Summary by CodeRabbit
New Features
Tests
Chores