mirror of
https://github.com/k2-fsa/sherpa-onnx.git
synced 2026-11-10 21:11:03 +08:00
Dart, flutter, go, c-api blinding and example (#3202)
This commit is contained in:
1 parent
3b6442ffdc
commit
6293cc7e33
7 files changed
+68
-12
No files matched your search
@@ -49,6 +49,10 @@ int32_t main(int32_t argc, char *argv[]) {
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/vocab.json";
|
||||
config.model.pocket.token_scores_json =
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/token_scores.json";
|
||||
// Voice embedding cache capacity (default: 50)
|
||||
// Increase this if you have many different reference audios to avoid
|
||||
// recomputing voice embeddings
|
||||
config.model.pocket.voice_embedding_cache_capacity = 50;
|
||||
|
||||
config.model.num_threads = 2;
|
||||
|
||||
@@ -82,7 +86,10 @@ int32_t main(int32_t argc, char *argv[]) {
|
||||
cfg.reference_audio = wave->samples;
|
||||
cfg.reference_audio_len = wave->num_samples;
|
||||
cfg.reference_sample_rate = wave->sample_rate;
|
||||
cfg.extra = "{\"max_reference_audio_len\": 10.0}";
|
||||
// Extra parameters passed as JSON string
|
||||
// - max_reference_audio_len: maximum length of reference audio in seconds
|
||||
// - seed: random seed for reproducibility (optional, -1 for random)
|
||||
cfg.extra = "{\"max_reference_audio_len\": 10.0, \"seed\": 42}";
|
||||
|
||||
#if 0
|
||||
// If you don't want to use a callback, then please enable this branch
|
||||
|
||||
@@ -19,7 +19,17 @@ void main(List<String> arguments) async {
|
||||
..addOption('token-scores-json', help: 'Path to the token_scores.json file')
|
||||
..addOption('reference-audio', help: 'Path to reference audio (wav)')
|
||||
..addOption('text', help: 'Text to generate TTS for')
|
||||
..addOption('output-wav', help: 'Filename to save the generated audio');
|
||||
..addOption('output-wav', help: 'Filename to save the generated audio')
|
||||
..addOption(
|
||||
'voice-embedding-cache-capacity',
|
||||
help: 'Voice embedding cache capacity (default: 50)',
|
||||
defaultsTo: '50',
|
||||
)
|
||||
..addOption(
|
||||
'seed',
|
||||
help: 'Random seed for reproducibility (default: -1, random)',
|
||||
defaultsTo: '-1',
|
||||
);
|
||||
|
||||
final res = parser.parse(arguments);
|
||||
|
||||
@@ -47,6 +57,10 @@ void main(List<String> arguments) async {
|
||||
final referenceAudioPath = res['reference-audio'] as String;
|
||||
final text = res['text'] as String;
|
||||
final outputWav = res['output-wav'] as String;
|
||||
final voiceEmbeddingCacheCapacity = int.parse(
|
||||
res['voice-embedding-cache-capacity'] as String,
|
||||
);
|
||||
final seed = int.parse(res['seed'] as String);
|
||||
|
||||
// ---------------- Pocket model config ----------------
|
||||
final pocket = sherpa_onnx.OfflineTtsPocketModelConfig(
|
||||
@@ -57,6 +71,7 @@ void main(List<String> arguments) async {
|
||||
textConditioner: textConditioner,
|
||||
vocabJson: vocabJson,
|
||||
tokenScoresJson: tokenScoresJson,
|
||||
voiceEmbeddingCacheCapacity: voiceEmbeddingCacheCapacity,
|
||||
);
|
||||
|
||||
final modelConfig = sherpa_onnx.OfflineTtsModelConfig(
|
||||
@@ -80,7 +95,7 @@ void main(List<String> arguments) async {
|
||||
speed: 1.0,
|
||||
referenceAudio: wave.samples,
|
||||
referenceSampleRate: wave.sampleRate,
|
||||
extra: {"max_reference_audio_len": 12},
|
||||
extra: {"max_reference_audio_len": 12, if (seed >= 0) "seed": seed},
|
||||
);
|
||||
|
||||
// If you don't want to use a callback
|
||||
|
||||
@@ -243,6 +243,9 @@ final class SherpaOnnxOfflineTtsPocketModelConfig extends Struct {
|
||||
external Pointer<Utf8> textConditioner;
|
||||
external Pointer<Utf8> vocabJson;
|
||||
external Pointer<Utf8> tokenScoresJson;
|
||||
|
||||
@Int32()
|
||||
external int voiceEmbeddingCacheCapacity;
|
||||
}
|
||||
|
||||
final class SherpaOnnxOfflineTtsModelConfig extends Struct {
|
||||
|
||||
@@ -352,6 +352,7 @@ class OfflineTtsPocketModelConfig {
|
||||
this.textConditioner = '',
|
||||
this.vocabJson = '',
|
||||
this.tokenScoresJson = '',
|
||||
this.voiceEmbeddingCacheCapacity = 50,
|
||||
});
|
||||
|
||||
factory OfflineTtsPocketModelConfig.fromJson(Map<String, dynamic> json) {
|
||||
@@ -363,6 +364,8 @@ class OfflineTtsPocketModelConfig {
|
||||
textConditioner: json['textConditioner'] as String? ?? '',
|
||||
vocabJson: json['vocabJson'] as String? ?? '',
|
||||
tokenScoresJson: json['tokenScoresJson'] as String? ?? '',
|
||||
voiceEmbeddingCacheCapacity:
|
||||
json['voiceEmbeddingCacheCapacity'] as int? ?? 50,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -374,11 +377,12 @@ class OfflineTtsPocketModelConfig {
|
||||
'textConditioner': textConditioner,
|
||||
'vocabJson': vocabJson,
|
||||
'tokenScoresJson': tokenScoresJson,
|
||||
'voiceEmbeddingCacheCapacity': voiceEmbeddingCacheCapacity,
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'OfflineTtsPocketModelConfig(lmFlow: $lmFlow, lmMain: $lmMain, encoder: $encoder, decoder: $decoder, textConditioner: $textConditioner, vocabJson: $vocabJson, tokenScoresJson: $tokenScoresJson)';
|
||||
return 'OfflineTtsPocketModelConfig(lmFlow: $lmFlow, lmMain: $lmMain, encoder: $encoder, decoder: $decoder, textConditioner: $textConditioner, vocabJson: $vocabJson, tokenScoresJson: $tokenScoresJson, voiceEmbeddingCacheCapacity: $voiceEmbeddingCacheCapacity)';
|
||||
}
|
||||
|
||||
final String lmFlow;
|
||||
@@ -388,6 +392,7 @@ class OfflineTtsPocketModelConfig {
|
||||
final String textConditioner;
|
||||
final String vocabJson;
|
||||
final String tokenScoresJson;
|
||||
final int voiceEmbeddingCacheCapacity;
|
||||
}
|
||||
|
||||
class OfflineTtsModelConfig {
|
||||
@@ -569,6 +574,8 @@ class OfflineTts {
|
||||
c.ref.model.pocket.vocabJson = config.model.pocket.vocabJson.toNativeUtf8();
|
||||
c.ref.model.pocket.tokenScoresJson = config.model.pocket.tokenScoresJson
|
||||
.toNativeUtf8();
|
||||
c.ref.model.pocket.voiceEmbeddingCacheCapacity =
|
||||
config.model.pocket.voiceEmbeddingCacheCapacity;
|
||||
|
||||
c.ref.model.numThreads = config.model.numThreads;
|
||||
c.ref.model.debug = config.model.debug ? 1 : 0;
|
||||
|
||||
@@ -20,6 +20,8 @@ func main() {
|
||||
config.ModelConfig.FunAsrNano.LLM = "./sherpa-onnx-funasr-nano-int8-2025-12-30/llm.int8.onnx"
|
||||
config.ModelConfig.FunAsrNano.Embedding = "./sherpa-onnx-funasr-nano-int8-2025-12-30/embedding.int8.onnx"
|
||||
config.ModelConfig.FunAsrNano.Tokenizer = "./sherpa-onnx-funasr-nano-int8-2025-12-30/Qwen3-0.6B"
|
||||
// Seed for reproducibility (default: 42)
|
||||
config.ModelConfig.FunAsrNano.Seed = 42
|
||||
|
||||
config.ModelConfig.Tokens = ""
|
||||
|
||||
|
||||
@@ -94,6 +94,8 @@ func main() {
|
||||
|
||||
var referenceAudio string = "./sherpa-onnx-pocket-tts-int8-2026-01-26/test_wavs/bria.wav"
|
||||
var outputFilename string = "./generated.wav"
|
||||
var voiceEmbeddingCacheCapacity int = 50
|
||||
var seed int = -1
|
||||
|
||||
text := `Today as always, men fall into two groups: slaves and free men.
|
||||
Whoever does not have two-thirds of his day for himself, is a slave,
|
||||
@@ -102,6 +104,8 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
flag.StringVar(&referenceAudio, "reference-audio", referenceAudio, "Path to the reference audio")
|
||||
flag.StringVar(&text, "text", text, "Text to be synthesized")
|
||||
flag.StringVar(&outputFilename, "output-filename", outputFilename, "File to save the generated audio")
|
||||
flag.IntVar(&voiceEmbeddingCacheCapacity, "voice-embedding-cache-capacity", voiceEmbeddingCacheCapacity, "Voice embedding cache capacity (default: 50)")
|
||||
flag.IntVar(&seed, "seed", seed, "Random seed for reproducibility (default: -1, random)")
|
||||
flag.Parse()
|
||||
|
||||
// ---------------- config ----------------
|
||||
@@ -121,6 +125,7 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/vocab.json"
|
||||
config.Model.Pocket.TokenScoresJson =
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/token_scores.json"
|
||||
config.Model.Pocket.VoiceEmbeddingCacheCapacity = voiceEmbeddingCacheCapacity
|
||||
|
||||
config.Model.NumThreads = 2
|
||||
config.Model.Debug = 0
|
||||
@@ -142,10 +147,16 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
cfg.ReferenceAudio = wave.Samples
|
||||
cfg.ReferenceSampleRate = wave.SampleRate
|
||||
|
||||
cfg.Extra = json.RawMessage(`{
|
||||
"max_reference_audio_len": 10,
|
||||
"temperature": 0.7
|
||||
}`)
|
||||
// Build extra config with optional seed
|
||||
extraMap := map[string]interface{}{
|
||||
"max_reference_audio_len": 10,
|
||||
"temperature": 0.7,
|
||||
}
|
||||
if seed >= 0 {
|
||||
extraMap["seed"] = seed
|
||||
}
|
||||
extraBytes, _ := json.Marshal(extraMap)
|
||||
cfg.Extra = json.RawMessage(extraBytes)
|
||||
|
||||
log.Println("Start generating")
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ func main() {
|
||||
|
||||
var referenceAudio string = "./sherpa-onnx-pocket-tts-int8-2026-01-26/test_wavs/bria.wav"
|
||||
var outputFilename string = "./generated.wav"
|
||||
var voiceEmbeddingCacheCapacity int = 50
|
||||
var seed int = -1
|
||||
|
||||
text := `Today as always, men fall into two groups: slaves and free men.
|
||||
Whoever does not have two-thirds of his day for himself, is a slave,
|
||||
@@ -21,6 +23,8 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
flag.StringVar(&referenceAudio, "reference-audio", referenceAudio, "Path to the reference audio")
|
||||
flag.StringVar(&text, "text", text, "Text to be synthesized")
|
||||
flag.StringVar(&outputFilename, "output-filename", outputFilename, "File to save the generated audio")
|
||||
flag.IntVar(&voiceEmbeddingCacheCapacity, "voice-embedding-cache-capacity", voiceEmbeddingCacheCapacity, "Voice embedding cache capacity (default: 50)")
|
||||
flag.IntVar(&seed, "seed", seed, "Random seed for reproducibility (default: -1, random)")
|
||||
flag.Parse()
|
||||
|
||||
// ---------------- config ----------------
|
||||
@@ -40,6 +44,7 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/vocab.json"
|
||||
config.Model.Pocket.TokenScoresJson =
|
||||
"./sherpa-onnx-pocket-tts-int8-2026-01-26/token_scores.json"
|
||||
config.Model.Pocket.VoiceEmbeddingCacheCapacity = voiceEmbeddingCacheCapacity
|
||||
|
||||
config.Model.NumThreads = 2
|
||||
config.Model.Debug = 0
|
||||
@@ -61,10 +66,16 @@ whatever he may be: a statesman, a businessman, an official, or a scholar.`
|
||||
cfg.ReferenceAudio = wave.Samples
|
||||
cfg.ReferenceSampleRate = wave.SampleRate
|
||||
|
||||
cfg.Extra = json.RawMessage(`{
|
||||
"max_reference_audio_len": 10,
|
||||
"temperature": 0.7
|
||||
}`)
|
||||
// Build extra config with optional seed
|
||||
extraMap := map[string]interface{}{
|
||||
"max_reference_audio_len": 10,
|
||||
"temperature": 0.7,
|
||||
}
|
||||
if seed >= 0 {
|
||||
extraMap["seed"] = seed
|
||||
}
|
||||
extraBytes, _ := json.Marshal(extraMap)
|
||||
cfg.Extra = json.RawMessage(extraBytes)
|
||||
|
||||
log.Println("Start generating")
|
||||
|
||||
|
||||
Reference in new issue
Block a user