Fangjun Kuang
Committed by GitHub

Add C# API for Kokoro TTS 1.0 (#1805)

@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 cd dotnet-examples/ 3 cd dotnet-examples/
4 4
5 cd ./kokoro-tts 5 cd ./kokoro-tts
6 -./run-kokoro-en.sh 6 +./run-kokoro.sh
7 ls -lh 7 ls -lh
8 8
9 cd ../offline-tts 9 cd ../offline-tts
@@ -14,6 +14,63 @@ class OfflineTtsDemo @@ -14,6 +14,63 @@ class OfflineTtsDemo
14 { 14 {
15 static void Main(string[] args) 15 static void Main(string[] args)
16 { 16 {
  17 +
  18 + TestZhEn();
  19 + TestEn();
  20 + }
  21 +
  22 + static void TestZhEn()
  23 + {
  24 + var config = new OfflineTtsConfig();
  25 + config.Model.Kokoro.Model = "./kokoro-multi-lang-v1_0/model.onnx";
  26 + config.Model.Kokoro.Voices = "./kokoro-multi-lang-v1_0/voices.bin";
  27 + config.Model.Kokoro.Tokens = "./kokoro-multi-lang-v1_0/tokens.txt";
  28 + config.Model.Kokoro.DataDir = "./kokoro-multi-lang-v1_0/espeak-ng-data";
  29 + config.Model.Kokoro.DictDir = "./kokoro-multi-lang-v1_0/dict";
  30 + config.Model.Kokoro.Lexicon = "./kokoro-multi-lang-v1_0/lexicon-us-en.txt,./kokoro-multi-lang-v1_0/lexicon-zh.txt";
  31 +
  32 + config.Model.NumThreads = 2;
  33 + config.Model.Debug = 1;
  34 + config.Model.Provider = "cpu";
  35 +
  36 + var tts = new OfflineTts(config);
  37 + var speed = 1.0f;
  38 + var text = "中英文语音合成测试。This is generated by next generation Kaldi using Kokoro without Misaki. 你觉得中英文说的如何呢?";
  39 +
  40 + var sid = 50;
  41 +
  42 + var MyCallback = (IntPtr samples, int n, float progress) =>
  43 + {
  44 + float[] data = new float[n];
  45 + Marshal.Copy(samples, data, 0, n);
  46 + // You can process samples here, e.g., play them.
  47 + // See ../kokoro-tts-playback for how to play them
  48 + Console.WriteLine($"Progress {progress*100}%");
  49 +
  50 + // 1 means to keep generating
  51 + // 0 means to stop generating
  52 + return 1;
  53 + };
  54 +
  55 + var callback = new OfflineTtsCallbackProgress(MyCallback);
  56 +
  57 + var audio = tts.GenerateWithCallbackProgress(text, speed, sid, callback);
  58 +
  59 + var outputFilename = "./generated-kokoro-zh-en.wav";
  60 + var ok = audio.SaveToWaveFile(outputFilename);
  61 +
  62 + if (ok)
  63 + {
  64 + Console.WriteLine($"Wrote to {outputFilename} succeeded!");
  65 + }
  66 + else
  67 + {
  68 + Console.WriteLine($"Failed to write {outputFilename}");
  69 + }
  70 + }
  71 +
  72 + static void TestEn()
  73 + {
17 var config = new OfflineTtsConfig(); 74 var config = new OfflineTtsConfig();
18 config.Model.Kokoro.Model = "./kokoro-en-v0_19/model.onnx"; 75 config.Model.Kokoro.Model = "./kokoro-en-v0_19/model.onnx";
19 config.Model.Kokoro.Voices = "./kokoro-en-v0_19/voices.bin"; 76 config.Model.Kokoro.Voices = "./kokoro-en-v0_19/voices.bin";
@@ -54,7 +111,7 @@ class OfflineTtsDemo @@ -54,7 +111,7 @@ class OfflineTtsDemo
54 111
55 var audio = tts.GenerateWithCallbackProgress(text, speed, sid, callback); 112 var audio = tts.GenerateWithCallbackProgress(text, speed, sid, callback);
56 113
57 - var outputFilename = "./generated-kokoro-0.wav"; 114 + var outputFilename = "./generated-kokoro-en.wav";
58 var ok = audio.SaveToWaveFile(outputFilename); 115 var ok = audio.SaveToWaveFile(outputFilename);
59 116
60 if (ok) 117 if (ok)
1 #!/usr/bin/env bash 1 #!/usr/bin/env bash
2 set -ex 2 set -ex
3 3
  4 +if [ ! -f ./kokoro-multi-lang-v1_0/model.onnx ]; then
  5 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-multi-lang-v1_0.tar.bz2
  6 + tar xf kokoro-multi-lang-v1_0.tar.bz2
  7 + rm kokoro-multi-lang-v1_0.tar.bz2
  8 +fi
  9 +
4 if [ ! -f ./kokoro-en-v0_19/model.onnx ]; then 10 if [ ! -f ./kokoro-en-v0_19/model.onnx ]; then
5 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-en-v0_19.tar.bz2 11 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-en-v0_19.tar.bz2
6 tar xf kokoro-en-v0_19.tar.bz2 12 tar xf kokoro-en-v0_19.tar.bz2
@@ -15,6 +15,9 @@ namespace SherpaOnnx @@ -15,6 +15,9 @@ namespace SherpaOnnx
15 DataDir = ""; 15 DataDir = "";
16 16
17 LengthScale = 1.0F; 17 LengthScale = 1.0F;
  18 +
  19 + DictDir = "";
  20 + Lexicon = "";
18 } 21 }
19 [MarshalAs(UnmanagedType.LPStr)] 22 [MarshalAs(UnmanagedType.LPStr)]
20 public string Model; 23 public string Model;
@@ -29,5 +32,11 @@ namespace SherpaOnnx @@ -29,5 +32,11 @@ namespace SherpaOnnx
29 public string DataDir; 32 public string DataDir;
30 33
31 public float LengthScale; 34 public float LengthScale;
  35 +
  36 + [MarshalAs(UnmanagedType.LPStr)]
  37 + public string DictDir;
  38 +
  39 + [MarshalAs(UnmanagedType.LPStr)]
  40 + public string Lexicon;
32 } 41 }
33 } 42 }