From 90dfe73f1a1b6815cfba08ec165394719005e4cf Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sun, 07 Jun 2026 01:48:32 +0800
Subject: [PATCH] Fix X-ASR CJK spacing
---
privatevoice.src/internal/engine/engine_darwin.go | 87 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/privatevoice.src/internal/engine/engine_darwin.go b/privatevoice.src/internal/engine/engine_darwin.go
index be5b525..d18dd48 100755
--- a/privatevoice.src/internal/engine/engine_darwin.go
+++ b/privatevoice.src/internal/engine/engine_darwin.go
@@ -16,9 +16,17 @@
hwInfo string
}
+type xasrStreamingEngine struct {
+ recognizer *sherpa.OnlineRecognizer
+ hwInfo string
+}
+
func newPlatformEngine(resolved model.ResolvedModel) (Engine, error) {
if !isSupportedBackend(resolved.BackendKind) {
return nil, fmt.Errorf("unsupported backend kind: %s", resolved.BackendKind)
+ }
+ if resolved.BackendKind == model.BackendXASRStreaming {
+ return newXASRStreamingEngine(resolved)
}
providers := darwinProviders(resolved.ProviderOrder)
@@ -42,6 +50,30 @@
}
return nil, fmt.Errorf("failed to initialize sherpa-onnx with any provider")
+}
+
+func newXASRStreamingEngine(resolved model.ResolvedModel) (Engine, error) {
+ providers := darwinProviders(resolved.ProviderOrder)
+
+ for _, p := range providers {
+ config, err := onlineConfigForResolvedModel(resolved, p.provider)
+ if err != nil {
+ return nil, err
+ }
+
+ recognizer := sherpa.NewOnlineRecognizer(&config)
+ if recognizer != nil {
+ info := fmt.Sprintf("%s ยท %s", resolved.Profile.DisplayName, p.name)
+ logger.Info("Engine initialized: %s", info)
+ return &xasrStreamingEngine{
+ recognizer: recognizer,
+ hwInfo: info,
+ }, nil
+ }
+ logger.Info("Failed to init X-ASR with %s, trying next provider", p.name)
+ }
+
+ return nil, fmt.Errorf("failed to initialize X-ASR streaming recognizer with any provider")
}
func offlineConfigForResolvedModel(resolved model.ResolvedModel, provider string) (sherpa.OfflineRecognizerConfig, error) {
@@ -79,6 +111,29 @@
config.ModelConfig.Qwen3ASR.Seed = 0
default:
return sherpa.OfflineRecognizerConfig{}, fmt.Errorf("unsupported backend kind: %s", resolved.BackendKind)
+ }
+
+ return config, nil
+}
+
+func onlineConfigForResolvedModel(resolved model.ResolvedModel, provider string) (sherpa.OnlineRecognizerConfig, error) {
+ config := sherpa.OnlineRecognizerConfig{}
+ config.FeatConfig.SampleRate = 16000
+ config.FeatConfig.FeatureDim = 80
+ config.ModelConfig.Tokens = resolved.Files["tokens"]
+ config.ModelConfig.NumThreads = resolved.Profile.NumThreads
+ config.ModelConfig.Provider = provider
+ config.ModelConfig.ModelType = "zipformer2"
+ config.DecodingMethod = "greedy_search"
+ config.EnableEndpoint = 0
+
+ switch resolved.BackendKind {
+ case model.BackendXASRStreaming:
+ config.ModelConfig.Transducer.Encoder = resolved.Files["encoder"]
+ config.ModelConfig.Transducer.Decoder = resolved.Files["decoder"]
+ config.ModelConfig.Transducer.Joiner = resolved.Files["joiner"]
+ default:
+ return sherpa.OnlineRecognizerConfig{}, fmt.Errorf("unsupported online backend kind: %s", resolved.BackendKind)
}
return config, nil
@@ -127,7 +182,32 @@
return result.Text, nil
}
+func (e *xasrStreamingEngine) Recognize(samples []float32) (string, error) {
+ stream := sherpa.NewOnlineStream(e.recognizer)
+ defer sherpa.DeleteOnlineStream(stream)
+
+ if len(samples) > 0 {
+ stream.AcceptWaveform(16000, samples)
+ }
+ stream.InputFinished()
+
+ for e.recognizer.IsReady(stream) {
+ e.recognizer.Decode(stream)
+ }
+
+ result := e.recognizer.GetResult(stream)
+ if result == nil {
+ return "", nil
+ }
+
+ return result.Text, nil
+}
+
func (e *sherpaEngine) HardwareInfo() string {
+ return e.hwInfo
+}
+
+func (e *xasrStreamingEngine) HardwareInfo() string {
return e.hwInfo
}
@@ -137,3 +217,10 @@
e.recognizer = nil
}
}
+
+func (e *xasrStreamingEngine) Close() {
+ if e.recognizer != nil {
+ sherpa.DeleteOnlineRecognizer(e.recognizer)
+ e.recognizer = nil
+ }
+}
--
Gitblit v1.9.3