Add Dart API for Google MedAsr model (#2953)

This commit is contained in:
Fangjun Kuang 2025-12-29 12:49:06 +08:00 committed by GitHub
parent d2b8492c57
commit 14da0f6f76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 1237 additions and 879 deletions

View File

@ -74,6 +74,10 @@ popd
pushd non-streaming-asr
echo '----------MedASR CTC----------'
./run-medasr-ctc.sh
rm -rf sherpa-onnx-*
echo '----------Omnilingual ASR CTC----------'
./run-omnilingual-asr-ctc.sh
rm -rf sherpa-onnx-*

View File

@ -0,0 +1,54 @@
// Copyright (c) 2025 Xiaomi Corporation
import 'dart:io';
import 'package:args/args.dart';
import 'package:sherpa_onnx/sherpa_onnx.dart' as sherpa_onnx;
import './init.dart';
void main(List<String> arguments) async {
await initSherpaOnnx();
final parser = ArgParser()
..addOption('model', help: 'Path to the MedASR CTC model')
..addOption('tokens', help: 'Path to tokens.txt')
..addOption('input-wav', help: 'Path to input.wav to transcribe');
final res = parser.parse(arguments);
if (res['model'] == null ||
res['tokens'] == null ||
res['input-wav'] == null) {
print(parser.usage);
exit(1);
}
final model = res['model'] as String;
final tokens = res['tokens'] as String;
final inputWav = res['input-wav'] as String;
final medasr = sherpa_onnx.OfflineMedAsrCtcModelConfig(model: model);
final modelConfig = sherpa_onnx.OfflineModelConfig(
medasr: medasr,
tokens: tokens,
debug: true,
numThreads: 1,
);
final config = sherpa_onnx.OfflineRecognizerConfig(model: modelConfig);
final recognizer = sherpa_onnx.OfflineRecognizer(config);
final waveData = sherpa_onnx.readWave(inputWav);
final stream = recognizer.createStream();
stream.acceptWaveform(
samples: waveData.samples,
sampleRate: waveData.sampleRate,
);
recognizer.decode(stream);
final result = recognizer.getResult(stream);
print(result.text);
stream.free();
recognizer.free();
}

View File

@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -ex
dart pub get
if [ ! -f ./sherpa-onnx-medasr-ctc-en-int8-2025-12-25/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-medasr-ctc-en-int8-2025-12-25.tar.bz2
tar xvf sherpa-onnx-medasr-ctc-en-int8-2025-12-25.tar.bz2
rm sherpa-onnx-medasr-ctc-en-int8-2025-12-25.tar.bz2
fi
dart run \
./bin/medasr-ctc.dart \
--model ./sherpa-onnx-medasr-ctc-en-int8-2025-12-25/model.int8.onnx \
--tokens ./sherpa-onnx-medasr-ctc-en-int8-2025-12-25/tokens.txt \
--input-wav ./sherpa-onnx-medasr-ctc-en-int8-2025-12-25/test_wavs/0.wav

View File

@ -31,10 +31,10 @@ class OfflineTransducerModelConfig {
}
Map<String, dynamic> toJson() => {
'encoder': encoder,
'decoder': decoder,
'joiner': joiner,
};
'encoder': encoder,
'decoder': decoder,
'joiner': joiner,
};
final String encoder;
final String decoder;
@ -45,9 +45,7 @@ class OfflineParaformerModelConfig {
const OfflineParaformerModelConfig({this.model = ''});
factory OfflineParaformerModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineParaformerModelConfig(
model: json['model'] as String? ?? '',
);
return OfflineParaformerModelConfig(model: json['model'] as String? ?? '');
}
@override
@ -55,9 +53,7 @@ class OfflineParaformerModelConfig {
return 'OfflineParaformerModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -76,9 +72,7 @@ class OfflineNemoEncDecCtcModelConfig {
return 'OfflineNemoEncDecCtcModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -87,9 +81,7 @@ class OfflineDolphinModelConfig {
const OfflineDolphinModelConfig({this.model = ''});
factory OfflineDolphinModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineDolphinModelConfig(
model: json['model'] as String? ?? '',
);
return OfflineDolphinModelConfig(model: json['model'] as String? ?? '');
}
@override
@ -97,9 +89,7 @@ class OfflineDolphinModelConfig {
return 'OfflineDolphinModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -118,9 +108,7 @@ class OfflineZipformerCtcModelConfig {
return 'OfflineZipformerCtcModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -129,9 +117,7 @@ class OfflineWenetCtcModelConfig {
const OfflineWenetCtcModelConfig({this.model = ''});
factory OfflineWenetCtcModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineWenetCtcModelConfig(
model: json['model'] as String? ?? '',
);
return OfflineWenetCtcModelConfig(model: json['model'] as String? ?? '');
}
@override
@ -139,9 +125,7 @@ class OfflineWenetCtcModelConfig {
return 'OfflineWenetCtcModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -149,7 +133,9 @@ class OfflineWenetCtcModelConfig {
class OfflineOmnilingualAsrCtcModelConfig {
const OfflineOmnilingualAsrCtcModelConfig({this.model = ''});
factory OfflineOmnilingualAsrCtcModelConfig.fromJson(Map<String, dynamic> json) {
factory OfflineOmnilingualAsrCtcModelConfig.fromJson(
Map<String, dynamic> json,
) {
return OfflineOmnilingualAsrCtcModelConfig(
model: json['model'] as String? ?? '',
);
@ -160,20 +146,36 @@ class OfflineOmnilingualAsrCtcModelConfig {
return 'OfflineOmnilingualAsrCtcModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
class OfflineMedAsrCtcModelConfig {
const OfflineMedAsrCtcModelConfig({this.model = ''});
factory OfflineMedAsrCtcModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineMedAsrCtcModelConfig(model: json['model'] as String? ?? '');
}
@override
String toString() {
return 'OfflineMedAsrCtcModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
class OfflineWhisperModelConfig {
const OfflineWhisperModelConfig(
{this.encoder = '',
this.decoder = '',
this.language = '',
this.task = '',
this.tailPaddings = -1});
const OfflineWhisperModelConfig({
this.encoder = '',
this.decoder = '',
this.language = '',
this.task = '',
this.tailPaddings = -1,
});
factory OfflineWhisperModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineWhisperModelConfig(
@ -191,12 +193,12 @@ class OfflineWhisperModelConfig {
}
Map<String, dynamic> toJson() => {
'encoder': encoder,
'decoder': decoder,
'language': language,
'task': task,
'tailPaddings': tailPaddings,
};
'encoder': encoder,
'decoder': decoder,
'language': language,
'task': task,
'tailPaddings': tailPaddings,
};
final String encoder;
final String decoder;
@ -206,12 +208,13 @@ class OfflineWhisperModelConfig {
}
class OfflineCanaryModelConfig {
const OfflineCanaryModelConfig(
{this.encoder = '',
this.decoder = '',
this.srcLang = 'en',
this.tgtLang = 'en',
this.usePnc = true});
const OfflineCanaryModelConfig({
this.encoder = '',
this.decoder = '',
this.srcLang = 'en',
this.tgtLang = 'en',
this.usePnc = true,
});
factory OfflineCanaryModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineCanaryModelConfig(
@ -229,12 +232,12 @@ class OfflineCanaryModelConfig {
}
Map<String, dynamic> toJson() => {
'encoder': encoder,
'decoder': decoder,
'srcLang': srcLang,
'tgtLang': tgtLang,
'usePnc': usePnc,
};
'encoder': encoder,
'decoder': decoder,
'srcLang': srcLang,
'tgtLang': tgtLang,
'usePnc': usePnc,
};
final String encoder;
final String decoder;
@ -258,21 +261,19 @@ class OfflineFireRedAsrModelConfig {
return 'OfflineFireRedAsrModelConfig(encoder: $encoder, decoder: $decoder)';
}
Map<String, dynamic> toJson() => {
'encoder': encoder,
'decoder': decoder,
};
Map<String, dynamic> toJson() => {'encoder': encoder, 'decoder': decoder};
final String encoder;
final String decoder;
}
class OfflineMoonshineModelConfig {
const OfflineMoonshineModelConfig(
{this.preprocessor = '',
this.encoder = '',
this.uncachedDecoder = '',
this.cachedDecoder = ''});
const OfflineMoonshineModelConfig({
this.preprocessor = '',
this.encoder = '',
this.uncachedDecoder = '',
this.cachedDecoder = '',
});
factory OfflineMoonshineModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineMoonshineModelConfig(
@ -289,11 +290,11 @@ class OfflineMoonshineModelConfig {
}
Map<String, dynamic> toJson() => {
'preprocessor': preprocessor,
'encoder': encoder,
'uncachedDecoder': uncachedDecoder,
'cachedDecoder': cachedDecoder,
};
'preprocessor': preprocessor,
'encoder': encoder,
'uncachedDecoder': uncachedDecoder,
'cachedDecoder': cachedDecoder,
};
final String preprocessor;
final String encoder;
@ -305,9 +306,7 @@ class OfflineTdnnModelConfig {
const OfflineTdnnModelConfig({this.model = ''});
factory OfflineTdnnModelConfig.fromJson(Map<String, dynamic> json) {
return OfflineTdnnModelConfig(
model: json['model'] as String? ?? '',
);
return OfflineTdnnModelConfig(model: json['model'] as String? ?? '');
}
@override
@ -315,9 +314,7 @@ class OfflineTdnnModelConfig {
return 'OfflineTdnnModelConfig(model: $model)';
}
Map<String, dynamic> toJson() => {
'model': model,
};
Map<String, dynamic> toJson() => {'model': model};
final String model;
}
@ -344,10 +341,10 @@ class OfflineSenseVoiceModelConfig {
}
Map<String, dynamic> toJson() => {
'model': model,
'language': language,
'useInverseTextNormalization': useInverseTextNormalization,
};
'model': model,
'language': language,
'useInverseTextNormalization': useInverseTextNormalization,
};
final String model;
final String language;
@ -369,10 +366,7 @@ class OfflineLMConfig {
return 'OfflineLMConfig(model: $model, scale: $scale)';
}
Map<String, dynamic> toJson() => {
'model': model,
'scale': scale,
};
Map<String, dynamic> toJson() => {'model': model, 'scale': scale};
final String model;
final double scale;
@ -393,6 +387,7 @@ class OfflineModelConfig {
this.canary = const OfflineCanaryModelConfig(),
this.wenetCtc = const OfflineWenetCtcModelConfig(),
this.omnilingual = const OfflineOmnilingualAsrCtcModelConfig(),
this.medasr = const OfflineMedAsrCtcModelConfig(),
required this.tokens,
this.numThreads = 1,
this.debug = true,
@ -407,56 +402,74 @@ class OfflineModelConfig {
return OfflineModelConfig(
transducer: json['transducer'] != null
? OfflineTransducerModelConfig.fromJson(
json['transducer'] as Map<String, dynamic>)
json['transducer'] as Map<String, dynamic>,
)
: const OfflineTransducerModelConfig(),
paraformer: json['paraformer'] != null
? OfflineParaformerModelConfig.fromJson(
json['paraformer'] as Map<String, dynamic>)
json['paraformer'] as Map<String, dynamic>,
)
: const OfflineParaformerModelConfig(),
nemoCtc: json['nemoCtc'] != null
? OfflineNemoEncDecCtcModelConfig.fromJson(
json['nemoCtc'] as Map<String, dynamic>)
json['nemoCtc'] as Map<String, dynamic>,
)
: const OfflineNemoEncDecCtcModelConfig(),
whisper: json['whisper'] != null
? OfflineWhisperModelConfig.fromJson(
json['whisper'] as Map<String, dynamic>)
json['whisper'] as Map<String, dynamic>,
)
: const OfflineWhisperModelConfig(),
tdnn: json['tdnn'] != null
? OfflineTdnnModelConfig.fromJson(
json['tdnn'] as Map<String, dynamic>)
json['tdnn'] as Map<String, dynamic>,
)
: const OfflineTdnnModelConfig(),
senseVoice: json['senseVoice'] != null
? OfflineSenseVoiceModelConfig.fromJson(
json['senseVoice'] as Map<String, dynamic>)
json['senseVoice'] as Map<String, dynamic>,
)
: const OfflineSenseVoiceModelConfig(),
moonshine: json['moonshine'] != null
? OfflineMoonshineModelConfig.fromJson(
json['moonshine'] as Map<String, dynamic>)
json['moonshine'] as Map<String, dynamic>,
)
: const OfflineMoonshineModelConfig(),
fireRedAsr: json['fireRedAsr'] != null
? OfflineFireRedAsrModelConfig.fromJson(
json['fireRedAsr'] as Map<String, dynamic>)
json['fireRedAsr'] as Map<String, dynamic>,
)
: const OfflineFireRedAsrModelConfig(),
dolphin: json['dolphin'] != null
? OfflineDolphinModelConfig.fromJson(
json['dolphin'] as Map<String, dynamic>)
json['dolphin'] as Map<String, dynamic>,
)
: const OfflineDolphinModelConfig(),
zipformerCtc: json['zipformerCtc'] != null
? OfflineZipformerCtcModelConfig.fromJson(
json['zipformerCtc'] as Map<String, dynamic>)
json['zipformerCtc'] as Map<String, dynamic>,
)
: const OfflineZipformerCtcModelConfig(),
canary: json['canary'] != null
? OfflineCanaryModelConfig.fromJson(
json['canary'] as Map<String, dynamic>)
json['canary'] as Map<String, dynamic>,
)
: const OfflineCanaryModelConfig(),
wenetCtc: json['wenetCtc'] != null
? OfflineWenetCtcModelConfig.fromJson(
json['wenetCtc'] as Map<String, dynamic>)
json['wenetCtc'] as Map<String, dynamic>,
)
: const OfflineWenetCtcModelConfig(),
omnilingual: json['omnilingual'] != null
? OfflineOmnilingualAsrCtcModelConfig.fromJson(
json['omnilingual'] as Map<String, dynamic>)
json['omnilingual'] as Map<String, dynamic>,
)
: const OfflineOmnilingualAsrCtcModelConfig(),
medasr: json['medasr'] != null
? OfflineMedAsrCtcModelConfig.fromJson(
json['medasr'] as Map<String, dynamic>,
)
: const OfflineMedAsrCtcModelConfig(),
tokens: json['tokens'] as String,
numThreads: json['numThreads'] as int? ?? 1,
debug: json['debug'] as bool? ?? true,
@ -470,32 +483,33 @@ class OfflineModelConfig {
@override
String toString() {
return 'OfflineModelConfig(transducer: $transducer, paraformer: $paraformer, nemoCtc: $nemoCtc, whisper: $whisper, tdnn: $tdnn, senseVoice: $senseVoice, moonshine: $moonshine, fireRedAsr: $fireRedAsr, dolphin: $dolphin, zipformerCtc: $zipformerCtc, canary: $canary, wenetCtc: $wenetCtc, omnilingual: $omnilingual, tokens: $tokens, numThreads: $numThreads, debug: $debug, provider: $provider, modelType: $modelType, modelingUnit: $modelingUnit, bpeVocab: $bpeVocab, telespeechCtc: $telespeechCtc)';
return 'OfflineModelConfig(transducer: $transducer, paraformer: $paraformer, nemoCtc: $nemoCtc, whisper: $whisper, tdnn: $tdnn, senseVoice: $senseVoice, moonshine: $moonshine, fireRedAsr: $fireRedAsr, dolphin: $dolphin, zipformerCtc: $zipformerCtc, canary: $canary, wenetCtc: $wenetCtc, omnilingual: $omnilingual, medasr: $medasr, tokens: $tokens, numThreads: $numThreads, debug: $debug, provider: $provider, modelType: $modelType, modelingUnit: $modelingUnit, bpeVocab: $bpeVocab, telespeechCtc: $telespeechCtc)';
}
Map<String, dynamic> toJson() => {
'transducer': transducer.toJson(),
'paraformer': paraformer.toJson(),
'nemoCtc': nemoCtc.toJson(),
'whisper': whisper.toJson(),
'tdnn': tdnn.toJson(),
'senseVoice': senseVoice.toJson(),
'moonshine': moonshine.toJson(),
'fireRedAsr': fireRedAsr.toJson(),
'dolphin': dolphin.toJson(),
'zipformerCtc': zipformerCtc.toJson(),
'canary': canary.toJson(),
'wenetCtc': wenetCtc.toJson(),
'omnilingual': omnilingual.toJson(),
'tokens': tokens,
'numThreads': numThreads,
'debug': debug,
'provider': provider,
'modelType': modelType,
'modelingUnit': modelingUnit,
'bpeVocab': bpeVocab,
'telespeechCtc': telespeechCtc,
};
'transducer': transducer.toJson(),
'paraformer': paraformer.toJson(),
'nemoCtc': nemoCtc.toJson(),
'whisper': whisper.toJson(),
'tdnn': tdnn.toJson(),
'senseVoice': senseVoice.toJson(),
'moonshine': moonshine.toJson(),
'fireRedAsr': fireRedAsr.toJson(),
'dolphin': dolphin.toJson(),
'zipformerCtc': zipformerCtc.toJson(),
'canary': canary.toJson(),
'wenetCtc': wenetCtc.toJson(),
'omnilingual': omnilingual.toJson(),
'medasr': medasr.toJson(),
'tokens': tokens,
'numThreads': numThreads,
'debug': debug,
'provider': provider,
'modelType': modelType,
'modelingUnit': modelingUnit,
'bpeVocab': bpeVocab,
'telespeechCtc': telespeechCtc,
};
final OfflineTransducerModelConfig transducer;
final OfflineParaformerModelConfig paraformer;
@ -510,6 +524,7 @@ class OfflineModelConfig {
final OfflineCanaryModelConfig canary;
final OfflineWenetCtcModelConfig wenetCtc;
final OfflineOmnilingualAsrCtcModelConfig omnilingual;
final OfflineMedAsrCtcModelConfig medasr;
final String tokens;
final int numThreads;
@ -562,18 +577,18 @@ class OfflineRecognizerConfig {
}
Map<String, dynamic> toJson() => {
'feat': feat.toJson(),
'model': model.toJson(),
'lm': lm.toJson(),
'decodingMethod': decodingMethod,
'maxActivePaths': maxActivePaths,
'hotwordsFile': hotwordsFile,
'hotwordsScore': hotwordsScore,
'ruleFsts': ruleFsts,
'ruleFars': ruleFars,
'blankPenalty': blankPenalty,
'hr': hr.toJson(),
};
'feat': feat.toJson(),
'model': model.toJson(),
'lm': lm.toJson(),
'decodingMethod': decodingMethod,
'maxActivePaths': maxActivePaths,
'hotwordsFile': hotwordsFile,
'hotwordsScore': hotwordsScore,
'ruleFsts': ruleFsts,
'ruleFars': ruleFars,
'blankPenalty': blankPenalty,
'hr': hr.toJson(),
};
final FeatureConfig feat;
final OfflineModelConfig model;
@ -594,19 +609,21 @@ class OfflineRecognizerConfig {
}
class OfflineRecognizerResult {
OfflineRecognizerResult(
{required this.text,
required this.tokens,
required this.timestamps,
required this.lang,
required this.emotion,
required this.event});
OfflineRecognizerResult({
required this.text,
required this.tokens,
required this.timestamps,
required this.lang,
required this.emotion,
required this.event,
});
factory OfflineRecognizerResult.fromJson(Map<String, dynamic> json) {
return OfflineRecognizerResult(
text: json['text'] as String? ?? '',
tokens: (json['tokens'] as List?)?.map((e) => e as String).toList() ?? [],
timestamps: (json['timestamps'] as List?)
timestamps:
(json['timestamps'] as List?)
?.map((e) => (e as num).toDouble())
.toList() ??
[],
@ -622,13 +639,13 @@ class OfflineRecognizerResult {
}
Map<String, dynamic> toJson() => {
'text': text,
'tokens': tokens,
'timestamps': timestamps,
'lang': lang,
'emotion': emotion,
'event': event,
};
'text': text,
'tokens': tokens,
'timestamps': timestamps,
'lang': lang,
'emotion': emotion,
'event': event,
};
final String text;
final List<String> tokens;
@ -662,7 +679,8 @@ class OfflineRecognizer {
if (ptr == nullptr) {
throw Exception(
"Failed to create offline recognizer. Please check your config");
"Failed to create offline recognizer. Please check your config",
);
}
freeConfig(c);
@ -680,19 +698,20 @@ class OfflineRecognizer {
}
static Pointer<SherpaOnnxOfflineRecognizerConfig> convertConfig(
OfflineRecognizerConfig config) {
OfflineRecognizerConfig config,
) {
final c = calloc<SherpaOnnxOfflineRecognizerConfig>();
c.ref.feat.sampleRate = config.feat.sampleRate;
c.ref.feat.featureDim = config.feat.featureDim;
// transducer
c.ref.model.transducer.encoder =
config.model.transducer.encoder.toNativeUtf8();
c.ref.model.transducer.decoder =
config.model.transducer.decoder.toNativeUtf8();
c.ref.model.transducer.joiner =
config.model.transducer.joiner.toNativeUtf8();
c.ref.model.transducer.encoder = config.model.transducer.encoder
.toNativeUtf8();
c.ref.model.transducer.decoder = config.model.transducer.decoder
.toNativeUtf8();
c.ref.model.transducer.joiner = config.model.transducer.joiner
.toNativeUtf8();
// paraformer
c.ref.model.paraformer.model = config.model.paraformer.model.toNativeUtf8();
@ -715,30 +734,33 @@ class OfflineRecognizer {
c.ref.model.senseVoice.model = config.model.senseVoice.model.toNativeUtf8();
c.ref.model.senseVoice.language =
config.model.senseVoice.language.toNativeUtf8();
c.ref.model.senseVoice.language = config.model.senseVoice.language
.toNativeUtf8();
c.ref.model.senseVoice.useInverseTextNormalization =
config.model.senseVoice.useInverseTextNormalization ? 1 : 0;
c.ref.model.moonshine.preprocessor =
config.model.moonshine.preprocessor.toNativeUtf8();
c.ref.model.moonshine.encoder =
config.model.moonshine.encoder.toNativeUtf8();
c.ref.model.moonshine.uncachedDecoder =
config.model.moonshine.uncachedDecoder.toNativeUtf8();
c.ref.model.moonshine.cachedDecoder =
config.model.moonshine.cachedDecoder.toNativeUtf8();
c.ref.model.moonshine.preprocessor = config.model.moonshine.preprocessor
.toNativeUtf8();
c.ref.model.moonshine.encoder = config.model.moonshine.encoder
.toNativeUtf8();
c.ref.model.moonshine.uncachedDecoder = config
.model
.moonshine
.uncachedDecoder
.toNativeUtf8();
c.ref.model.moonshine.cachedDecoder = config.model.moonshine.cachedDecoder
.toNativeUtf8();
// FireRedAsr
c.ref.model.fireRedAsr.encoder =
config.model.fireRedAsr.encoder.toNativeUtf8();
c.ref.model.fireRedAsr.decoder =
config.model.fireRedAsr.decoder.toNativeUtf8();
c.ref.model.fireRedAsr.encoder = config.model.fireRedAsr.encoder
.toNativeUtf8();
c.ref.model.fireRedAsr.decoder = config.model.fireRedAsr.decoder
.toNativeUtf8();
c.ref.model.dolphin.model = config.model.dolphin.model.toNativeUtf8();
c.ref.model.zipformerCtc.model =
config.model.zipformerCtc.model.toNativeUtf8();
c.ref.model.zipformerCtc.model = config.model.zipformerCtc.model
.toNativeUtf8();
c.ref.model.canary.encoder = config.model.canary.encoder.toNativeUtf8();
c.ref.model.canary.decoder = config.model.canary.decoder.toNativeUtf8();
@ -747,7 +769,9 @@ class OfflineRecognizer {
c.ref.model.canary.usePnc = config.model.canary.usePnc ? 1 : 0;
c.ref.model.wenetCtc.model = config.model.wenetCtc.model.toNativeUtf8();
c.ref.model.omnilingual.model = config.model.omnilingual.model.toNativeUtf8();
c.ref.model.omnilingual.model = config.model.omnilingual.model
.toNativeUtf8();
c.ref.model.medasr.model = config.model.medasr.model.toNativeUtf8();
c.ref.model.tokens = config.model.tokens.toNativeUtf8();
@ -793,6 +817,7 @@ class OfflineRecognizer {
calloc.free(c.ref.model.modelType);
calloc.free(c.ref.model.provider);
calloc.free(c.ref.model.tokens);
calloc.free(c.ref.model.medasr.model);
calloc.free(c.ref.model.omnilingual.model);
calloc.free(c.ref.model.wenetCtc.model);
calloc.free(c.ref.model.canary.tgtLang);
@ -836,15 +861,16 @@ class OfflineRecognizer {
OfflineRecognizerResult getResult(OfflineStream stream) {
final json =
SherpaOnnxBindings.getOfflineStreamResultAsJson?.call(stream.ptr) ??
nullptr;
nullptr;
if (json == nullptr) {
return OfflineRecognizerResult(
text: '',
tokens: [],
timestamps: [],
lang: '',
emotion: '',
event: '');
text: '',
tokens: [],
timestamps: [],
lang: '',
emotion: '',
event: '',
);
}
final parsedJson = jsonDecode(toDartString(json));
@ -852,12 +878,13 @@ class OfflineRecognizer {
SherpaOnnxBindings.destroyOfflineStreamResultJson?.call(json);
return OfflineRecognizerResult(
text: parsedJson['text'],
tokens: List<String>.from(parsedJson['tokens']),
timestamps: List<double>.from(parsedJson['timestamps']),
lang: parsedJson['lang'],
emotion: parsedJson['emotion'],
event: parsedJson['event']);
text: parsedJson['text'],
tokens: List<String>.from(parsedJson['tokens']),
timestamps: List<double>.from(parsedJson['timestamps']),
lang: parsedJson['lang'],
emotion: parsedJson['emotion'],
event: parsedJson['event'],
);
}
Pointer<SherpaOnnxOfflineRecognizer> ptr;

File diff suppressed because it is too large Load Diff