import 'dart:collection'; import 'package:json_annotation/json_annotation.dart'; part 'speech_recognition_result.g.dart'; /// A sequence of recognized words from the speech recognition /// service. /// /// Depending on the platform behaviour the words may come in all /// at once at the end or as partial results as each word is /// recognized. Use the [finalResult] flag to determine if the /// result is considered final by the platform. @JsonSerializable(explicitToJson: true) class SpeechRecognitionResult { List _alternates; /// Returns a list of possible transcriptions of the speech. /// /// The first value is always the same as the [recognizedWords] /// value. Use the confidence for each alternate transcription /// to determine how likely it is. Note that not all platforms /// do a good job with confidence, there are convenience methods /// on [SpeechRecogntionWords] to work with possibly missing /// confidence values. List get alternates => UnmodifiableListView(_alternates); /// The sequence of words that is the best transcription of /// what was said. /// /// This is the same as the first value of [alternates]. String get recognizedWords => _alternates.isNotEmpty ? _alternates.first.recognizedWords : ""; /// False means the words are an interim result, true means /// they are the final recognition. final bool finalResult; /// The confidence that the [recognizedWords] are correct. /// /// Confidence is expressed as a value between 0 and 1. -1 /// means that the confidence value was not available. double get confidence => _alternates.isNotEmpty ? _alternates.first.confidence : 0; /// true if there is confidence in this recognition, false otherwise. /// /// There are two separate ways for there to be confidence, the first /// is if the confidence is missing, which is indicated by a value of /// -1. The second is if the confidence is greater than or equal /// [threshold]. If [threshold] is not provided it defaults to 0.8. bool isConfident( {double threshold = SpeechRecognitionWords.confidenceThreshold}) => _alternates.isNotEmpty ? _alternates.first.isConfident(threshold: threshold) : false; /// true if [confidence] is not the [missingConfidence] value, false /// otherwise. bool get hasConfidenceRating => _alternates.isNotEmpty ? _alternates.first.hasConfidenceRating : false; SpeechRecognitionResult(this._alternates, this.finalResult); @override String toString() { return "SpeechRecognitionResult words: $_alternates, final: $finalResult"; } @override bool operator ==(Object other) { return identical(this, other) || other is SpeechRecognitionResult && recognizedWords == other.recognizedWords && finalResult == other.finalResult; } @override int get hashCode => recognizedWords.hashCode; factory SpeechRecognitionResult.fromJson(Map json) => _$SpeechRecognitionResultFromJson(json); Map toJson() => _$SpeechRecognitionResultToJson(this); } /// A set of words recognized in a [SpeechRecognitionResult]. /// /// Each result will have one or more [SpeechRecognitionWords] /// with a varying degree of confidence about each set of words. @JsonSerializable() class SpeechRecognitionWords { /// The sequence of words recognized final String recognizedWords; /// The confidence that the [recognizedWords] are correct. /// /// Confidence is expressed as a value between 0 and 1. 0 /// means that the confidence value was not available. Use /// [isConfident] which will ignore 0 values automatically. final double confidence; static const double confidenceThreshold = 0.8; static const double missingConfidence = -1; const SpeechRecognitionWords(this.recognizedWords, this.confidence); /// true if there is confidence in this recognition, false otherwise. /// /// There are two separate ways for there to be confidence, the first /// is if the confidence is missing, which is indicated by a value of /// -1. The second is if the confidence is greater than or equal /// [threshold]. If [threshold] is not provided it defaults to 0.8. bool isConfident({double threshold = confidenceThreshold}) => confidence == missingConfidence || confidence >= threshold; /// true if [confidence] is not the [missingConfidence] value, false /// otherwise. bool get hasConfidenceRating => confidence != missingConfidence; @override String toString() { return "SpeechRecognitionWords words: $recognizedWords, confidence: $confidence"; } @override bool operator ==(Object other) { return identical(this, other) || other is SpeechRecognitionWords && recognizedWords == other.recognizedWords && confidence == other.confidence; } @override int get hashCode => recognizedWords.hashCode; factory SpeechRecognitionWords.fromJson(Map json) => _$SpeechRecognitionWordsFromJson(json); Map toJson() => _$SpeechRecognitionWordsToJson(this); }