Fangjun Kuang
Committed by GitHub

Removed unused TTS example code in .Net examples (#1492)

@@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
20 exit 1 20 exit 1
21 else 21 else
22 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 22 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  23 + emcc --version
23 fi 24 fi
24 fi 25 fi
25 26
@@ -15,6 +15,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -15,6 +15,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
15 exit 1 15 exit 1
16 else 16 else
17 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 17 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  18 + emcc --version
18 fi 19 fi
19 fi 20 fi
20 21
@@ -22,6 +22,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -22,6 +22,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
22 exit 1 22 exit 1
23 else 23 else
24 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 24 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  25 + emcc --version
25 fi 26 fi
26 fi 27 fi
27 28
@@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
20 exit 1 20 exit 1
21 else 21 else
22 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 22 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  23 + emcc --version
23 fi 24 fi
24 fi 25 fi
25 26
@@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
20 exit 1 20 exit 1
21 else 21 else
22 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 22 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  23 + emcc --version
23 fi 24 fi
24 fi 25 fi
25 26
@@ -21,6 +21,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -21,6 +21,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
21 exit 1 21 exit 1
22 else 22 else
23 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 23 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  24 + emcc --version
24 fi 25 fi
25 fi 26 fi
26 27
@@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then @@ -20,6 +20,7 @@ if [ x"$EMSCRIPTEN" == x"" ]; then
20 exit 1 20 exit 1
21 else 21 else
22 EMSCRIPTEN=$(dirname $(realpath $(which emcc))) 22 EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
  23 + emcc --version
23 fi 24 fi
24 fi 25 fi
25 26
1 -using NAudio.Wave;  
2 -  
3 -namespace TTS.Struct  
4 -{  
5 - public sealed partial class SherpaOnnxGeneratedAudioResult  
6 - {  
7 - private WaveOutEvent waveOut;  
8 - private WaveFormat waveFormat;  
9 - private BufferedWaveProvider bufferedWaveProvider;  
10 -  
11 - private int bufferLength = 1;  
12 -  
13 - public TimeSpan? AudioDuration => bufferedWaveProvider?.BufferedDuration;  
14 -  
15 - public float PlayProgress => (waveOut?.GetPosition() * 1.0f / bufferLength).Value;  
16 -  
17 - public void Play()  
18 - {  
19 - waveOut ??= new WaveOutEvent();  
20 -  
21 - waveFormat ??= new WaveFormat(sample_rate, AudioDataBit, Channels); // 32-bit 浮点,单声道  
22 -  
23 - if (bufferedWaveProvider == null)  
24 - {  
25 - bufferedWaveProvider ??= new BufferedWaveProvider(waveFormat);  
26 -  
27 - var buffer = AudioByteData;  
28 -  
29 - bufferLength = buffer.Length;  
30 -  
31 - bufferedWaveProvider.AddSamples(buffer, 0, bufferLength);  
32 - bufferedWaveProvider.BufferLength = bufferLength;  
33 - waveOut.Init(bufferedWaveProvider);  
34 - }  
35 - waveOut.Play();  
36 - }  
37 -  
38 - public void Stop()  
39 - {  
40 - waveOut?.Stop();  
41 - }  
42 -  
43 - }  
44 -}  
1 -using System.Text;  
2 -using TTS;  
3 -using TTS.Struct;  
4 -  
5 -internal class Program  
6 -{  
7 - private static void Main(string[] args)  
8 - {  
9 - SherpaOnnxOfflineTtsConfig sherpaOnnxOfflineTtsConfig = new SherpaOnnxOfflineTtsConfig();  
10 - sherpaOnnxOfflineTtsConfig.model = new SherpaOnnxOfflineTtsModelConfig  
11 - {  
12 - debug = 0,  
13 - num_threads = 4,  
14 - provider = "cpu",  
15 - vits = new SherpaOnnxOfflineTtsVitsModelConfig  
16 - {  
17 - //lexicon = "vits-zh-aishell3/lexicon.txt",  
18 - //model = "vits-zh-aishell3/vits-aishell3.onnx",  
19 - //tokens = "vits-zh-aishell3/tokens.txt",  
20 - model = @"C:\Services\Sherpa\model.onnx",  
21 - lexicon = "",  
22 - tokens = @"C:\Services\Sherpa\tokens.txt",  
23 - data_dir = @"C:\Services\Sherpa\espeak-ng-data",  
24 -  
25 - noise_scale = 0.667f,  
26 - noise_scale_w = 0.8f,  
27 - length_scale = 1,  
28 - },  
29 -  
30 - };  
31 -  
32 - TTSCore i = new TTSCore(sherpaOnnxOfflineTtsConfig);  
33 -  
34 - Console.InputEncoding = Encoding.Unicode;  
35 - Console.OutputEncoding = Encoding.UTF8;  
36 -  
37 - while (true)  
38 - {  
39 - var str = Console.ReadLine();  
40 - var audioResult = i.ToSpeech(str, 40, 1f);  
41 -  
42 - // audioResult.WriteWAVFile("123.wav");保存本地  
43 -  
44 - audioResult.Play();  
45 -  
46 - int lastIndex = -1;  
47 - while (audioResult.PlayProgress <= 1f)  
48 - {  
49 - int index = (int)(audioResult.PlayProgress * (str.Length - 1));  
50 - if (lastIndex != index)  
51 - {  
52 - Console.Write(str[index]);  
53 - lastIndex = index;  
54 - }  
55 - Thread.Sleep(100);  
56 - }  
57 -  
58 - if (++lastIndex < str.Length)  
59 - Console.Write(str[lastIndex]);  
60 -  
61 - Console.WriteLine();  
62 -  
63 - }  
64 -  
65 - }  
66 -}  
1 -using System;  
2 -using System.Collections.Generic;  
3 -using System.Linq;  
4 -using System.Runtime.InteropServices;  
5 -using System.Text;  
6 -using System.Threading.Tasks;  
7 -  
8 -namespace TTS.Struct  
9 -{  
10 - /// <summary>  
11 - /// 生成语音结果  
12 - /// </summary>  
13 - public sealed partial class SherpaOnnxGeneratedAudioResult : IDisposable  
14 - {  
15 - public const string Filename = "sherpa-onnx-c-api";  
16 -  
17 - /// <summary>  
18 - /// 销毁非托管内存  
19 - /// </summary>  
20 - /// <param name="ttsGenerateIntptr"></param>  
21 - [DllImport(Filename)]  
22 - private static extern void SherpaOnnxDestroyOfflineTtsGeneratedAudio(IntPtr ttsGenerateIntptr);  
23 -  
24 - [DllImport(Filename)]  
25 - private static extern int SherpaOnnxWriteWave(IntPtr q, int n, int sample_rate, string filename);  
26 -  
27 - /// <summary>  
28 - /// 音频数据比特  
29 - /// </summary>  
30 - public const int AudioDataBit = 16;  
31 - /// <summary>  
32 - /// 单通道  
33 - /// </summary>  
34 - public const int Channels = 1;  
35 -  
36 - /// <summary>  
37 - /// 原生句柄  
38 - /// </summary>  
39 - internal IntPtr thisHandle;  
40 -  
41 - internal readonly IntPtr audioData;  
42 - internal readonly int dataSize;  
43 -  
44 - /// <summary>  
45 - /// 采样率  
46 - /// </summary>  
47 - public readonly int sample_rate;  
48 -  
49 - /// <summary>  
50 - /// 音频数据指针  
51 - /// </summary>  
52 - public IntPtr AudioDataIntPtr => audioData;  
53 -  
54 - /// <summary>  
55 - /// 数据的大小  
56 - /// </summary>  
57 - public unsafe int AudioDataLength  
58 - {  
59 - get  
60 - {  
61 - return dataSize;  
62 -  
63 - //float* buffer = (float*)audioData;  
64 - //while (*buffer != 0)  
65 - // ++buffer;  
66 - //return (int)(buffer - (float*)audioData);  
67 - }  
68 - }  
69 -  
70 - /// <summary>  
71 - /// 获得音频数据 float[]  
72 - /// 这个内部创建一个数组  
73 - /// </summary>  
74 - public unsafe float[] AudioFloatData  
75 - {  
76 - get  
77 - {  
78 - int length = AudioDataLength;  
79 -  
80 - float[] floatAudioData = new float[length];  
81 - Marshal.Copy(audioData, floatAudioData, 0, floatAudioData.Length);  
82 - return floatAudioData;  
83 - }  
84 - }  
85 -  
86 -  
87 - /// <summary>  
88 - /// 获得音频数据 byte[]  
89 - /// 这个内部创建一个数组  
90 - /// </summary>  
91 - public byte[] AudioByteData  
92 - {  
93 - get  
94 - {  
95 - byte[] bytes = new byte[AudioDataLength * 2];  
96 - ReadData(bytes, 0);  
97 - return bytes;  
98 - }  
99 - }  
100 -  
101 - internal SherpaOnnxGeneratedAudioResult(IntPtr intPtr, SherpaOnnxGeneratedAudio sherpaOnnx)  
102 - {  
103 - this.thisHandle = intPtr;  
104 - this.audioData = sherpaOnnx.audioData;  
105 - this.dataSize = sherpaOnnx.dataSize;  
106 - this.sample_rate = sherpaOnnx.sample_rate;  
107 - }  
108 -  
109 - ~SherpaOnnxGeneratedAudioResult()  
110 - {  
111 - Dispose();  
112 - }  
113 -  
114 - /// <summary>  
115 - /// 读取数据  
116 - /// 没有垃圾产生,自己传递数组进来  
117 - /// </summary>  
118 - /// <param name="audioFloats">数组</param>  
119 - /// <param name="offset">数组那个位置写入</param>  
120 - /// <returns>写入了多少个</returns>  
121 - public int ReadData(float[] audioFloats, int offset)  
122 - {  
123 - int length = AudioDataLength;  
124 -  
125 - int c = audioFloats.Length - offset;  
126 - length = c >= length ? length : c;  
127 -  
128 - Marshal.Copy(audioData, audioFloats, offset, length);  
129 - return length;  
130 - }  
131 -  
132 - /// <summary>  
133 - /// 读取数据  
134 - /// 这个内部转换成byte[] 音频数组  
135 - /// 没有垃圾产生,自己传递数组进来  
136 - /// </summary>  
137 - /// <param name="audioFloats">数组,这个长度需要是AudioDataLength*2大小</param>  
138 - /// <param name="offset">数组那个位置写入</param>  
139 - /// <returns>写入了多少个</returns>  
140 - public int ReadData(byte[] audioFloats, int offset)  
141 - {  
142 - //因为是16bit存储音频数据,所以float会转换成两个字节存储  
143 - var audiodata = AudioFloatData;  
144 -  
145 - int length = audiodata.Length * 2;  
146 -  
147 - int c = audioFloats.Length - offset;  
148 - c = c % 2 == 0 ? c : c - 1;  
149 -  
150 - length = c >= length ? length : c;  
151 -  
152 - int p = length / 2;  
153 -  
154 - for (int i = 0; i < p; i++)  
155 - {  
156 - short value = (short)(audiodata[i] * short.MaxValue);  
157 -  
158 - audioFloats[offset++] = (byte)value;  
159 - audioFloats[offset++] = (byte)(value >> 8);  
160 - }  
161 -  
162 - return length;  
163 -  
164 - }  
165 -  
166 - /// <summary>  
167 - /// 写入WAV音频数据  
168 - /// </summary>  
169 - /// <param name="filename"></param>  
170 - /// <returns></returns>  
171 - public bool WriteWAVFile(string filename)  
172 - {  
173 - return 1 == SherpaOnnxWriteWave(audioData, this.dataSize, this.sample_rate, filename);  
174 - }  
175 -  
176 - public void Dispose()  
177 - {  
178 - if (this.thisHandle != IntPtr.Zero)  
179 - {  
180 - SherpaOnnxDestroyOfflineTtsGeneratedAudio(this.thisHandle);  
181 - GC.SuppressFinalize(this);  
182 - this.thisHandle = IntPtr.Zero;  
183 - }  
184 - }  
185 - }  
186 -  
187 - [StructLayout(LayoutKind.Sequential)]  
188 - internal struct SherpaOnnxGeneratedAudio  
189 - {  
190 - internal readonly IntPtr audioData;  
191 - internal readonly int dataSize;  
192 -  
193 - /// <summary>  
194 - /// 采样率  
195 - /// </summary>  
196 - public readonly int sample_rate;  
197 - }  
198 -}  
1 -using System.Runtime.InteropServices;  
2 -  
3 -namespace TTS.Struct  
4 -{  
5 - [StructLayout(LayoutKind.Sequential)]  
6 - public struct SherpaOnnxOfflineTtsConfig  
7 - {  
8 - public SherpaOnnxOfflineTtsModelConfig model;  
9 -  
10 - [MarshalAs(UnmanagedType.LPStr)]  
11 - public string rule_fsts;  
12 -  
13 - public int max_num_sentences;  
14 -  
15 - [MarshalAs(UnmanagedType.LPStr)]  
16 - public string rule_fars;  
17 - }  
18 -}  
1 -using System.Runtime.InteropServices;  
2 -  
3 -namespace TTS.Struct  
4 -{  
5 - [StructLayout(LayoutKind.Sequential)]  
6 - public struct SherpaOnnxOfflineTtsModelConfig  
7 - {  
8 - /// <summary>  
9 - /// 模型配置  
10 - /// </summary>  
11 - public SherpaOnnxOfflineTtsVitsModelConfig vits;  
12 - /// <summary>  
13 - /// 线程数  
14 - /// </summary>  
15 - public int num_threads;  
16 - public int debug;  
17 - /// <summary>  
18 - /// 使用cpu  
19 - /// </summary>  
20 - [MarshalAs(UnmanagedType.LPStr)]  
21 - public string provider;  
22 - }  
23 -}  
1 -using System.Runtime.InteropServices;  
2 -  
3 -namespace TTS.Struct  
4 -{  
5 - [StructLayout(LayoutKind.Sequential)]  
6 - public struct SherpaOnnxOfflineTtsVitsModelConfig  
7 - {  
8 - /// <summary>  
9 - /// 模型  
10 - /// "vits-zh-aishell3/vits-aishell3.onnx"  
11 - /// </summary>  
12 - [MarshalAs(UnmanagedType.LPStr)]  
13 - public string model;  
14 - /// <summary>  
15 - /// 词典文件  
16 - /// "vits-zh-aishell3/lexicon.txt"  
17 - /// </summary>  
18 - [MarshalAs(UnmanagedType.LPStr)]  
19 - public string lexicon;  
20 -  
21 - [MarshalAs(UnmanagedType.LPStr)]  
22 - public string tokens;  
23 -  
24 - [MarshalAs(UnmanagedType.LPStr)]  
25 - public string data_dir;  
26 -  
27 - /// <summary>  
28 - /// VITS模型的noise_scale (float,默认值= 0.667)  
29 - /// </summary>  
30 - public float noise_scale = 0.667f;  
31 - /// <summary>  
32 - /// VITS模型的noise_scale_w (float,默认值= 0.8)  
33 - /// </summary>  
34 - public float noise_scale_w = 0.8f;  
35 - /// <summary>  
36 - /// 演讲的速度。大→慢;小→更快。(float, default = 1)  
37 - /// </summary>  
38 - public float length_scale = 1f;  
39 -  
40 - [MarshalAs(UnmanagedType.LPStr)]  
41 - public string dict_dir;  
42 -  
43 - public SherpaOnnxOfflineTtsVitsModelConfig()  
44 - {  
45 - noise_scale = 0.667f;  
46 - noise_scale_w = 0.8f;  
47 - length_scale = 1f;  
48 -  
49 - model = "vits-zh-aishell3/vits-aishell3.onnx";  
50 - lexicon = "vits-zh-aishell3/lexicon.txt";  
51 - tokens = "vits-zh-aishell3/tokens.txt";  
52 - data_dir = "";  
53 - dict_dir = "";  
54 - }  
55 - }  
56 -}  
1 -<Project Sdk="Microsoft.NET.Sdk">  
2 -  
3 - <PropertyGroup>  
4 - <OutputType>Exe</OutputType>  
5 - <TargetFramework>net6.0</TargetFramework>  
6 - <ImplicitUsings>enable</ImplicitUsings>  
7 - <Nullable>enable</Nullable>  
8 - <AllowUnsafeBlocks>true</AllowUnsafeBlocks>  
9 - </PropertyGroup>  
10 - <ItemGroup>  
11 - <PackageReference Include="NAudio" Version="2.2.1" />  
12 - <PackageReference Include="org.k2fsa.sherpa.onnx" Version="1.10.23" />  
13 - </ItemGroup>  
14 -  
15 -</Project>  
1 -using System.Runtime.InteropServices;  
2 -using TTS.Struct;  
3 -  
4 -namespace TTS  
5 -{  
6 - internal sealed class TTSCore : IDisposable  
7 - {  
8 - public const string Filename = "sherpa-onnx-c-api";  
9 -  
10 - [DllImport(Filename, CallingConvention = CallingConvention.Cdecl)]  
11 - private static extern IntPtr SherpaOnnxCreateOfflineTts(SherpaOnnxOfflineTtsConfig handle);  
12 -  
13 - [DllImport(Filename)]  
14 - private static extern IntPtr SherpaOnnxOfflineTtsGenerate(IntPtr createOfflineTtsIntptr, IntPtr text, int sid, float speed);  
15 -  
16 - [DllImport(Filename)]  
17 - private static extern void SherpaOnnxDestroyOfflineTts(IntPtr intPtr);  
18 -  
19 - /// <summary>  
20 - /// 原生句柄  
21 - /// </summary>  
22 - private IntPtr thisHandle;  
23 -  
24 - public TTSCore(SherpaOnnxOfflineTtsConfig modelConfig)  
25 - {  
26 - IntPtr ttsHandle = SherpaOnnxCreateOfflineTts(modelConfig);  
27 - if (ttsHandle == IntPtr.Zero)  
28 - {  
29 - throw new InvalidOperationException("Failed to create SherpaOnnx TTS engine.");  
30 - }  
31 - thisHandle = ttsHandle;  
32 - }  
33 -  
34 - /// <summary>  
35 - /// 文字转语音  
36 - /// </summary>  
37 - /// <param name="text">文字</param>  
38 - /// <param name="sid">音色</param>  
39 - /// <param name="speed">速度</param>  
40 - /// <returns></returns>  
41 - public SherpaOnnxGeneratedAudioResult ToSpeech(string text, int sid, float speed = 1f)  
42 - {  
43 - var result = SherpaOnnxOfflineTtsGenerate(thisHandle, Marshal.StringToCoTaskMemUTF8(text), sid, speed);  
44 - SherpaOnnxGeneratedAudio impl = (SherpaOnnxGeneratedAudio)Marshal.PtrToStructure(result, typeof(SherpaOnnxGeneratedAudio));  
45 - return new SherpaOnnxGeneratedAudioResult(result, impl);  
46 - }  
47 -  
48 - /// <summary>  
49 - /// 文字转语音  
50 - /// </summary>  
51 - /// <param name="text">文字</param>  
52 - /// <param name="sid">音色</param>  
53 - /// <param name="speed">速度</param>  
54 - /// <returns></returns>  
55 - public Task<SherpaOnnxGeneratedAudioResult> ToSpeechAsync(string text, int sid, float speed = 1f)  
56 - {  
57 - return Task.Run(() => ToSpeech(text, sid, speed));  
58 - }  
59 -  
60 - ~TTSCore()  
61 - {  
62 - Dispose();  
63 - }  
64 -  
65 - public void Dispose()  
66 - {  
67 - if (this.thisHandle != IntPtr.Zero)  
68 - {  
69 - SherpaOnnxDestroyOfflineTts(this.thisHandle);  
70 - GC.SuppressFinalize(this);  
71 - this.thisHandle = IntPtr.Zero;  
72 - }  
73 - }  
74 - }  
75 -}