diff --git a/flutter/sherpa_onnx/lib/src/audio_tagging.dart b/flutter/sherpa_onnx/lib/src/audio_tagging.dart index 3e3dbed2..2e3e30ed 100644 --- a/flutter/sherpa_onnx/lib/src/audio_tagging.dart +++ b/flutter/sherpa_onnx/lib/src/audio_tagging.dart @@ -8,11 +8,24 @@ import './sherpa_onnx_bindings.dart'; class OfflineZipformerAudioTaggingModelConfig { const OfflineZipformerAudioTaggingModelConfig({this.model = ''}); + factory OfflineZipformerAudioTaggingModelConfig.fromJson( + Map map) { + return OfflineZipformerAudioTaggingModelConfig( + model: map['model'] ?? '', + ); + } + @override String toString() { return 'OfflineZipformerAudioTaggingModelConfig(model: $model)'; } + Map toJson() { + return { + 'model': model, + }; + } + final String model; } @@ -24,11 +37,32 @@ class AudioTaggingModelConfig { this.provider = 'cpu', this.debug = true}); + factory AudioTaggingModelConfig.fromJson(Map map) { + return AudioTaggingModelConfig( + zipformer: + OfflineZipformerAudioTaggingModelConfig.fromJson(map['zipformer']), + ced: map['ced'] ?? '', + numThreads: map['numThreads'] ?? 1, + provider: map['provider'] ?? 'cpu', + debug: map['debug'] ?? true, + ); + } + @override String toString() { return 'AudioTaggingModelConfig(zipformer: $zipformer, ced: $ced, numThreads: $numThreads, provider: $provider, debug: $debug)'; } + Map toJson() { + return { + 'zipformer': zipformer.toJson(), + 'ced': ced, + 'numThreads': numThreads, + 'provider': provider, + 'debug': debug, + }; + } + final OfflineZipformerAudioTaggingModelConfig zipformer; final String ced; final int numThreads; @@ -39,11 +73,25 @@ class AudioTaggingModelConfig { class AudioTaggingConfig { AudioTaggingConfig({required this.model, this.labels = ''}); + factory AudioTaggingConfig.fromJson(Map map) { + return AudioTaggingConfig( + model: AudioTaggingModelConfig.fromJson(map['model']), + labels: map['labels'] ?? '', + ); + } + @override String toString() { return 'AudioTaggingConfig(model: $model, labels: $labels)'; } + Map toJson() { + return { + 'model': model.toJson(), + 'labels': labels, + }; + } + final AudioTaggingModelConfig model; final String labels; } @@ -51,11 +99,27 @@ class AudioTaggingConfig { class AudioEvent { AudioEvent({required this.name, required this.index, required this.prob}); + factory AudioEvent.fromJson(Map map) { + return AudioEvent( + name: map['name'], + index: map['index'], + prob: map['prob'], + ); + } + @override String toString() { return 'AudioEvent(name: $name, index: $index, prob: $prob)'; } + Map toJson() { + return { + 'name': name, + 'index': index, + 'prob': prob, + }; + } + final String name; final int index; final double prob; diff --git a/flutter/sherpa_onnx/lib/src/feature_config.dart b/flutter/sherpa_onnx/lib/src/feature_config.dart index 2af7f2cc..01474698 100644 --- a/flutter/sherpa_onnx/lib/src/feature_config.dart +++ b/flutter/sherpa_onnx/lib/src/feature_config.dart @@ -3,11 +3,23 @@ class FeatureConfig { const FeatureConfig({this.sampleRate = 16000, this.featureDim = 80}); + factory FeatureConfig.fromJson(Map json) { + return FeatureConfig( + sampleRate: json['sampleRate'] as int? ?? 16000, + featureDim: json['featureDim'] as int? ?? 80, + ); + } + @override String toString() { return 'FeatureConfig(sampleRate: $sampleRate, featureDim: $featureDim)'; } + Map toJson() => { + 'sampleRate': sampleRate, + 'featureDim': featureDim, + }; + final int sampleRate; final int featureDim; } diff --git a/flutter/sherpa_onnx/lib/src/keyword_spotter.dart b/flutter/sherpa_onnx/lib/src/keyword_spotter.dart index 310657d1..4580b8e3 100644 --- a/flutter/sherpa_onnx/lib/src/keyword_spotter.dart +++ b/flutter/sherpa_onnx/lib/src/keyword_spotter.dart @@ -23,11 +23,40 @@ class KeywordSpotterConfig { this.keywordsBufSize = 0, }); + factory KeywordSpotterConfig.fromJson(Map json) { + return KeywordSpotterConfig( + feat: json['feat'] != null + ? FeatureConfig.fromJson(json['feat'] as Map) + : const FeatureConfig(), + model: OnlineModelConfig.fromJson(json['model'] as Map), + maxActivePaths: json['maxActivePaths'] as int? ?? 4, + numTrailingBlanks: json['numTrailingBlanks'] as int? ?? 1, + keywordsScore: (json['keywordsScore'] as num?)?.toDouble() ?? 1.0, + keywordsThreshold: + (json['keywordsThreshold'] as num?)?.toDouble() ?? 0.25, + keywordsFile: json['keywordsFile'] as String? ?? '', + keywordsBuf: json['keywordsBuf'] as String? ?? '', + keywordsBufSize: json['keywordsBufSize'] as int? ?? 0, + ); + } + @override String toString() { return 'KeywordSpotterConfig(feat: $feat, model: $model, maxActivePaths: $maxActivePaths, numTrailingBlanks: $numTrailingBlanks, keywordsScore: $keywordsScore, keywordsThreshold: $keywordsThreshold, keywordsFile: $keywordsFile, keywordsBuf: $keywordsBuf, keywordsBufSize: $keywordsBufSize)'; } + Map toJson() => { + 'feat': feat.toJson(), + 'model': model.toJson(), + 'maxActivePaths': maxActivePaths, + 'numTrailingBlanks': numTrailingBlanks, + 'keywordsScore': keywordsScore, + 'keywordsThreshold': keywordsThreshold, + 'keywordsFile': keywordsFile, + 'keywordsBuf': keywordsBuf, + 'keywordsBufSize': keywordsBufSize, + }; + final FeatureConfig feat; final OnlineModelConfig model; @@ -44,11 +73,21 @@ class KeywordSpotterConfig { class KeywordResult { KeywordResult({required this.keyword}); + factory KeywordResult.fromJson(Map json) { + return KeywordResult( + keyword: json['keyword'] as String? ?? '', + ); + } + @override String toString() { return 'KeywordResult(keyword: $keyword)'; } + Map toJson() => { + 'keyword': keyword, + }; + final String keyword; } diff --git a/flutter/sherpa_onnx/lib/src/offline_punctuation.dart b/flutter/sherpa_onnx/lib/src/offline_punctuation.dart index dd38a244..a50073e0 100644 --- a/flutter/sherpa_onnx/lib/src/offline_punctuation.dart +++ b/flutter/sherpa_onnx/lib/src/offline_punctuation.dart @@ -11,11 +11,27 @@ class OfflinePunctuationModelConfig { this.provider = 'cpu', this.debug = true}); + factory OfflinePunctuationModelConfig.fromJson(Map json) { + return OfflinePunctuationModelConfig( + ctTransformer: json['ctTransformer'] as String, + numThreads: json['numThreads'] as int? ?? 1, + provider: json['provider'] as String? ?? 'cpu', + debug: json['debug'] as bool? ?? true, + ); + } + @override String toString() { return 'OfflinePunctuationModelConfig(ctTransformer: $ctTransformer, numThreads: $numThreads, provider: $provider, debug: $debug)'; } + Map toJson() => { + 'ctTransformer': ctTransformer, + 'numThreads': numThreads, + 'provider': provider, + 'debug': debug, + }; + final String ctTransformer; final int numThreads; final String provider; @@ -27,11 +43,22 @@ class OfflinePunctuationConfig { required this.model, }); + factory OfflinePunctuationConfig.fromJson(Map json) { + return OfflinePunctuationConfig( + model: OfflinePunctuationModelConfig.fromJson( + json['model'] as Map), + ); + } + @override String toString() { return 'OfflinePunctuationConfig(model: $model)'; } + Map toJson() => { + 'model': model.toJson(), + }; + final OfflinePunctuationModelConfig model; } diff --git a/flutter/sherpa_onnx/lib/src/offline_recognizer.dart b/flutter/sherpa_onnx/lib/src/offline_recognizer.dart index e7a68845..e7bbaf8c 100644 --- a/flutter/sherpa_onnx/lib/src/offline_recognizer.dart +++ b/flutter/sherpa_onnx/lib/src/offline_recognizer.dart @@ -16,11 +16,25 @@ class OfflineTransducerModelConfig { this.joiner = '', }); + factory OfflineTransducerModelConfig.fromJson(Map json) { + return OfflineTransducerModelConfig( + encoder: json['encoder'] as String? ?? '', + decoder: json['decoder'] as String? ?? '', + joiner: json['joiner'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineTransducerModelConfig(encoder: $encoder, decoder: $decoder, joiner: $joiner)'; } + Map toJson() => { + 'encoder': encoder, + 'decoder': decoder, + 'joiner': joiner, + }; + final String encoder; final String decoder; final String joiner; @@ -29,22 +43,42 @@ class OfflineTransducerModelConfig { class OfflineParaformerModelConfig { const OfflineParaformerModelConfig({this.model = ''}); + factory OfflineParaformerModelConfig.fromJson(Map json) { + return OfflineParaformerModelConfig( + model: json['model'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineParaformerModelConfig(model: $model)'; } + Map toJson() => { + 'model': model, + }; + final String model; } class OfflineNemoEncDecCtcModelConfig { const OfflineNemoEncDecCtcModelConfig({this.model = ''}); + factory OfflineNemoEncDecCtcModelConfig.fromJson(Map json) { + return OfflineNemoEncDecCtcModelConfig( + model: json['model'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineNemoEncDecCtcModelConfig(model: $model)'; } + Map toJson() => { + 'model': model, + }; + final String model; } @@ -56,11 +90,29 @@ class OfflineWhisperModelConfig { this.task = '', this.tailPaddings = -1}); + factory OfflineWhisperModelConfig.fromJson(Map json) { + return OfflineWhisperModelConfig( + encoder: json['encoder'] as String? ?? '', + decoder: json['decoder'] as String? ?? '', + language: json['language'] as String? ?? '', + task: json['task'] as String? ?? '', + tailPaddings: json['tailPaddings'] as int? ?? -1, + ); + } + @override String toString() { return 'OfflineWhisperModelConfig(encoder: $encoder, decoder: $decoder, language: $language, task: $task, tailPaddings: $tailPaddings)'; } + Map toJson() => { + 'encoder': encoder, + 'decoder': decoder, + 'language': language, + 'task': task, + 'tailPaddings': tailPaddings, + }; + final String encoder; final String decoder; final String language; @@ -69,15 +121,25 @@ class OfflineWhisperModelConfig { } class OfflineFireRedAsrModelConfig { - const OfflineFireRedAsrModelConfig( - {this.encoder = '', - this.decoder = ''}); + const OfflineFireRedAsrModelConfig({this.encoder = '', this.decoder = ''}); + + factory OfflineFireRedAsrModelConfig.fromJson(Map json) { + return OfflineFireRedAsrModelConfig( + encoder: json['encoder'] as String? ?? '', + decoder: json['decoder'] as String? ?? '', + ); + } @override String toString() { return 'OfflineFireRedAsrModelConfig(encoder: $encoder, decoder: $decoder)'; } + Map toJson() => { + 'encoder': encoder, + 'decoder': decoder, + }; + final String encoder; final String decoder; } @@ -89,11 +151,27 @@ class OfflineMoonshineModelConfig { this.uncachedDecoder = '', this.cachedDecoder = ''}); + factory OfflineMoonshineModelConfig.fromJson(Map json) { + return OfflineMoonshineModelConfig( + preprocessor: json['preprocessor'] as String? ?? '', + encoder: json['encoder'] as String? ?? '', + uncachedDecoder: json['uncachedDecoder'] as String? ?? '', + cachedDecoder: json['cachedDecoder'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineMoonshineModelConfig(preprocessor: $preprocessor, encoder: $encoder, uncachedDecoder: $uncachedDecoder, cachedDecoder: $cachedDecoder)'; } + Map toJson() => { + 'preprocessor': preprocessor, + 'encoder': encoder, + 'uncachedDecoder': uncachedDecoder, + 'cachedDecoder': cachedDecoder, + }; + final String preprocessor; final String encoder; final String uncachedDecoder; @@ -103,11 +181,21 @@ class OfflineMoonshineModelConfig { class OfflineTdnnModelConfig { const OfflineTdnnModelConfig({this.model = ''}); + factory OfflineTdnnModelConfig.fromJson(Map json) { + return OfflineTdnnModelConfig( + model: json['model'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineTdnnModelConfig(model: $model)'; } + Map toJson() => { + 'model': model, + }; + final String model; } @@ -118,11 +206,26 @@ class OfflineSenseVoiceModelConfig { this.useInverseTextNormalization = false, }); + factory OfflineSenseVoiceModelConfig.fromJson(Map json) { + return OfflineSenseVoiceModelConfig( + model: json['model'] as String? ?? '', + language: json['language'] as String? ?? '', + useInverseTextNormalization: + json['useInverseTextNormalization'] as bool? ?? false, + ); + } + @override String toString() { return 'OfflineSenseVoiceModelConfig(model: $model, language: $language, useInverseTextNormalization: $useInverseTextNormalization)'; } + Map toJson() => { + 'model': model, + 'language': language, + 'useInverseTextNormalization': useInverseTextNormalization, + }; + final String model; final String language; final bool useInverseTextNormalization; @@ -131,11 +234,23 @@ class OfflineSenseVoiceModelConfig { class OfflineLMConfig { const OfflineLMConfig({this.model = '', this.scale = 1.0}); + factory OfflineLMConfig.fromJson(Map json) { + return OfflineLMConfig( + model: json['model'] as String? ?? '', + scale: (json['scale'] as num?)?.toDouble() ?? 1.0, + ); + } + @override String toString() { return 'OfflineLMConfig(model: $model, scale: $scale)'; } + Map toJson() => { + 'model': model, + 'scale': scale, + }; + final String model; final double scale; } @@ -160,11 +275,75 @@ class OfflineModelConfig { this.telespeechCtc = '', }); + factory OfflineModelConfig.fromJson(Map json) { + return OfflineModelConfig( + transducer: json['transducer'] != null + ? OfflineTransducerModelConfig.fromJson( + json['transducer'] as Map) + : const OfflineTransducerModelConfig(), + paraformer: json['paraformer'] != null + ? OfflineParaformerModelConfig.fromJson( + json['paraformer'] as Map) + : const OfflineParaformerModelConfig(), + nemoCtc: json['nemoCtc'] != null + ? OfflineNemoEncDecCtcModelConfig.fromJson( + json['nemoCtc'] as Map) + : const OfflineNemoEncDecCtcModelConfig(), + whisper: json['whisper'] != null + ? OfflineWhisperModelConfig.fromJson( + json['whisper'] as Map) + : const OfflineWhisperModelConfig(), + tdnn: json['tdnn'] != null + ? OfflineTdnnModelConfig.fromJson( + json['tdnn'] as Map) + : const OfflineTdnnModelConfig(), + senseVoice: json['senseVoice'] != null + ? OfflineSenseVoiceModelConfig.fromJson( + json['senseVoice'] as Map) + : const OfflineSenseVoiceModelConfig(), + moonshine: json['moonshine'] != null + ? OfflineMoonshineModelConfig.fromJson( + json['moonshine'] as Map) + : const OfflineMoonshineModelConfig(), + fireRedAsr: json['fireRedAsr'] != null + ? OfflineFireRedAsrModelConfig.fromJson( + json['fireRedAsr'] as Map) + : const OfflineFireRedAsrModelConfig(), + tokens: json['tokens'] as String, + numThreads: json['numThreads'] as int? ?? 1, + debug: json['debug'] as bool? ?? true, + provider: json['provider'] as String? ?? 'cpu', + modelType: json['modelType'] as String? ?? '', + modelingUnit: json['modelingUnit'] as String? ?? '', + bpeVocab: json['bpeVocab'] as String? ?? '', + telespeechCtc: json['telespeechCtc'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineModelConfig(transducer: $transducer, paraformer: $paraformer, nemoCtc: $nemoCtc, whisper: $whisper, tdnn: $tdnn, senseVoice: $senseVoice, moonshine: $moonshine, fireRedAsr: $fireRedAsr, tokens: $tokens, numThreads: $numThreads, debug: $debug, provider: $provider, modelType: $modelType, modelingUnit: $modelingUnit, bpeVocab: $bpeVocab, telespeechCtc: $telespeechCtc)'; } + Map 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(), + 'tokens': tokens, + 'numThreads': numThreads, + 'debug': debug, + 'provider': provider, + 'modelType': modelType, + 'modelingUnit': modelingUnit, + 'bpeVocab': bpeVocab, + 'telespeechCtc': telespeechCtc, + }; + final OfflineTransducerModelConfig transducer; final OfflineParaformerModelConfig paraformer; final OfflineNemoEncDecCtcModelConfig nemoCtc; @@ -198,11 +377,43 @@ class OfflineRecognizerConfig { this.blankPenalty = 0.0, }); + factory OfflineRecognizerConfig.fromJson(Map json) { + return OfflineRecognizerConfig( + feat: json['feat'] != null + ? FeatureConfig.fromJson(json['feat'] as Map) + : const FeatureConfig(), + model: OfflineModelConfig.fromJson(json['model'] as Map), + lm: json['lm'] != null + ? OfflineLMConfig.fromJson(json['lm'] as Map) + : const OfflineLMConfig(), + decodingMethod: json['decodingMethod'] as String? ?? 'greedy_search', + maxActivePaths: json['maxActivePaths'] as int? ?? 4, + hotwordsFile: json['hotwordsFile'] as String? ?? '', + hotwordsScore: (json['hotwordsScore'] as num?)?.toDouble() ?? 1.5, + ruleFsts: json['ruleFsts'] as String? ?? '', + ruleFars: json['ruleFars'] as String? ?? '', + blankPenalty: (json['blankPenalty'] as num?)?.toDouble() ?? 0.0, + ); + } + @override String toString() { return 'OfflineRecognizerConfig(feat: $feat, model: $model, lm: $lm, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ruleFsts: $ruleFsts, ruleFars: $ruleFars, blankPenalty: $blankPenalty)'; } + Map toJson() => { + 'feat': feat.toJson(), + 'model': model.toJson(), + 'lm': lm.toJson(), + 'decodingMethod': decodingMethod, + 'maxActivePaths': maxActivePaths, + 'hotwordsFile': hotwordsFile, + 'hotwordsScore': hotwordsScore, + 'ruleFsts': ruleFsts, + 'ruleFars': ruleFars, + 'blankPenalty': blankPenalty, + }; + final FeatureConfig feat; final OfflineModelConfig model; final OfflineLMConfig lm; @@ -229,11 +440,34 @@ class OfflineRecognizerResult { required this.emotion, required this.event}); + factory OfflineRecognizerResult.fromJson(Map json) { + return OfflineRecognizerResult( + text: json['text'] as String? ?? '', + tokens: (json['tokens'] as List?)?.map((e) => e as String).toList() ?? [], + timestamps: (json['timestamps'] as List?) + ?.map((e) => (e as num).toDouble()) + .toList() ?? + [], + lang: json['lang'] as String? ?? '', + emotion: json['emotion'] as String? ?? '', + event: json['event'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineRecognizerResult(text: $text, tokens: $tokens, timestamps: $timestamps, lang: $lang, emotion: $emotion, event: $event)'; } + Map toJson() => { + 'text': text, + 'tokens': tokens, + 'timestamps': timestamps, + 'lang': lang, + 'emotion': emotion, + 'event': event, + }; + final String text; final List tokens; final List timestamps; @@ -305,8 +539,10 @@ class OfflineRecognizer { 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.tokens = config.model.tokens.toNativeUtf8(); diff --git a/flutter/sherpa_onnx/lib/src/offline_speaker_diarization.dart b/flutter/sherpa_onnx/lib/src/offline_speaker_diarization.dart index fe046a16..6ee72f9f 100644 --- a/flutter/sherpa_onnx/lib/src/offline_speaker_diarization.dart +++ b/flutter/sherpa_onnx/lib/src/offline_speaker_diarization.dart @@ -14,11 +14,25 @@ class OfflineSpeakerDiarizationSegment { required this.speaker, }); + factory OfflineSpeakerDiarizationSegment.fromJson(Map json) { + return OfflineSpeakerDiarizationSegment( + start: (json['start'] as num).toDouble(), + end: (json['end'] as num).toDouble(), + speaker: json['speaker'] as int, + ); + } + @override String toString() { return 'OfflineSpeakerDiarizationSegment(start: $start, end: $end, speaker: $speaker)'; } + Map toJson() => { + 'start': start, + 'end': end, + 'speaker': speaker, + }; + final double start; final double end; final int speaker; @@ -29,11 +43,22 @@ class OfflineSpeakerSegmentationPyannoteModelConfig { this.model = '', }); + factory OfflineSpeakerSegmentationPyannoteModelConfig.fromJson( + Map json) { + return OfflineSpeakerSegmentationPyannoteModelConfig( + model: json['model'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineSpeakerSegmentationPyannoteModelConfig(model: $model)'; } + Map toJson() => { + 'model': model, + }; + final String model; } @@ -45,11 +70,31 @@ class OfflineSpeakerSegmentationModelConfig { this.provider = 'cpu', }); + factory OfflineSpeakerSegmentationModelConfig.fromJson( + Map json) { + return OfflineSpeakerSegmentationModelConfig( + pyannote: json['pyannote'] != null + ? OfflineSpeakerSegmentationPyannoteModelConfig.fromJson( + json['pyannote'] as Map) + : const OfflineSpeakerSegmentationPyannoteModelConfig(), + numThreads: json['numThreads'] as int? ?? 1, + debug: json['debug'] as bool? ?? true, + provider: json['provider'] as String? ?? 'cpu', + ); + } + @override String toString() { return 'OfflineSpeakerSegmentationModelConfig(pyannote: $pyannote, numThreads: $numThreads, debug: $debug, provider: $provider)'; } + Map toJson() => { + 'pyannote': pyannote.toJson(), + 'numThreads': numThreads, + 'debug': debug, + 'provider': provider, + }; + final OfflineSpeakerSegmentationPyannoteModelConfig pyannote; final int numThreads; @@ -63,11 +108,23 @@ class FastClusteringConfig { this.threshold = 0.5, }); + factory FastClusteringConfig.fromJson(Map json) { + return FastClusteringConfig( + numClusters: json['numClusters'] as int? ?? -1, + threshold: (json['threshold'] as num?)?.toDouble() ?? 0.5, + ); + } + @override String toString() { return 'FastClusteringConfig(numClusters: $numClusters, threshold: $threshold)'; } + Map toJson() => { + 'numClusters': numClusters, + 'threshold': threshold, + }; + final int numClusters; final double threshold; } @@ -81,11 +138,38 @@ class OfflineSpeakerDiarizationConfig { this.minDurationOff = 0.5, }); + factory OfflineSpeakerDiarizationConfig.fromJson(Map json) { + return OfflineSpeakerDiarizationConfig( + segmentation: json['segmentation'] != null + ? OfflineSpeakerSegmentationModelConfig.fromJson( + json['segmentation'] as Map) + : const OfflineSpeakerSegmentationModelConfig(), + embedding: json['embedding'] != null + ? SpeakerEmbeddingExtractorConfig.fromJson( + json['embedding'] as Map) + : const SpeakerEmbeddingExtractorConfig(model: ''), + clustering: json['clustering'] != null + ? FastClusteringConfig.fromJson( + json['clustering'] as Map) + : const FastClusteringConfig(), + minDurationOn: (json['minDurationOn'] as num?)?.toDouble() ?? 0.2, + minDurationOff: (json['minDurationOff'] as num?)?.toDouble() ?? 0.5, + ); + } + @override String toString() { return 'OfflineSpeakerDiarizationConfig(segmentation: $segmentation, embedding: $embedding, clustering: $clustering, minDurationOn: $minDurationOn, minDurationOff: $minDurationOff)'; } + Map toJson() => { + 'segmentation': segmentation.toJson(), + 'embedding': embedding.toJson(), + 'clustering': clustering.toJson(), + 'minDurationOn': minDurationOn, + 'minDurationOff': minDurationOff, + }; + final OfflineSpeakerSegmentationModelConfig segmentation; final SpeakerEmbeddingExtractorConfig embedding; final FastClusteringConfig clustering; diff --git a/flutter/sherpa_onnx/lib/src/online_punctuation.dart b/flutter/sherpa_onnx/lib/src/online_punctuation.dart index 118be8f5..85ada985 100644 --- a/flutter/sherpa_onnx/lib/src/online_punctuation.dart +++ b/flutter/sherpa_onnx/lib/src/online_punctuation.dart @@ -11,6 +11,16 @@ class OnlinePunctuationModelConfig { this.provider = 'cpu', this.debug = true}); + factory OnlinePunctuationModelConfig.fromJson(Map json) { + return OnlinePunctuationModelConfig( + cnnBiLstm: json['cnnBiLstm'], + bpeVocab: json['bpeVocab'], + numThreads: json['numThreads'], + provider: json['provider'], + debug: json['debug'], + ); + } + @override String toString() { return 'OnlinePunctuationModelConfig(cnnBiLstm: $cnnBiLstm, ' @@ -18,6 +28,16 @@ class OnlinePunctuationModelConfig { 'provider: $provider, debug: $debug)'; } + Map toJson() { + return { + 'cnnBiLstm': cnnBiLstm, + 'bpeVocab': bpeVocab, + 'numThreads': numThreads, + 'provider': provider, + 'debug': debug, + }; + } + final String cnnBiLstm; final String bpeVocab; final int numThreads; @@ -30,11 +50,23 @@ class OnlinePunctuationConfig { required this.model, }); + factory OnlinePunctuationConfig.fromJson(Map json) { + return OnlinePunctuationConfig( + model: OnlinePunctuationModelConfig.fromJson(json['model']), + ); + } + @override String toString() { return 'OnlinePunctuationConfig(model: $model)'; } + Map toJson() { + return { + 'model': model.toJson(), + }; + } + final OnlinePunctuationModelConfig model; } @@ -90,7 +122,7 @@ class OnlinePunctuation { final ans = p.toDartString(); SherpaOnnxBindings.sherpaOnnxOnlinePunctuationFreeText?.call(p); - + return ans; } diff --git a/flutter/sherpa_onnx/lib/src/online_recognizer.dart b/flutter/sherpa_onnx/lib/src/online_recognizer.dart index 69ed9389..4a4959c9 100644 --- a/flutter/sherpa_onnx/lib/src/online_recognizer.dart +++ b/flutter/sherpa_onnx/lib/src/online_recognizer.dart @@ -16,11 +16,25 @@ class OnlineTransducerModelConfig { this.joiner = '', }); + factory OnlineTransducerModelConfig.fromJson(Map json) { + return OnlineTransducerModelConfig( + encoder: json['encoder'] as String? ?? '', + decoder: json['decoder'] as String? ?? '', + joiner: json['joiner'] as String? ?? '', + ); + } + @override String toString() { return 'OnlineTransducerModelConfig(encoder: $encoder, decoder: $decoder, joiner: $joiner)'; } + Map toJson() => { + 'encoder': encoder, + 'decoder': decoder, + 'joiner': joiner, + }; + final String encoder; final String decoder; final String joiner; @@ -29,11 +43,23 @@ class OnlineTransducerModelConfig { class OnlineParaformerModelConfig { const OnlineParaformerModelConfig({this.encoder = '', this.decoder = ''}); + factory OnlineParaformerModelConfig.fromJson(Map json) { + return OnlineParaformerModelConfig( + encoder: json['encoder'] as String? ?? '', + decoder: json['decoder'] as String? ?? '', + ); + } + @override String toString() { return 'OnlineParaformerModelConfig(encoder: $encoder, decoder: $decoder)'; } + Map toJson() => { + 'encoder': encoder, + 'decoder': decoder, + }; + final String encoder; final String decoder; } @@ -41,11 +67,21 @@ class OnlineParaformerModelConfig { class OnlineZipformer2CtcModelConfig { const OnlineZipformer2CtcModelConfig({this.model = ''}); + factory OnlineZipformer2CtcModelConfig.fromJson(Map json) { + return OnlineZipformer2CtcModelConfig( + model: json['model'] as String? ?? '', + ); + } + @override String toString() { return 'OnlineZipformer2CtcModelConfig(model: $model)'; } + Map toJson() => { + 'model': model, + }; + final String model; } @@ -63,11 +99,42 @@ class OnlineModelConfig { this.bpeVocab = '', }); + factory OnlineModelConfig.fromJson(Map json) { + return OnlineModelConfig( + transducer: OnlineTransducerModelConfig.fromJson( + json['transducer'] as Map? ?? const {}), + paraformer: OnlineParaformerModelConfig.fromJson( + json['paraformer'] as Map? ?? const {}), + zipformer2Ctc: OnlineZipformer2CtcModelConfig.fromJson( + json['zipformer2Ctc'] as Map? ?? const {}), + tokens: json['tokens'] as String, + numThreads: json['numThreads'] as int? ?? 1, + provider: json['provider'] as String? ?? 'cpu', + debug: json['debug'] as bool? ?? true, + modelType: json['modelType'] as String? ?? '', + modelingUnit: json['modelingUnit'] as String? ?? '', + bpeVocab: json['bpeVocab'] as String? ?? '', + ); + } + @override String toString() { return 'OnlineModelConfig(transducer: $transducer, paraformer: $paraformer, zipformer2Ctc: $zipformer2Ctc, tokens: $tokens, numThreads: $numThreads, provider: $provider, debug: $debug, modelType: $modelType, modelingUnit: $modelingUnit, bpeVocab: $bpeVocab)'; } + Map toJson() => { + 'transducer': transducer.toJson(), + 'paraformer': paraformer.toJson(), + 'zipformer2Ctc': zipformer2Ctc.toJson(), + 'tokens': tokens, + 'numThreads': numThreads, + 'provider': provider, + 'debug': debug, + 'modelType': modelType, + 'modelingUnit': modelingUnit, + 'bpeVocab': bpeVocab, + }; + final OnlineTransducerModelConfig transducer; final OnlineParaformerModelConfig paraformer; final OnlineZipformer2CtcModelConfig zipformer2Ctc; @@ -90,11 +157,23 @@ class OnlineModelConfig { class OnlineCtcFstDecoderConfig { const OnlineCtcFstDecoderConfig({this.graph = '', this.maxActive = 3000}); + factory OnlineCtcFstDecoderConfig.fromJson(Map json) { + return OnlineCtcFstDecoderConfig( + graph: json['graph'] as String? ?? '', + maxActive: json['maxActive'] as int? ?? 3000, + ); + } + @override String toString() { return 'OnlineCtcFstDecoderConfig(graph: $graph, maxActive: $maxActive)'; } + Map toJson() => { + 'graph': graph, + 'maxActive': maxActive, + }; + final String graph; final int maxActive; } @@ -117,11 +196,52 @@ class OnlineRecognizerConfig { this.blankPenalty = 0.0, }); + factory OnlineRecognizerConfig.fromJson(Map json) { + return OnlineRecognizerConfig( + feat: FeatureConfig.fromJson( + json['feat'] as Map? ?? const {}), + model: OnlineModelConfig.fromJson(json['model'] as Map), + decodingMethod: json['decodingMethod'] as String? ?? 'greedy_search', + maxActivePaths: json['maxActivePaths'] as int? ?? 4, + enableEndpoint: json['enableEndpoint'] as bool? ?? true, + rule1MinTrailingSilence: + (json['rule1MinTrailingSilence'] as num?)?.toDouble() ?? 2.4, + rule2MinTrailingSilence: + (json['rule2MinTrailingSilence'] as num?)?.toDouble() ?? 1.2, + rule3MinUtteranceLength: + (json['rule3MinUtteranceLength'] as num?)?.toDouble() ?? 20.0, + hotwordsFile: json['hotwordsFile'] as String? ?? '', + hotwordsScore: (json['hotwordsScore'] as num?)?.toDouble() ?? 1.5, + ctcFstDecoderConfig: OnlineCtcFstDecoderConfig.fromJson( + json['ctcFstDecoderConfig'] as Map? ?? const {}), + ruleFsts: json['ruleFsts'] as String? ?? '', + ruleFars: json['ruleFars'] as String? ?? '', + blankPenalty: (json['blankPenalty'] as num?)?.toDouble() ?? 0.0, + ); + } + @override String toString() { return 'OnlineRecognizerConfig(feat: $feat, model: $model, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, enableEndpoint: $enableEndpoint, rule1MinTrailingSilence: $rule1MinTrailingSilence, rule2MinTrailingSilence: $rule2MinTrailingSilence, rule3MinUtteranceLength: $rule3MinUtteranceLength, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ctcFstDecoderConfig: $ctcFstDecoderConfig, ruleFsts: $ruleFsts, ruleFars: $ruleFars, blankPenalty: $blankPenalty)'; } + Map toJson() => { + 'feat': feat.toJson(), + 'model': model.toJson(), + 'decodingMethod': decodingMethod, + 'maxActivePaths': maxActivePaths, + 'enableEndpoint': enableEndpoint, + 'rule1MinTrailingSilence': rule1MinTrailingSilence, + 'rule2MinTrailingSilence': rule2MinTrailingSilence, + 'rule3MinUtteranceLength': rule3MinUtteranceLength, + 'hotwordsFile': hotwordsFile, + 'hotwordsScore': hotwordsScore, + 'ctcFstDecoderConfig': ctcFstDecoderConfig.toJson(), + 'ruleFsts': ruleFsts, + 'ruleFars': ruleFars, + 'blankPenalty': blankPenalty, + }; + final FeatureConfig feat; final OnlineModelConfig model; final String decodingMethod; @@ -151,11 +271,27 @@ class OnlineRecognizerResult { OnlineRecognizerResult( {required this.text, required this.tokens, required this.timestamps}); + factory OnlineRecognizerResult.fromJson(Map json) { + return OnlineRecognizerResult( + text: json['text'] as String, + tokens: List.from(json['tokens'] as List), + timestamps: (json['timestamps'] as List) + .map((e) => (e as num).toDouble()) + .toList(), + ); + } + @override String toString() { return 'OnlineRecognizerResult(text: $text, tokens: $tokens, timestamps: $timestamps)'; } + Map toJson() => { + 'text': text, + 'tokens': tokens, + 'timestamps': timestamps, + }; + final String text; final List tokens; final List timestamps; diff --git a/flutter/sherpa_onnx/lib/src/speaker_identification.dart b/flutter/sherpa_onnx/lib/src/speaker_identification.dart index 8b27dbc6..7fc13906 100644 --- a/flutter/sherpa_onnx/lib/src/speaker_identification.dart +++ b/flutter/sherpa_onnx/lib/src/speaker_identification.dart @@ -13,11 +13,27 @@ class SpeakerEmbeddingExtractorConfig { this.debug = true, this.provider = 'cpu'}); + factory SpeakerEmbeddingExtractorConfig.fromJson(Map json) { + return SpeakerEmbeddingExtractorConfig( + model: json['model'] as String, + numThreads: json['numThreads'] as int? ?? 1, + debug: json['debug'] as bool? ?? true, + provider: json['provider'] as String? ?? 'cpu', + ); + } + @override String toString() { return 'SpeakerEmbeddingExtractorConfig(model: $model, numThreads: $numThreads, debug: $debug, provider: $provider)'; } + Map toJson() => { + 'model': model, + 'numThreads': numThreads, + 'debug': debug, + 'provider': provider, + }; + final String model; final int numThreads; final bool debug; diff --git a/flutter/sherpa_onnx/lib/src/tts.dart b/flutter/sherpa_onnx/lib/src/tts.dart index a74690e7..d3099944 100644 --- a/flutter/sherpa_onnx/lib/src/tts.dart +++ b/flutter/sherpa_onnx/lib/src/tts.dart @@ -18,11 +18,35 @@ class OfflineTtsVitsModelConfig { this.dictDir = '', }); + factory OfflineTtsVitsModelConfig.fromJson(Map json) { + return OfflineTtsVitsModelConfig( + model: json['model'] as String? ?? '', + lexicon: json['lexicon'] as String? ?? '', + tokens: json['tokens'] as String? ?? '', + dataDir: json['dataDir'] as String? ?? '', + noiseScale: (json['noiseScale'] as num?)?.toDouble() ?? 0.667, + noiseScaleW: (json['noiseScaleW'] as num?)?.toDouble() ?? 0.8, + lengthScale: (json['lengthScale'] as num?)?.toDouble() ?? 1.0, + dictDir: json['dictDir'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineTtsVitsModelConfig(model: $model, lexicon: $lexicon, tokens: $tokens, dataDir: $dataDir, noiseScale: $noiseScale, noiseScaleW: $noiseScaleW, lengthScale: $lengthScale, dictDir: $dictDir)'; } + Map toJson() => { + 'model': model, + 'lexicon': lexicon, + 'tokens': tokens, + 'dataDir': dataDir, + 'noiseScale': noiseScale, + 'noiseScaleW': noiseScaleW, + 'lengthScale': lengthScale, + 'dictDir': dictDir, + }; + final String model; final String lexicon; final String tokens; @@ -45,11 +69,35 @@ class OfflineTtsMatchaModelConfig { this.dictDir = '', }); + factory OfflineTtsMatchaModelConfig.fromJson(Map json) { + return OfflineTtsMatchaModelConfig( + acousticModel: json['acousticModel'] as String? ?? '', + vocoder: json['vocoder'] as String? ?? '', + lexicon: json['lexicon'] as String? ?? '', + tokens: json['tokens'] as String? ?? '', + dataDir: json['dataDir'] as String? ?? '', + noiseScale: (json['noiseScale'] as num?)?.toDouble() ?? 0.667, + lengthScale: (json['lengthScale'] as num?)?.toDouble() ?? 1.0, + dictDir: json['dictDir'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineTtsMatchaModelConfig(acousticModel: $acousticModel, vocoder: $vocoder, lexicon: $lexicon, tokens: $tokens, dataDir: $dataDir, noiseScale: $noiseScale, lengthScale: $lengthScale, dictDir: $dictDir)'; } + Map toJson() => { + 'acousticModel': acousticModel, + 'vocoder': vocoder, + 'lexicon': lexicon, + 'tokens': tokens, + 'dataDir': dataDir, + 'noiseScale': noiseScale, + 'lengthScale': lengthScale, + 'dictDir': dictDir, + }; + final String acousticModel; final String vocoder; final String lexicon; @@ -71,11 +119,33 @@ class OfflineTtsKokoroModelConfig { this.lexicon = '', }); + factory OfflineTtsKokoroModelConfig.fromJson(Map json) { + return OfflineTtsKokoroModelConfig( + model: json['model'] as String? ?? '', + voices: json['voices'] as String? ?? '', + tokens: json['tokens'] as String? ?? '', + dataDir: json['dataDir'] as String? ?? '', + lengthScale: (json['lengthScale'] as num?)?.toDouble() ?? 1.0, + dictDir: json['dictDir'] as String? ?? '', + lexicon: json['lexicon'] as String? ?? '', + ); + } + @override String toString() { return 'OfflineTtsKokoroModelConfig(model: $model, voices: $voices, tokens: $tokens, dataDir: $dataDir, lengthScale: $lengthScale, dictDir: $dictDir, lexicon: $lexicon)'; } + Map toJson() => { + 'model': model, + 'voices': voices, + 'tokens': tokens, + 'dataDir': dataDir, + 'lengthScale': lengthScale, + 'dictDir': dictDir, + 'lexicon': lexicon, + }; + final String model; final String voices; final String tokens; @@ -95,11 +165,34 @@ class OfflineTtsModelConfig { this.provider = 'cpu', }); + factory OfflineTtsModelConfig.fromJson(Map json) { + return OfflineTtsModelConfig( + vits: OfflineTtsVitsModelConfig.fromJson( + json['vits'] as Map? ?? const {}), + matcha: OfflineTtsMatchaModelConfig.fromJson( + json['matcha'] as Map? ?? const {}), + kokoro: OfflineTtsKokoroModelConfig.fromJson( + json['kokoro'] as Map? ?? const {}), + numThreads: json['numThreads'] as int? ?? 1, + debug: json['debug'] as bool? ?? true, + provider: json['provider'] as String? ?? 'cpu', + ); + } + @override String toString() { return 'OfflineTtsModelConfig(vits: $vits, matcha: $matcha, kokoro: $kokoro, numThreads: $numThreads, debug: $debug, provider: $provider)'; } + Map toJson() => { + 'vits': vits.toJson(), + 'matcha': matcha.toJson(), + 'kokoro': kokoro.toJson(), + 'numThreads': numThreads, + 'debug': debug, + 'provider': provider, + }; + final OfflineTtsVitsModelConfig vits; final OfflineTtsMatchaModelConfig matcha; final OfflineTtsKokoroModelConfig kokoro; @@ -117,11 +210,30 @@ class OfflineTtsConfig { this.silenceScale = 0.2, }); + factory OfflineTtsConfig.fromJson(Map json) { + return OfflineTtsConfig( + model: + OfflineTtsModelConfig.fromJson(json['model'] as Map), + ruleFsts: json['ruleFsts'] as String? ?? '', + maxNumSenetences: json['maxNumSenetences'] as int? ?? 1, + ruleFars: json['ruleFars'] as String? ?? '', + silenceScale: (json['silenceScale'] as num?)?.toDouble() ?? 0.2, + ); + } + @override String toString() { return 'OfflineTtsConfig(model: $model, ruleFsts: $ruleFsts, maxNumSenetences: $maxNumSenetences, ruleFars: $ruleFars, silenceScale: $silenceScale)'; } + Map toJson() => { + 'model': model.toJson(), + 'ruleFsts': ruleFsts, + 'maxNumSenetences': maxNumSenetences, + 'ruleFars': ruleFars, + 'silenceScale': silenceScale, + }; + final OfflineTtsModelConfig model; final String ruleFsts; final int maxNumSenetences; diff --git a/flutter/sherpa_onnx/lib/src/vad.dart b/flutter/sherpa_onnx/lib/src/vad.dart index 7db0e55e..85937c47 100644 --- a/flutter/sherpa_onnx/lib/src/vad.dart +++ b/flutter/sherpa_onnx/lib/src/vad.dart @@ -14,11 +14,33 @@ class SileroVadModelConfig { this.windowSize = 512, this.maxSpeechDuration = 5.0}); + factory SileroVadModelConfig.fromJson(Map json) { + return SileroVadModelConfig( + model: json['model'] as String? ?? '', + threshold: (json['threshold'] as num?)?.toDouble() ?? 0.5, + minSilenceDuration: + (json['minSilenceDuration'] as num?)?.toDouble() ?? 0.5, + minSpeechDuration: + (json['minSpeechDuration'] as num?)?.toDouble() ?? 0.25, + windowSize: json['windowSize'] as int? ?? 512, + maxSpeechDuration: (json['maxSpeechDuration'] as num?)?.toDouble() ?? 5.0, + ); + } + @override String toString() { return 'SileroVadModelConfig(model: $model, threshold: $threshold, minSilenceDuration: $minSilenceDuration, minSpeechDuration: $minSpeechDuration, windowSize: $windowSize, maxSpeechDuration: $maxSpeechDuration)'; } + Map toJson() => { + 'model': model, + 'threshold': threshold, + 'minSilenceDuration': minSilenceDuration, + 'minSpeechDuration': minSpeechDuration, + 'windowSize': windowSize, + 'maxSpeechDuration': maxSpeechDuration, + }; + final String model; final double threshold; final double minSilenceDuration; @@ -28,23 +50,43 @@ class SileroVadModelConfig { } class VadModelConfig { - VadModelConfig( - {this.sileroVad = const SileroVadModelConfig(), - this.sampleRate = 16000, - this.numThreads = 1, - this.provider = 'cpu', - this.debug = true}); - - @override - String toString() { - return 'VadModelConfig(sileroVad: $sileroVad, sampleRate: $sampleRate, numThreads: $numThreads, provider: $provider, debug: $debug)'; - } + VadModelConfig({ + this.sileroVad = const SileroVadModelConfig(), + this.sampleRate = 16000, + this.numThreads = 1, + this.provider = 'cpu', + this.debug = true, + }); final SileroVadModelConfig sileroVad; final int sampleRate; final int numThreads; final String provider; final bool debug; + + factory VadModelConfig.fromJson(Map json) { + return VadModelConfig( + sileroVad: SileroVadModelConfig.fromJson( + json['sileroVad'] as Map? ?? const {}), + sampleRate: json['sampleRate'] as int? ?? 16000, + numThreads: json['numThreads'] as int? ?? 1, + provider: json['provider'] as String? ?? 'cpu', + debug: json['debug'] as bool? ?? true, + ); + } + + Map toJson() => { + 'sileroVad': sileroVad.toJson(), + 'sampleRate': sampleRate, + 'numThreads': numThreads, + 'provider': provider, + 'debug': debug, + }; + + @override + String toString() { + return 'VadModelConfig(sileroVad: $sileroVad, sampleRate: $sampleRate, numThreads: $numThreads, provider: $provider, debug: $debug)'; + } } class SpeechSegment {