Ariver
2026-06-03 2dbeae0987f702cae85274e296b087d609fcd289
privatevoice.src/internal/engine/engine_darwin.go
@@ -17,22 +17,21 @@
}
func newPlatformEngine(resolved model.ResolvedModel) (Engine, error) {
   if !isSupportedBackend(resolved.BackendKind) {
      return nil, fmt.Errorf("unsupported backend kind: %s", resolved.BackendKind)
   }
   providers := darwinProviders(resolved.ProviderOrder)
   for _, p := range providers {
      config := sherpa.OfflineRecognizerConfig{}
      config.FeatConfig.SampleRate = 16000
      config.FeatConfig.FeatureDim = 80
      config.ModelConfig.SenseVoice.Model = resolved.Files["model"]
      config.ModelConfig.SenseVoice.UseInverseTextNormalization = 1
      config.ModelConfig.Tokens = resolved.Files["tokens"]
      config.ModelConfig.NumThreads = resolved.Profile.NumThreads
      config.ModelConfig.Provider = p.provider
      config.DecodingMethod = "greedy_search"
      config, err := offlineConfigForResolvedModel(resolved, p.provider)
      if err != nil {
         return nil, err
      }
      recognizer := sherpa.NewOfflineRecognizer(&config)
      if recognizer != nil {
         info := fmt.Sprintf("SenseVoice · %s", p.name)
         info := fmt.Sprintf("%s · %s", resolved.Profile.DisplayName, p.name)
         logger.Info("Engine initialized: %s", info)
         return &sherpaEngine{
            recognizer: recognizer,
@@ -45,6 +44,46 @@
   return nil, fmt.Errorf("failed to initialize sherpa-onnx with any provider")
}
func offlineConfigForResolvedModel(resolved model.ResolvedModel, provider string) (sherpa.OfflineRecognizerConfig, error) {
   config := sherpa.OfflineRecognizerConfig{}
   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.DecodingMethod = "greedy_search"
   switch resolved.BackendKind {
   case model.BackendSenseVoice:
      config.ModelConfig.SenseVoice.Model = resolved.Files["model"]
      config.ModelConfig.SenseVoice.UseInverseTextNormalization = 1
   case model.BackendMoonshine:
      config.ModelConfig.Moonshine.Preprocessor = resolved.Files["preprocessor"]
      config.ModelConfig.Moonshine.Encoder = resolved.Files["encoder"]
      config.ModelConfig.Moonshine.UncachedDecoder = resolved.Files["uncached_decoder"]
      config.ModelConfig.Moonshine.CachedDecoder = resolved.Files["cached_decoder"]
   case model.BackendNemoTransducer:
      config.ModelConfig.Transducer.Encoder = resolved.Files["encoder"]
      config.ModelConfig.Transducer.Decoder = resolved.Files["decoder"]
      config.ModelConfig.Transducer.Joiner = resolved.Files["joiner"]
      config.ModelConfig.ModelType = model.BackendNemoTransducer
   case model.BackendQwen3ASR:
      config.ModelConfig.Qwen3ASR.ConvFrontend = resolved.Files["conv_frontend"]
      config.ModelConfig.Qwen3ASR.Encoder = resolved.Files["encoder"]
      config.ModelConfig.Qwen3ASR.Decoder = resolved.Files["decoder"]
      config.ModelConfig.Qwen3ASR.Tokenizer = resolved.Files["tokenizer"]
      config.ModelConfig.Qwen3ASR.MaxTotalLen = 1024
      config.ModelConfig.Qwen3ASR.MaxNewTokens = 256
      config.ModelConfig.Qwen3ASR.Temperature = 0.0
      config.ModelConfig.Qwen3ASR.TopP = 0.9
      config.ModelConfig.Qwen3ASR.Seed = 0
   default:
      return sherpa.OfflineRecognizerConfig{}, fmt.Errorf("unsupported backend kind: %s", resolved.BackendKind)
   }
   return config, nil
}
func darwinProviders(providerOrder []string) []struct {
   name     string
   provider string