From a8bdb4b38a0a7f2cc7e025c9ac9fda8821e42ccf Mon Sep 17 00:00:00 2001 From: Fangjun Kuang Date: Mon, 14 Aug 2023 14:38:41 +0800 Subject: [PATCH] Support paraformer on iOS (#265) * Fix C API to support streaming paraformer * Fix Swift API * Support paraformer in iOS --- c-api-examples/decode-file-c-api.c | 6 +- .../SherpaOnnx.xcodeproj/project.pbxproj | 16 +++- .../UserInterfaceState.xcuserstate | Bin 36312 -> 42749 bytes ios-swift/SherpaOnnx/SherpaOnnx/Model.swift | 69 ++++++++++------ .../SherpaOnnx/ViewController.swift | 3 +- .../UserInterfaceState.xcuserstate | Bin 12582 -> 16738 bytes ios-swiftui/SherpaOnnx/SherpaOnnx/Model.swift | 27 +++++-- .../SherpaOnnx/SherpaOnnxViewModel.swift | 21 ++--- sherpa-onnx/c-api/c-api.cc | 26 ++++-- sherpa-onnx/c-api/c-api.h | 17 +++- swift-api-examples/SherpaOnnx.swift | 76 +++++++++++++----- swift-api-examples/decode-file.swift | 29 ++++--- 12 files changed, 204 insertions(+), 86 deletions(-) diff --git a/c-api-examples/decode-file-c-api.c b/c-api-examples/decode-file-c-api.c index 6a8e1d3e..afcc3e4b 100644 --- a/c-api-examples/decode-file-c-api.c +++ b/c-api-examples/decode-file-c-api.c @@ -113,13 +113,13 @@ int32_t main(int32_t argc, char *argv[]) { config.model_config.tokens = value; break; case 'e': - config.model_config.encoder = value; + config.model_config.transducer.encoder = value; break; case 'd': - config.model_config.decoder = value; + config.model_config.transducer.decoder = value; break; case 'j': - config.model_config.joiner = value; + config.model_config.transducer.joiner = value; break; case 'n': config.model_config.num_threads = atoi(value); diff --git a/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.pbxproj b/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.pbxproj index d125a9b4..a7d3c3c3 100644 --- a/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.pbxproj +++ b/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + C93989AE2A89FE13009AB859 /* sherpa-onnx.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C984A81B29AA11C500D74C52 /* sherpa-onnx.xcframework */; }; + C93989B02A89FE33009AB859 /* onnxruntime.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C93989AF2A89FE33009AB859 /* onnxruntime.xcframework */; }; C984A7E829A9EEB700D74C52 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C984A7E729A9EEB700D74C52 /* AppDelegate.swift */; }; C984A7EA29A9EEB700D74C52 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C984A7E929A9EEB700D74C52 /* SceneDelegate.swift */; }; C984A7F129A9EEB900D74C52 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C984A7F029A9EEB900D74C52 /* Assets.xcassets */; }; @@ -18,8 +20,6 @@ C984A82829AA196100D74C52 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C984A82629AA196100D74C52 /* Main.storyboard */; }; C984A82A29AA19AC00D74C52 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = C984A82929AA19AC00D74C52 /* Model.swift */; }; C984A83C29AA430B00D74C52 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C984A83B29AA430B00D74C52 /* ViewController.swift */; }; - C984A83D29AA43D900D74C52 /* sherpa-onnx.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C984A81B29AA11C500D74C52 /* sherpa-onnx.xcframework */; }; - C984A83F29AA43EE00D74C52 /* onnxruntime.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = C984A83E29AA43EE00D74C52 /* onnxruntime.xcframework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,6 +40,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + C93989AF2A89FE33009AB859 /* onnxruntime.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = onnxruntime.xcframework; path = "../../build-ios/ios-onnxruntime/1.15.1/onnxruntime.xcframework"; sourceTree = ""; }; + C93989B12A89FF78009AB859 /* decoder.int8.onnx */ = {isa = PBXFileReference; lastKnownFileType = file; name = decoder.int8.onnx; path = "../../../icefall-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en/decoder.int8.onnx"; sourceTree = ""; }; + C93989B22A89FF78009AB859 /* encoder.int8.onnx */ = {isa = PBXFileReference; lastKnownFileType = file; name = encoder.int8.onnx; path = "../../../icefall-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en/encoder.int8.onnx"; sourceTree = ""; }; + C93989B32A89FF78009AB859 /* tokens.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = tokens.txt; path = "../../../icefall-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en/tokens.txt"; sourceTree = ""; }; C984A7E429A9EEB700D74C52 /* SherpaOnnx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SherpaOnnx.app; sourceTree = BUILT_PRODUCTS_DIR; }; C984A7E729A9EEB700D74C52 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C984A7E929A9EEB700D74C52 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -66,8 +70,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C984A83F29AA43EE00D74C52 /* onnxruntime.xcframework in Frameworks */, - C984A83D29AA43D900D74C52 /* sherpa-onnx.xcframework in Frameworks */, + C93989B02A89FE33009AB859 /* onnxruntime.xcframework in Frameworks */, + C93989AE2A89FE13009AB859 /* sherpa-onnx.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -146,8 +150,12 @@ C984A81A29AA11C500D74C52 /* Frameworks */ = { isa = PBXGroup; children = ( + C93989B12A89FF78009AB859 /* decoder.int8.onnx */, + C93989B22A89FF78009AB859 /* encoder.int8.onnx */, + C93989B32A89FF78009AB859 /* tokens.txt */, C984A82029AA139600D74C52 /* onnxruntime.xcframework */, C984A83E29AA43EE00D74C52 /* onnxruntime.xcframework */, + C93989AF2A89FE33009AB859 /* onnxruntime.xcframework */, C984A81B29AA11C500D74C52 /* sherpa-onnx.xcframework */, ); name = Frameworks; diff --git a/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.xcworkspace/xcuserdata/fangjun.xcuserdatad/UserInterfaceState.xcuserstate b/ios-swift/SherpaOnnx/SherpaOnnx.xcodeproj/project.xcworkspace/xcuserdata/fangjun.xcuserdatad/UserInterfaceState.xcuserstate index 5e8e877dcea4ec7756ef472033352e4fe8e05dd1..5753b74b8f40bedcfa5f1816dbdfd9e66e4fa335 100644 GIT binary patch delta 22052 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 String { /// sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 (Bilingual, Chinese + English) /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/zipformer-transducer-models.html -func getBilingualStreamZhEnZipformer20230220() -> SherpaOnnxOnlineTransducerModelConfig { +func getBilingualStreamZhEnZipformer20230220() -> SherpaOnnxOnlineModelConfig { let encoder = getResource("encoder-epoch-99-avg-1", "onnx") let decoder = getResource("decoder-epoch-99-avg-1", "onnx") let joiner = getResource("joiner-epoch-99-avg-1", "onnx") let tokens = getResource("tokens", "txt") - return sherpaOnnxOnlineTransducerModelConfig( - encoder: encoder, - decoder: decoder, - joiner: joiner, + return sherpaOnnxOnlineModelConfig( tokens: tokens, - numThreads: 2, + transducer: sherpaOnnxOnlineTransducerModelConfig( + encoder: encoder, + decoder: decoder, + joiner: joiner + ), + numThreads: 1, modelType: "zipformer" ) } -func getZhZipformer20230615() -> SherpaOnnxOnlineTransducerModelConfig { +func getZhZipformer20230615() -> SherpaOnnxOnlineModelConfig { let encoder = getResource("encoder-epoch-12-avg-4-chunk-16-left-128", "onnx") let decoder = getResource("decoder-epoch-12-avg-4-chunk-16-left-128", "onnx") let joiner = getResource("joiner-epoch-12-avg-4-chunk-16-left-128", "onnx") let tokens = getResource("tokens", "txt") - return sherpaOnnxOnlineTransducerModelConfig( - encoder: encoder, - decoder: decoder, - joiner: joiner, + return sherpaOnnxOnlineModelConfig( tokens: tokens, - numThreads: 2, + transducer: sherpaOnnxOnlineTransducerModelConfig( + encoder: encoder, + decoder: decoder, + joiner: joiner + ), + numThreads: 1, modelType: "zipformer2" ) } -func getZhZipformer20230615Int8() -> SherpaOnnxOnlineTransducerModelConfig { +func getZhZipformer20230615Int8() -> SherpaOnnxOnlineModelConfig { let encoder = getResource("encoder-epoch-12-avg-4-chunk-16-left-128.int8", "onnx") let decoder = getResource("decoder-epoch-12-avg-4-chunk-16-left-128", "onnx") let joiner = getResource("joiner-epoch-12-avg-4-chunk-16-left-128", "onnx") let tokens = getResource("tokens", "txt") - return sherpaOnnxOnlineTransducerModelConfig( - encoder: encoder, - decoder: decoder, - joiner: joiner, + return sherpaOnnxOnlineModelConfig( tokens: tokens, - numThreads: 2, + transducer: sherpaOnnxOnlineTransducerModelConfig( + encoder: encoder, + decoder: decoder, + joiner: joiner), + numThreads: 1, modelType: "zipformer2" ) } -func getEnZipformer20230626() -> SherpaOnnxOnlineTransducerModelConfig { +func getEnZipformer20230626() -> SherpaOnnxOnlineModelConfig { let encoder = getResource("encoder-epoch-99-avg-1-chunk-16-left-128", "onnx") let decoder = getResource("decoder-epoch-99-avg-1-chunk-16-left-128", "onnx") let joiner = getResource("joiner-epoch-99-avg-1-chunk-16-left-128", "onnx") let tokens = getResource("tokens", "txt") - return sherpaOnnxOnlineTransducerModelConfig( - encoder: encoder, - decoder: decoder, - joiner: joiner, + return sherpaOnnxOnlineModelConfig( tokens: tokens, - numThreads: 2, + transducer: sherpaOnnxOnlineTransducerModelConfig( + encoder: encoder, + decoder: decoder, + joiner: joiner), + numThreads: 1, modelType: "zipformer2" ) } +func getBilingualStreamingZhEnParaformer() -> SherpaOnnxOnlineModelConfig { + let encoder = getResource("encoder.int8", "onnx") + let decoder = getResource("decoder.int8", "onnx") + let tokens = getResource("tokens", "txt") + + return sherpaOnnxOnlineModelConfig( + tokens: tokens, + paraformer: sherpaOnnxOnlineParaformerModelConfig( + encoder: encoder, + decoder: decoder), + numThreads: 1, + modelType: "paraformer" + ) +} + /// Please refer to /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html /// to add more models if you need diff --git a/ios-swift/SherpaOnnx/SherpaOnnx/ViewController.swift b/ios-swift/SherpaOnnx/SherpaOnnx/ViewController.swift index eb4706b6..7153a354 100644 --- a/ios-swift/SherpaOnnx/SherpaOnnx/ViewController.swift +++ b/ios-swift/SherpaOnnx/SherpaOnnx/ViewController.swift @@ -87,7 +87,8 @@ class ViewController: UIViewController { // let modelConfig = getBilingualStreamZhEnZipformer20230220() // let modelConfig = getZhZipformer20230615() - let modelConfig = getEnZipformer20230626() + // let modelConfig = getEnZipformer20230626() + let modelConfig = getBilingualStreamingZhEnParaformer() let featConfig = sherpaOnnxFeatureConfig( sampleRate: 16000, diff --git a/ios-swiftui/SherpaOnnx/SherpaOnnx.xcodeproj/project.xcworkspace/xcuserdata/fangjun.xcuserdatad/UserInterfaceState.xcuserstate b/ios-swiftui/SherpaOnnx/SherpaOnnx.xcodeproj/project.xcworkspace/xcuserdata/fangjun.xcuserdatad/UserInterfaceState.xcuserstate index 0d703c0bb045d34e1bb8ffe0119d156becfe22f0..86affab0e9c6646a04cd5298d6cf2b5ecb035fc6 100644 GIT binary patch literal 16738 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 delta 6317 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 diff --git a/ios-swiftui/SherpaOnnx/SherpaOnnx/Model.swift b/ios-swiftui/SherpaOnnx/SherpaOnnx/Model.swift index 569b62c8..a8439f8e 100644 --- a/ios-swiftui/SherpaOnnx/SherpaOnnx/Model.swift +++ b/ios-swiftui/SherpaOnnx/SherpaOnnx/Model.swift @@ -15,22 +15,39 @@ func getResource(_ forResource: String, _ ofType: String) -> String { /// sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 (Bilingual, Chinese + English) /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/zipformer-transducer-models.html -func getBilingualStreamZhEnZipformer20230220() -> SherpaOnnxOnlineTransducerModelConfig { +func getBilingualStreamZhEnZipformer20230220() -> SherpaOnnxOnlineModelConfig { let encoder = getResource("encoder-epoch-99-avg-1", "onnx") let decoder = getResource("decoder-epoch-99-avg-1", "onnx") let joiner = getResource("joiner-epoch-99-avg-1", "onnx") let tokens = getResource("tokens", "txt") - return sherpaOnnxOnlineTransducerModelConfig( - encoder: encoder, - decoder: decoder, - joiner: joiner, + return sherpaOnnxOnlineModelConfig( tokens: tokens, + transducer: sherpaOnnxOnlineTransducerModelConfig( + encoder: encoder, + decoder: decoder, + joiner: joiner), numThreads: 2, modelType: "zipformer" ) } +// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-paraformer/index.html +func getBilingualStreamingZhEnParaformer() -> SherpaOnnxOnlineModelConfig { + let encoder = getResource("encoder.int8", "onnx") + let decoder = getResource("decoder.int8", "onnx") + let tokens = getResource("tokens", "txt") + + return sherpaOnnxOnlineModelConfig( + tokens: tokens, + paraformer: sherpaOnnxOnlineParaformerModelConfig( + encoder: encoder, + decoder: decoder), + numThreads: 1, + modelType: "paraformer" + ) +} + /// Please refer to /// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html /// to add more models if you need diff --git a/ios-swiftui/SherpaOnnx/SherpaOnnx/SherpaOnnxViewModel.swift b/ios-swiftui/SherpaOnnx/SherpaOnnx/SherpaOnnxViewModel.swift index e2b9c5bf..52912137 100644 --- a/ios-swiftui/SherpaOnnx/SherpaOnnx/SherpaOnnxViewModel.swift +++ b/ios-swiftui/SherpaOnnx/SherpaOnnx/SherpaOnnxViewModel.swift @@ -16,15 +16,15 @@ enum Status { class SherpaOnnxViewModel: ObservableObject { @Published var status: Status = .stop @Published var subtitles: String = "" - + var sentences: [String] = [] - + var audioEngine: AVAudioEngine? = nil var recognizer: SherpaOnnxRecognizer! = nil - + var lastSentence: String = "" let maxSentence: Int = 20 - + var results: String { if sentences.isEmpty && lastSentence.isEmpty { return "" @@ -42,24 +42,25 @@ class SherpaOnnxViewModel: ObservableObject { .joined(separator: "\n") + "\n\(sentences.count): \(lastSentence.lowercased())" } } - + func updateLabel() { DispatchQueue.main.async { self.subtitles = self.results } } - + init() { initRecognizer() initRecorder() } - + private func initRecognizer() { // Please select one model that is best suitable for you. // // You can also modify Model.swift to add new pre-trained models from // https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html - let modelConfig = getBilingualStreamZhEnZipformer20230220() + // let modelConfig = getBilingualStreamZhEnZipformer20230220() + let modelConfig = getBilingualStreamingZhEnParaformer() let featConfig = sherpaOnnxFeatureConfig( sampleRate: 16000, @@ -77,7 +78,7 @@ class SherpaOnnxViewModel: ObservableObject { ) recognizer = SherpaOnnxRecognizer(config: &config) } - + private func initRecorder() { print("init recorder") audioEngine = AVAudioEngine() @@ -152,7 +153,7 @@ class SherpaOnnxViewModel: ObservableObject { } } } - + public func toggleRecorder() { if status == .stop { startRecorder() diff --git a/sherpa-onnx/c-api/c-api.cc b/sherpa-onnx/c-api/c-api.cc index 7a2e0540..0a3bc13f 100644 --- a/sherpa-onnx/c-api/c-api.cc +++ b/sherpa-onnx/c-api/c-api.cc @@ -39,11 +39,17 @@ SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer( SHERPA_ONNX_OR(config->feat_config.feature_dim, 80); recognizer_config.model_config.transducer.encoder = - SHERPA_ONNX_OR(config->model_config.encoder, ""); + SHERPA_ONNX_OR(config->model_config.transducer.encoder, ""); recognizer_config.model_config.transducer.decoder = - SHERPA_ONNX_OR(config->model_config.decoder, ""); + SHERPA_ONNX_OR(config->model_config.transducer.decoder, ""); recognizer_config.model_config.transducer.joiner = - SHERPA_ONNX_OR(config->model_config.joiner, ""); + SHERPA_ONNX_OR(config->model_config.transducer.joiner, ""); + + recognizer_config.model_config.paraformer.encoder = + SHERPA_ONNX_OR(config->model_config.paraformer.encoder, ""); + recognizer_config.model_config.paraformer.decoder = + SHERPA_ONNX_OR(config->model_config.paraformer.decoder, ""); + recognizer_config.model_config.tokens = SHERPA_ONNX_OR(config->model_config.tokens, ""); recognizer_config.model_config.num_threads = @@ -128,6 +134,8 @@ SherpaOnnxOnlineRecognizerResult *GetOnlineStreamResult( const auto &text = result.text; auto r = new SherpaOnnxOnlineRecognizerResult; + memset(r, 0, sizeof(SherpaOnnxOnlineRecognizerResult)); + // copy text r->text = new char[text.size() + 1]; std::copy(text.begin(), text.end(), const_cast(r->text)); @@ -153,7 +161,6 @@ SherpaOnnxOnlineRecognizerResult *GetOnlineStreamResult( r->tokens = new char[total_length]; memset(reinterpret_cast(const_cast(r->tokens)), 0, total_length); - r->timestamps = new float[r->count]; char **tokens_temp = new char *[r->count]; int32_t pos = 0; for (int32_t i = 0; i < r->count; ++i) { @@ -162,10 +169,17 @@ SherpaOnnxOnlineRecognizerResult *GetOnlineStreamResult( result.tokens[i].c_str(), result.tokens[i].size()); // +1 to move past the null character pos += result.tokens[i].size() + 1; - r->timestamps[i] = result.timestamps[i]; + } + r->tokens_arr = tokens_temp; + + if (!result.timestamps.empty()) { + r->timestamps = new float[r->count]; + std::copy(result.timestamps.begin(), result.timestamps.end(), + r->timestamps); + } else { + r->timestamps = nullptr; } - r->tokens_arr = tokens_temp; } else { r->count = 0; r->timestamps = nullptr; diff --git a/sherpa-onnx/c-api/c-api.h b/sherpa-onnx/c-api/c-api.h index cb1fa7e8..621b6a80 100644 --- a/sherpa-onnx/c-api/c-api.h +++ b/sherpa-onnx/c-api/c-api.h @@ -50,12 +50,25 @@ SHERPA_ONNX_API typedef struct SherpaOnnxOnlineTransducerModelConfig { const char *encoder; const char *decoder; const char *joiner; +} SherpaOnnxOnlineTransducerModelConfig; + +// please visit +// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-paraformer/index.html +// to download pre-trained streaming paraformer models +SHERPA_ONNX_API typedef struct SherpaOnnxOnlineParaformerModelConfig { + const char *encoder; + const char *decoder; +} SherpaOnnxOnlineParaformerModelConfig; + +SHERPA_ONNX_API typedef struct SherpaOnnxModelConfig { + SherpaOnnxOnlineTransducerModelConfig transducer; + SherpaOnnxOnlineParaformerModelConfig paraformer; const char *tokens; int32_t num_threads; const char *provider; int32_t debug; // true to print debug information of the model const char *model_type; -} SherpaOnnxOnlineTransducerModelConfig; +} SherpaOnnxOnlineModelConfig; /// It expects 16 kHz 16-bit single channel wave format. SHERPA_ONNX_API typedef struct SherpaOnnxFeatureConfig { @@ -71,7 +84,7 @@ SHERPA_ONNX_API typedef struct SherpaOnnxFeatureConfig { SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerConfig { SherpaOnnxFeatureConfig feat_config; - SherpaOnnxOnlineTransducerModelConfig model_config; + SherpaOnnxOnlineModelConfig model_config; /// Possible values are: greedy_search, modified_beam_search const char *decoding_method; diff --git a/swift-api-examples/SherpaOnnx.swift b/swift-api-examples/SherpaOnnx.swift index 70565abd..4f2c470e 100644 --- a/swift-api-examples/SherpaOnnx.swift +++ b/swift-api-examples/SherpaOnnx.swift @@ -18,31 +18,71 @@ func toCPointer(_ s: String) -> UnsafePointer! { /// Return an instance of SherpaOnnxOnlineTransducerModelConfig. /// /// Please refer to -/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html +/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/index.html /// to download the required `.onnx` files. /// /// - Parameters: /// - encoder: Path to encoder.onnx /// - decoder: Path to decoder.onnx /// - joiner: Path to joiner.onnx -/// - tokens: Path to tokens.txt -/// - numThreads: Number of threads to use for neural network computation. /// /// - Returns: Return an instance of SherpaOnnxOnlineTransducerModelConfig func sherpaOnnxOnlineTransducerModelConfig( - encoder: String, - decoder: String, - joiner: String, - tokens: String, - numThreads: Int = 2, - provider: String = "cpu", - debug: Int = 0, - modelType: String = "" + encoder: String = "", + decoder: String = "", + joiner: String = "" ) -> SherpaOnnxOnlineTransducerModelConfig { return SherpaOnnxOnlineTransducerModelConfig( encoder: toCPointer(encoder), decoder: toCPointer(decoder), - joiner: toCPointer(joiner), + joiner: toCPointer(joiner) + ) +} + +/// Return an instance of SherpaOnnxOnlineParaformerModelConfig. +/// +/// Please refer to +/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-paraformer/index.html +/// to download the required `.onnx` files. +/// +/// - Parameters: +/// - encoder: Path to encoder.onnx +/// - decoder: Path to decoder.onnx +/// +/// - Returns: Return an instance of SherpaOnnxOnlineParaformerModelConfig +func sherpaOnnxOnlineParaformerModelConfig( + encoder: String = "", + decoder: String = "" +) -> SherpaOnnxOnlineParaformerModelConfig { + return SherpaOnnxOnlineParaformerModelConfig( + encoder: toCPointer(encoder), + decoder: toCPointer(decoder) + ) +} + +/// Return an instance of SherpaOnnxOnlineModelConfig. +/// +/// Please refer to +/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html +/// to download the required `.onnx` files. +/// +/// - Parameters: +/// - tokens: Path to tokens.txt +/// - numThreads: Number of threads to use for neural network computation. +/// +/// - Returns: Return an instance of SherpaOnnxOnlineTransducerModelConfig +func sherpaOnnxOnlineModelConfig( + tokens: String, + transducer: SherpaOnnxOnlineTransducerModelConfig = sherpaOnnxOnlineTransducerModelConfig(), + paraformer: SherpaOnnxOnlineParaformerModelConfig = sherpaOnnxOnlineParaformerModelConfig(), + numThreads: Int = 1, + provider: String = "cpu", + debug: Int = 0, + modelType: String = "" +) -> SherpaOnnxOnlineModelConfig { + return SherpaOnnxOnlineModelConfig( + transducer: transducer, + paraformer: paraformer, tokens: toCPointer(tokens), num_threads: Int32(numThreads), provider: toCPointer(provider), @@ -62,7 +102,7 @@ func sherpaOnnxFeatureConfig( func sherpaOnnxOnlineRecognizerConfig( featConfig: SherpaOnnxFeatureConfig, - modelConfig: SherpaOnnxOnlineTransducerModelConfig, + modelConfig: SherpaOnnxOnlineModelConfig, enableEndpoint: Bool = false, rule1MinTrailingSilence: Float = 2.4, rule2MinTrailingSilence: Float = 1.2, @@ -100,17 +140,17 @@ class SherpaOnnxOnlineRecongitionResult { } var count: Int32 { - return result.pointee.count + return result.pointee.count } var tokens: [String] { if let tokensPointer = result.pointee.tokens_arr { var tokens: [String] = [] for index in 0..