正在显示
13 个修改的文件
包含
497 行增加
和
6 行删除
| @@ -55,3 +55,19 @@ jobs: | @@ -55,3 +55,19 @@ jobs: | ||
| 55 | ./run-zipformer.sh | 55 | ./run-zipformer.sh |
| 56 | ./run-whisper.sh | 56 | ./run-whisper.sh |
| 57 | ./run-tdnn-yesno.sh | 57 | ./run-tdnn-yesno.sh |
| 58 | + | ||
| 59 | + cd ../offline-tts | ||
| 60 | + ./run-aishell3.sh | ||
| 61 | + ./run-piper.sh | ||
| 62 | + ls -lh | ||
| 63 | + | ||
| 64 | + cd ../.. | ||
| 65 | + | ||
| 66 | + mkdir tts | ||
| 67 | + | ||
| 68 | + cp dotnet-examples/offline-tts/*.wav ./tts | ||
| 69 | + | ||
| 70 | + - uses: actions/upload-artifact@v3 | ||
| 71 | + with: | ||
| 72 | + name: dot-net-tts-generated-test-files-${{ matrix.os }} | ||
| 73 | + path: tts |
| @@ -131,6 +131,7 @@ jobs: | @@ -131,6 +131,7 @@ jobs: | ||
| 131 | - name: Copy files | 131 | - name: Copy files |
| 132 | shell: bash | 132 | shell: bash |
| 133 | run: | | 133 | run: | |
| 134 | + cp -v scripts/dotnet/examples/offline-tts.csproj dotnet-examples/offline-tts/ | ||
| 134 | cp -v scripts/dotnet/examples/offline-decode-files.csproj dotnet-examples/offline-decode-files/ | 135 | cp -v scripts/dotnet/examples/offline-decode-files.csproj dotnet-examples/offline-decode-files/ |
| 135 | cp -v scripts/dotnet/examples/online-decode-files.csproj dotnet-examples/online-decode-files/ | 136 | cp -v scripts/dotnet/examples/online-decode-files.csproj dotnet-examples/online-decode-files/ |
| 136 | cp -v scripts/dotnet/examples/speech-recognition-from-microphone.csproj dotnet-examples/speech-recognition-from-microphone/ | 137 | cp -v scripts/dotnet/examples/speech-recognition-from-microphone.csproj dotnet-examples/speech-recognition-from-microphone/ |
| @@ -153,3 +154,19 @@ jobs: | @@ -153,3 +154,19 @@ jobs: | ||
| 153 | ./run-zipformer.sh | 154 | ./run-zipformer.sh |
| 154 | ./run-whisper.sh | 155 | ./run-whisper.sh |
| 155 | ./run-tdnn-yesno.sh | 156 | ./run-tdnn-yesno.sh |
| 157 | + | ||
| 158 | + cd ../offline-tts | ||
| 159 | + ./run-aishell3.sh | ||
| 160 | + ./run-piper.sh | ||
| 161 | + ls -lh | ||
| 162 | + | ||
| 163 | + cd ../.. | ||
| 164 | + | ||
| 165 | + mkdir tts | ||
| 166 | + | ||
| 167 | + cp dotnet-examples/offline-tts/*.wav ./tts | ||
| 168 | + | ||
| 169 | + - uses: actions/upload-artifact@v3 | ||
| 170 | + with: | ||
| 171 | + name: dot-net-tts-generated-test-files-${{ matrix.os }} | ||
| 172 | + path: tts |
dotnet-examples/.notes
0 → 100644
dotnet-examples/offline-tts/Program.cs
0 → 100644
| 1 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 2 | +// | ||
| 3 | +// This file shows how to use a non-streaming TTS model for text-to-speech | ||
| 4 | +// Please refer to | ||
| 5 | +// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html | ||
| 6 | +// and | ||
| 7 | +// https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models | ||
| 8 | +// to download pre-trained models | ||
| 9 | +using CommandLine.Text; | ||
| 10 | +using CommandLine; | ||
| 11 | +using SherpaOnnx; | ||
| 12 | +using System.Collections.Generic; | ||
| 13 | +using System; | ||
| 14 | + | ||
| 15 | +class OfflineTtsDemo | ||
| 16 | +{ | ||
| 17 | + class Options | ||
| 18 | + { | ||
| 19 | + | ||
| 20 | + [Option("tts-rule-fsts", Required = false, Default = "", HelpText = "path to rule.fst")] | ||
| 21 | + public string RuleFsts { get; set; } | ||
| 22 | + | ||
| 23 | + [Option("vits-data-dir", Required = false, Default = "", HelpText = "Path to the directory containing dict for espeak-ng.")] | ||
| 24 | + public string DataDir { get; set; } | ||
| 25 | + | ||
| 26 | + [Option("vits-length-scale", Required = false, Default = 1, HelpText = "speech speed. Larger->Slower; Smaller->faster")] | ||
| 27 | + public float LengthScale { get; set; } | ||
| 28 | + | ||
| 29 | + [Option("vits-noise-scale", Required = false, Default = 0.667f, HelpText = "noise_scale for VITS models")] | ||
| 30 | + public float NoiseScale { get; set; } | ||
| 31 | + | ||
| 32 | + [Option("vits-noise-scale-w", Required = false, Default = 0.8f, HelpText = "noise_scale_w for VITS models")] | ||
| 33 | + public float NoiseScaleW { get; set; } | ||
| 34 | + | ||
| 35 | + [Option("vits-lexicon", Required = false, Default = "", HelpText = "Path to lexicon.txt")] | ||
| 36 | + public string Lexicon { get; set; } | ||
| 37 | + | ||
| 38 | + [Option("vits-tokens", Required = false, Default = "", HelpText = "Path to tokens.txt")] | ||
| 39 | + public string Tokens { get; set; } | ||
| 40 | + | ||
| 41 | + [Option("tts-max-num-sentences", Required = false, Default = 1, HelpText = "Maximum number of sentences that we process at a time.")] | ||
| 42 | + public int MaxNumSentences { get; set; } | ||
| 43 | + | ||
| 44 | + [Option(Required = false, Default = 0, HelpText = "1 to show debug messages.")] | ||
| 45 | + public int Debug { get; set; } | ||
| 46 | + | ||
| 47 | + [Option("vits-model", Required = true, HelpText = "Path to VITS model")] | ||
| 48 | + public string Model { get; set; } | ||
| 49 | + | ||
| 50 | + [Option("sid", Required = false, Default = 0, HelpText = "Speaker ID")] | ||
| 51 | + public int SpeakerId { get; set; } | ||
| 52 | + | ||
| 53 | + [Option("text", Required = true, HelpText = "Text to synthesize")] | ||
| 54 | + public string Text { get; set; } | ||
| 55 | + | ||
| 56 | + [Option("output-filename", Required = true, Default = "./generated.wav", HelpText = "Path to save the generated audio")] | ||
| 57 | + public string OutputFilename { get; set; } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + static void Main(string[] args) | ||
| 61 | + { | ||
| 62 | + var parser = new CommandLine.Parser(with => with.HelpWriter = null); | ||
| 63 | + var parserResult = parser.ParseArguments<Options>(args); | ||
| 64 | + | ||
| 65 | + parserResult | ||
| 66 | + .WithParsed<Options>(options => Run(options)) | ||
| 67 | + .WithNotParsed(errs => DisplayHelp(parserResult, errs)); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + private static void DisplayHelp<T>(ParserResult<T> result, IEnumerable<Error> errs) | ||
| 71 | + { | ||
| 72 | + string usage = @" | ||
| 73 | +# vits-aishell3 | ||
| 74 | + | ||
| 75 | +wget -qq https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-zh-aishell3.tar.bz2 | ||
| 76 | +tar xf vits-zh-aishell3.tar.bz2 | ||
| 77 | + | ||
| 78 | +dotnet run \ | ||
| 79 | + --vits-model=./vits-zh-aishell3/vits-aishell3.onnx \ | ||
| 80 | + --vits-tokens=./vits-zh-aishell3/tokens.txt \ | ||
| 81 | + --vits-lexicon=./vits-zh-aishell3/lexicon.txt \ | ||
| 82 | + --tts-rule-fsts=./vits-zh-aishell3/rule.fst \ | ||
| 83 | + --sid=66 \ | ||
| 84 | + --debug=1 \ | ||
| 85 | + --output-filename=./aishell3-66.wav \ | ||
| 86 | + --text=这是一个语音合成测试 | ||
| 87 | + | ||
| 88 | +# Piper models | ||
| 89 | + | ||
| 90 | +wget -qq https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-en_US-amy-low.tar.bz2 | ||
| 91 | +tar xf vits-piper-en_US-amy-low.tar.bz2 | ||
| 92 | + | ||
| 93 | +dotnet run \ | ||
| 94 | + --vits-model=./vits-piper-en_US-amy-low/en_US-amy-low.onnx \ | ||
| 95 | + --vits-tokens=./vits-piper-en_US-amy-low/tokens.txt \ | ||
| 96 | + --vits-data-dir=./vits-piper-en_US-amy-low/espeak-ng-data \ | ||
| 97 | + --debug=1 \ | ||
| 98 | + --output-filename=./amy.wav \ | ||
| 99 | + --text='This is a text to speech application in dotnet with Next Generation Kaldi' | ||
| 100 | + | ||
| 101 | +Please refer to | ||
| 102 | +https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/index.html | ||
| 103 | +to download more models. | ||
| 104 | +"; | ||
| 105 | + | ||
| 106 | + var helpText = HelpText.AutoBuild(result, h => | ||
| 107 | + { | ||
| 108 | + h.AdditionalNewLineAfterOption = false; | ||
| 109 | + h.Heading = usage; | ||
| 110 | + h.Copyright = "Copyright (c) 2024 Xiaomi Corporation"; | ||
| 111 | + return HelpText.DefaultParsingErrorsHandler(result, h); | ||
| 112 | + }, e => e); | ||
| 113 | + Console.WriteLine(helpText); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + private static void Run(Options options) | ||
| 117 | + { | ||
| 118 | + OfflineTtsConfig config = new OfflineTtsConfig(); | ||
| 119 | + config.Model.Vits.Model = options.Model; | ||
| 120 | + config.Model.Vits.Lexicon = options.Lexicon; | ||
| 121 | + config.Model.Vits.Tokens = options.Tokens; | ||
| 122 | + config.Model.Vits.DataDir = options.DataDir; | ||
| 123 | + config.Model.Vits.NoiseScale = options.NoiseScale; | ||
| 124 | + config.Model.Vits.NoiseScaleW = options.NoiseScaleW; | ||
| 125 | + config.Model.Vits.LengthScale = options.LengthScale; | ||
| 126 | + config.Model.NumThreads = 1; | ||
| 127 | + config.Model.Debug = options.Debug; | ||
| 128 | + config.Model.Provider = "cpu"; | ||
| 129 | + config.RuleFsts = options.RuleFsts; | ||
| 130 | + config.MaxNumSentences = options.MaxNumSentences; | ||
| 131 | + | ||
| 132 | + OfflineTts tts = new OfflineTts(config); | ||
| 133 | + float speed = 1.0f / options.LengthScale; | ||
| 134 | + int sid = options.SpeakerId; | ||
| 135 | + OfflineTtsGeneratedAudio audio = tts.Generate(options.Text, speed, sid); | ||
| 136 | + bool ok = audio.SaveToWaveFile(options.OutputFilename); | ||
| 137 | + | ||
| 138 | + if (ok) | ||
| 139 | + { | ||
| 140 | + Console.WriteLine($"Wrote to {options.OutputFilename} succeeded!"); | ||
| 141 | + } | ||
| 142 | + else | ||
| 143 | + { | ||
| 144 | + Console.WriteLine($"Failed to write {options.OutputFilename}"); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | +} |
| 1 | +<Project Sdk="Microsoft.NET.Sdk"> | ||
| 2 | + | ||
| 3 | + <PropertyGroup> | ||
| 4 | + <OutputType>Exe</OutputType> | ||
| 5 | + <TargetFramework>net6.0</TargetFramework> | ||
| 6 | + <RootNamespace>offline_tts</RootNamespace> | ||
| 7 | + <ImplicitUsings>enable</ImplicitUsings> | ||
| 8 | + <Nullable>enable</Nullable> | ||
| 9 | + </PropertyGroup> | ||
| 10 | + | ||
| 11 | + <ItemGroup> | ||
| 12 | + <PackageReference Include="CommandLineParser" Version="2.9.1" /> | ||
| 13 | + <PackageReference Include="org.k2fsa.sherpa.onnx" Version="*" /> | ||
| 14 | + </ItemGroup> | ||
| 15 | + | ||
| 16 | +</Project> |
dotnet-examples/offline-tts/run-aishell3.sh
0 → 100755
| 1 | +#!/usr/bin/env bash | ||
| 2 | + | ||
| 3 | +if [ ! -f ./vits-zh-aishell3/vits-aishell3.onnx ]; then | ||
| 4 | + wget -qq https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-zh-aishell3.tar.bz2 | ||
| 5 | + tar xf vits-zh-aishell3.tar.bz2 | ||
| 6 | + rm vits-zh-aishell3.tar.bz2 | ||
| 7 | +fi | ||
| 8 | + | ||
| 9 | +dotnet run \ | ||
| 10 | + --vits-model=./vits-zh-aishell3/vits-aishell3.onnx \ | ||
| 11 | + --vits-tokens=./vits-zh-aishell3/tokens.txt \ | ||
| 12 | + --vits-lexicon=./vits-zh-aishell3/lexicon.txt \ | ||
| 13 | + --tts-rule-fsts=./vits-zh-aishell3/rule.fst \ | ||
| 14 | + --sid=66 \ | ||
| 15 | + --debug=1 \ | ||
| 16 | + --output-filename=./aishell3-66.wav \ | ||
| 17 | + --text="这是一个语音合成测试, 写于公元 2024 年 1 月 28 号, 23点27分,星期天。" |
dotnet-examples/offline-tts/run-piper.sh
0 → 100755
| 1 | +#!/usr/bin/env bash | ||
| 2 | + | ||
| 3 | +if [ ! -f ./vits-piper-en_US-amy-low/en_US-amy-low.onnx ]; then | ||
| 4 | + wget -qq https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-en_US-amy-low.tar.bz2 | ||
| 5 | + tar xf vits-piper-en_US-amy-low.tar.bz2 | ||
| 6 | + rm vits-piper-en_US-amy-low.tar.bz2 | ||
| 7 | +fi | ||
| 8 | + | ||
| 9 | +dotnet run \ | ||
| 10 | + --vits-model=./vits-piper-en_US-amy-low/en_US-amy-low.onnx \ | ||
| 11 | + --vits-tokens=./vits-piper-en_US-amy-low/tokens.txt \ | ||
| 12 | + --vits-data-dir=./vits-piper-en_US-amy-low/espeak-ng-data \ | ||
| 13 | + --debug=1 \ | ||
| 14 | + --output-filename=./amy.wav \ | ||
| 15 | + --text="This is a text to speech application in dotnet with Next Generation Kaldi" | ||
| 16 | + |
| @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "offline-decode-files", "off | @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "offline-decode-files", "off | ||
| 9 | EndProject | 9 | EndProject |
| 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "speech-recognition-from-microphone", "speech-recognition-from-microphone\speech-recognition-from-microphone.csproj", "{FE4EA1FF-062A-46B3-B78D-C828FED7B82E}" | 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "speech-recognition-from-microphone", "speech-recognition-from-microphone\speech-recognition-from-microphone.csproj", "{FE4EA1FF-062A-46B3-B78D-C828FED7B82E}" |
| 11 | EndProject | 11 | EndProject |
| 12 | +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "offline-tts", "offline-tts\offline-tts.csproj", "{72196886-7143-4043-96E2-BCACEC6C79EB}" | ||
| 13 | +EndProject | ||
| 12 | Global | 14 | Global |
| 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution | 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution |
| 14 | Debug|Any CPU = Debug|Any CPU | 16 | Debug|Any CPU = Debug|Any CPU |
| @@ -30,5 +32,9 @@ Global | @@ -30,5 +32,9 @@ Global | ||
| 30 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Debug|Any CPU.Build.0 = Debug|Any CPU | 32 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
| 31 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Release|Any CPU.ActiveCfg = Release|Any CPU | 33 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
| 32 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Release|Any CPU.Build.0 = Release|Any CPU | 34 | {FE4EA1FF-062A-46B3-B78D-C828FED7B82E}.Release|Any CPU.Build.0 = Release|Any CPU |
| 35 | + {72196886-7143-4043-96E2-BCACEC6C79EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| 36 | + {72196886-7143-4043-96E2-BCACEC6C79EB}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| 37 | + {72196886-7143-4043-96E2-BCACEC6C79EB}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| 38 | + {72196886-7143-4043-96E2-BCACEC6C79EB}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| 33 | EndGlobalSection | 39 | EndGlobalSection |
| 34 | EndGlobal | 40 | EndGlobal |
scripts/dotnet/examples/offline-tts.csproj
0 → 100644
| 1 | +<Project Sdk="Microsoft.NET.Sdk"> | ||
| 2 | + | ||
| 3 | + <PropertyGroup> | ||
| 4 | + <OutputType>Exe</OutputType> | ||
| 5 | + <TargetFramework>net6.0</TargetFramework> | ||
| 6 | + <RootNamespace>offline_tts</RootNamespace> | ||
| 7 | + <ImplicitUsings>enable</ImplicitUsings> | ||
| 8 | + <Nullable>enable</Nullable> | ||
| 9 | + </PropertyGroup> | ||
| 10 | + | ||
| 11 | + <PropertyGroup> | ||
| 12 | + <RestoreSources>/tmp/packages;$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources> | ||
| 13 | + </PropertyGroup> | ||
| 14 | + | ||
| 15 | + <ItemGroup> | ||
| 16 | + <PackageReference Include="CommandLineParser" Version="2.9.1" /> | ||
| 17 | + <PackageReference Include="org.k2fsa.sherpa.onnx" Version="*" /> | ||
| 18 | + </ItemGroup> | ||
| 19 | + | ||
| 20 | +</Project> |
| @@ -11,6 +11,214 @@ namespace SherpaOnnx | @@ -11,6 +11,214 @@ namespace SherpaOnnx | ||
| 11 | { | 11 | { |
| 12 | 12 | ||
| 13 | [StructLayout(LayoutKind.Sequential)] | 13 | [StructLayout(LayoutKind.Sequential)] |
| 14 | + public struct OfflineTtsVitsModelConfig | ||
| 15 | + { | ||
| 16 | + public OfflineTtsVitsModelConfig() | ||
| 17 | + { | ||
| 18 | + Model = ""; | ||
| 19 | + Lexicon = ""; | ||
| 20 | + Tokens = ""; | ||
| 21 | + DataDir = ""; | ||
| 22 | + | ||
| 23 | + NoiseScale = 0.667F; | ||
| 24 | + NoiseScaleW = 0.8F; | ||
| 25 | + LengthScale = 1.0F; | ||
| 26 | + } | ||
| 27 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 28 | + public string Model; | ||
| 29 | + | ||
| 30 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 31 | + public string Lexicon; | ||
| 32 | + | ||
| 33 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 34 | + public string Tokens; | ||
| 35 | + | ||
| 36 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 37 | + public string DataDir; | ||
| 38 | + | ||
| 39 | + public float NoiseScale; | ||
| 40 | + public float NoiseScaleW; | ||
| 41 | + public float LengthScale; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + [StructLayout(LayoutKind.Sequential)] | ||
| 45 | + public struct OfflineTtsModelConfig | ||
| 46 | + { | ||
| 47 | + public OfflineTtsModelConfig() | ||
| 48 | + { | ||
| 49 | + Vits = new OfflineTtsVitsModelConfig(); | ||
| 50 | + NumThreads = 1; | ||
| 51 | + Debug = 0; | ||
| 52 | + Provider = "cpu"; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public OfflineTtsVitsModelConfig Vits; | ||
| 56 | + public int NumThreads; | ||
| 57 | + public int Debug; | ||
| 58 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 59 | + public string Provider; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public struct OfflineTtsConfig | ||
| 63 | + { | ||
| 64 | + public OfflineTtsConfig() | ||
| 65 | + { | ||
| 66 | + Model = new OfflineTtsModelConfig(); | ||
| 67 | + RuleFsts = ""; | ||
| 68 | + MaxNumSentences = 1; | ||
| 69 | + } | ||
| 70 | + public OfflineTtsModelConfig Model; | ||
| 71 | + | ||
| 72 | + [MarshalAs(UnmanagedType.LPStr)] | ||
| 73 | + public string RuleFsts; | ||
| 74 | + | ||
| 75 | + public int MaxNumSentences; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + public class OfflineTtsGeneratedAudio | ||
| 79 | + { | ||
| 80 | + public OfflineTtsGeneratedAudio(IntPtr p) | ||
| 81 | + { | ||
| 82 | + _handle = new HandleRef(this, p); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + public bool SaveToWaveFile(String filename) | ||
| 86 | + { | ||
| 87 | + Impl impl = (Impl)Marshal.PtrToStructure(Handle, typeof(Impl)); | ||
| 88 | + int status = SherpaOnnxWriteWave(impl.Samples, impl.NumSamples, impl.SampleRate, filename); | ||
| 89 | + return status == 1; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + ~OfflineTtsGeneratedAudio() | ||
| 93 | + { | ||
| 94 | + Cleanup(); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public void Dispose() | ||
| 98 | + { | ||
| 99 | + Cleanup(); | ||
| 100 | + // Prevent the object from being placed on the | ||
| 101 | + // finalization queue | ||
| 102 | + System.GC.SuppressFinalize(this); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + private void Cleanup() | ||
| 106 | + { | ||
| 107 | + SherpaOnnxDestroyOfflineTtsGeneratedAudio(Handle); | ||
| 108 | + | ||
| 109 | + // Don't permit the handle to be used again. | ||
| 110 | + _handle = new HandleRef(this, IntPtr.Zero); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + [StructLayout(LayoutKind.Sequential)] | ||
| 114 | + struct Impl | ||
| 115 | + { | ||
| 116 | + public IntPtr Samples; | ||
| 117 | + public int NumSamples; | ||
| 118 | + public int SampleRate; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + private HandleRef _handle; | ||
| 122 | + public IntPtr Handle => _handle.Handle; | ||
| 123 | + | ||
| 124 | + public int NumSamples | ||
| 125 | + { | ||
| 126 | + get | ||
| 127 | + { | ||
| 128 | + Impl impl = (Impl)Marshal.PtrToStructure(Handle, typeof(Impl)); | ||
| 129 | + return impl.NumSamples; | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public int SampleRate | ||
| 134 | + { | ||
| 135 | + get | ||
| 136 | + { | ||
| 137 | + Impl impl = (Impl)Marshal.PtrToStructure(Handle, typeof(Impl)); | ||
| 138 | + return impl.SampleRate; | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + public float[] Samples | ||
| 143 | + { | ||
| 144 | + get | ||
| 145 | + { | ||
| 146 | + Impl impl = (Impl)Marshal.PtrToStructure(Handle, typeof(Impl)); | ||
| 147 | + | ||
| 148 | + float[] samples = new float[impl.NumSamples]; | ||
| 149 | + Marshal.Copy(impl.Samples, samples, 0, impl.NumSamples); | ||
| 150 | + return samples; | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + [DllImport(Dll.Filename)] | ||
| 155 | + private static extern void SherpaOnnxDestroyOfflineTtsGeneratedAudio(IntPtr handle); | ||
| 156 | + | ||
| 157 | + [DllImport(Dll.Filename)] | ||
| 158 | + private static extern int SherpaOnnxWriteWave(IntPtr samples, int n, int sample_rate, [MarshalAs(UnmanagedType.LPStr)] string filename); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + public class OfflineTts : IDisposable | ||
| 162 | + { | ||
| 163 | + public OfflineTts(OfflineTtsConfig config) | ||
| 164 | + { | ||
| 165 | + IntPtr h = SherpaOnnxCreateOfflineTts(ref config); | ||
| 166 | + _handle = new HandleRef(this, h); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + public OfflineTtsGeneratedAudio Generate(String text, float speed, int speakerId) | ||
| 170 | + { | ||
| 171 | + IntPtr p = SherpaOnnxOfflineTtsGenerate(_handle.Handle, text, speakerId, speed); | ||
| 172 | + return new OfflineTtsGeneratedAudio(p); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + public void Dispose() | ||
| 176 | + { | ||
| 177 | + Cleanup(); | ||
| 178 | + // Prevent the object from being placed on the | ||
| 179 | + // finalization queue | ||
| 180 | + System.GC.SuppressFinalize(this); | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + ~OfflineTts() | ||
| 184 | + { | ||
| 185 | + Cleanup(); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + private void Cleanup() | ||
| 189 | + { | ||
| 190 | + SherpaOnnxDestroyOfflineTts(_handle.Handle); | ||
| 191 | + | ||
| 192 | + // Don't permit the handle to be used again. | ||
| 193 | + _handle = new HandleRef(this, IntPtr.Zero); | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + private HandleRef _handle; | ||
| 197 | + | ||
| 198 | + public int SampleRate | ||
| 199 | + { | ||
| 200 | + get | ||
| 201 | + { | ||
| 202 | + return SherpaOnnxOfflineTtsSampleRate(_handle.Handle); | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + [DllImport(Dll.Filename)] | ||
| 207 | + private static extern IntPtr SherpaOnnxCreateOfflineTts(ref OfflineTtsConfig config); | ||
| 208 | + | ||
| 209 | + [DllImport(Dll.Filename)] | ||
| 210 | + private static extern void SherpaOnnxDestroyOfflineTts(IntPtr handle); | ||
| 211 | + | ||
| 212 | + [DllImport(Dll.Filename)] | ||
| 213 | + private static extern int SherpaOnnxOfflineTtsSampleRate(IntPtr handle); | ||
| 214 | + | ||
| 215 | + [DllImport(Dll.Filename)] | ||
| 216 | + private static extern IntPtr SherpaOnnxOfflineTtsGenerate(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] string text, int sid, float speed); | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + | ||
| 220 | + | ||
| 221 | + [StructLayout(LayoutKind.Sequential)] | ||
| 14 | public struct OfflineTransducerModelConfig | 222 | public struct OfflineTransducerModelConfig |
| 15 | { | 223 | { |
| 16 | public OfflineTransducerModelConfig() | 224 | public OfflineTransducerModelConfig() |
| @@ -15,12 +15,23 @@ pushd /tmp | @@ -15,12 +15,23 @@ pushd /tmp | ||
| 15 | 15 | ||
| 16 | mkdir -p linux macos windows | 16 | mkdir -p linux macos windows |
| 17 | 17 | ||
| 18 | +# You can pre-download the required wheels to /tmp | ||
| 19 | +src_dir=/tmp | ||
| 20 | + | ||
| 21 | +linux_wheel=$src_dir/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | ||
| 22 | +macos_wheel=$src_dir/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_10_14_x86_64.whl | ||
| 23 | +windows_wheel=$src_dir/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl | ||
| 24 | + | ||
| 18 | if [ ! -f /tmp/linux/libsherpa-onnx-core.so ]; then | 25 | if [ ! -f /tmp/linux/libsherpa-onnx-core.so ]; then |
| 19 | echo "---linux x86_64---" | 26 | echo "---linux x86_64---" |
| 20 | cd linux | 27 | cd linux |
| 21 | - mkdir wheel | 28 | + mkdir -p wheel |
| 22 | cd wheel | 29 | cd wheel |
| 30 | + if [ -f $linux_wheel ]; then | ||
| 31 | + cp -v $linux_wheel . | ||
| 32 | + else | ||
| 23 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | 33 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| 34 | + fi | ||
| 24 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | 35 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| 25 | cp -v sherpa_onnx/lib/*.so* ../ | 36 | cp -v sherpa_onnx/lib/*.so* ../ |
| 26 | cd .. | 37 | cd .. |
| @@ -36,9 +47,13 @@ fi | @@ -36,9 +47,13 @@ fi | ||
| 36 | if [ ! -f /tmp/macos/libsherpa-onnx-core.dylib ]; then | 47 | if [ ! -f /tmp/macos/libsherpa-onnx-core.dylib ]; then |
| 37 | echo "---macOS x86_64---" | 48 | echo "---macOS x86_64---" |
| 38 | cd macos | 49 | cd macos |
| 39 | - mkdir wheel | 50 | + mkdir -p wheel |
| 40 | cd wheel | 51 | cd wheel |
| 52 | + if [ -f $macos_wheel ]; then | ||
| 53 | + cp -v $macos_wheel . | ||
| 54 | + else | ||
| 41 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_10_14_x86_64.whl | 55 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_10_14_x86_64.whl |
| 56 | + fi | ||
| 42 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_10_14_x86_64.whl | 57 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_10_14_x86_64.whl |
| 43 | cp -v sherpa_onnx/lib/*.dylib ../ | 58 | cp -v sherpa_onnx/lib/*.dylib ../ |
| 44 | 59 | ||
| @@ -57,9 +72,13 @@ fi | @@ -57,9 +72,13 @@ fi | ||
| 57 | if [ ! -f /tmp/windows/libsherpa-onnx-core.dll ]; then | 72 | if [ ! -f /tmp/windows/libsherpa-onnx-core.dll ]; then |
| 58 | echo "---windows x64---" | 73 | echo "---windows x64---" |
| 59 | cd windows | 74 | cd windows |
| 60 | - mkdir wheel | 75 | + mkdir -p wheel |
| 61 | cd wheel | 76 | cd wheel |
| 77 | + if [ -f $windows_wheel ]; then | ||
| 78 | + cp -v $windows_wheel . | ||
| 79 | + else | ||
| 62 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl | 80 | curl -OL https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl |
| 81 | + fi | ||
| 63 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl | 82 | unzip sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl |
| 64 | cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll ../ | 83 | cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll ../ |
| 65 | cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib ../ | 84 | cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib ../ |
| @@ -101,5 +120,5 @@ popd | @@ -101,5 +120,5 @@ popd | ||
| 101 | 120 | ||
| 102 | ls -lh packages | 121 | ls -lh packages |
| 103 | 122 | ||
| 104 | -mkdir /tmp/packages | 123 | +mkdir -p /tmp/packages |
| 105 | cp -v packages/*.nupkg /tmp/packages | 124 | cp -v packages/*.nupkg /tmp/packages |
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | 18 | ||
| 19 | namespace sherpa_onnx { | 19 | namespace sherpa_onnx { |
| 20 | 20 | ||
| 21 | -class TransducerKeywordResult; | 21 | +struct TransducerKeywordResult; |
| 22 | class OnlineStream { | 22 | class OnlineStream { |
| 23 | public: | 23 | public: |
| 24 | explicit OnlineStream(const FeatureExtractorConfig &config = {}, | 24 | explicit OnlineStream(const FeatureExtractorConfig &config = {}, |
-
请 注册 或 登录 后发表评论