1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview The class to Manage both offline / online speech recognition.
9 <include src="plugin_manager.js"/>
10 <include src="audio_manager.js"/>
11 <include src="speech_recognition_manager.js"/>
13 cr.define('speech', function() {
17 * The state of speech recognition.
23 HOTWORD_RECOGNIZING: 'HOTWORD_RECOGNIZING',
24 RECOGNIZING: 'RECOGNIZING',
25 IN_SPEECH: 'IN_SPEECH',
32 function SpeechManager() {
33 this.audioManager_ = new speech.AudioManager();
34 this.audioManager_.addEventListener('audio', this.onAudioLevel_.bind(this));
36 this.speechRecognitionManager_ = new speech.SpeechRecognitionManager(this);
37 this.setState_(SpeechState.READY);
43 * @param {SpeechState} newState The new state.
46 SpeechManager.prototype.setState_ = function(newState) {
47 if (this.state == newState)
50 this.state = newState;
51 chrome.send('setSpeechRecognitionState', [this.state]);
55 * Called with the mean audio level when audio data arrives.
57 * @param {cr.event.Event} event The event object for the audio data.
60 SpeechManager.prototype.onAudioLevel_ = function(event) {
61 var data = event.data;
63 for (var i = 0; i < data.length; ++i)
64 level += Math.abs(data[i]);
66 chrome.send('speechSoundLevel', [level]);
70 * Called when the hotword recognizer is ready.
72 * @param {PluginManager} pluginManager The hotword plugin manager which gets
76 SpeechManager.prototype.onHotwordRecognizerReady_ = function(pluginManager) {
77 this.pluginManager_ = pluginManager;
78 this.audioManager_.addEventListener(
79 'audio', pluginManager.sendAudioData.bind(pluginManager));
81 this.pluginManager_.startRecognizer();
82 this.audioManager_.start();
83 this.setState_(SpeechState.HOTWORD_RECOGNIZING);
85 this.setState_(SpeechState.READY);
90 * Called when the hotword is recognized.
92 * @param {number} confidence The confidence store of the recognition.
95 SpeechManager.prototype.onHotwordRecognized_ = function(confidence) {
96 if (this.state != SpeechState.HOTWORD_RECOGNIZING)
98 this.pluginManager_.stopRecognizer();
99 this.speechRecognitionManager_.start();
103 * Called when the speech recognition has happened.
105 * @param {string} result The speech recognition result.
106 * @param {boolean} isFinal Whether the result is final or not.
108 SpeechManager.prototype.onSpeechRecognized = function(result, isFinal) {
109 chrome.send('speechResult', [result, isFinal]);
111 this.speechRecognitionManager_.stop();
115 * Called when the speech recognition has started.
117 SpeechManager.prototype.onSpeechRecognitionStarted = function() {
118 this.setState_(SpeechState.RECOGNIZING);
122 * Called when the speech recognition has ended.
124 SpeechManager.prototype.onSpeechRecognitionEnded = function() {
125 // Restarts the hotword recognition.
126 if (this.state != SpeechState.STOPPING && this.pluginManager_) {
127 this.pluginManager_.startRecognizer();
128 this.audioManager_.start();
129 this.setState_(SpeechState.HOTWORD_RECOGNIZING);
131 this.audioManager_.stop();
132 this.setState_(SpeechState.READY);
137 * Called when a speech has started.
139 SpeechManager.prototype.onSpeechStarted = function() {
140 if (this.state == SpeechState.RECOGNIZING)
141 this.setState_(SpeechState.IN_SPEECH);
145 * Called when a speech has ended.
147 SpeechManager.prototype.onSpeechEnded = function() {
148 if (this.state == SpeechState.IN_SPEECH)
149 this.setState_(SpeechState.RECOGNIZING);
153 * Called when an error happened during the speech recognition.
155 * @param {SpeechRecognitionError} e The error object.
157 SpeechManager.prototype.onSpeechRecognitionError = function(e) {
158 if (this.state != SpeechState.STOPPING)
159 this.setState_(SpeechState.READY);
163 * Changes the availability of the hotword plugin.
165 * @param {boolean} enabled Whether enabled or not.
167 SpeechManager.prototype.setHotwordEnabled = function(enabled) {
168 var recognizer = $('recognizer');
173 var pluginManager = new speech.PluginManager(
174 this.onHotwordRecognizerReady_.bind(this),
175 this.onHotwordRecognized_.bind(this));
176 pluginManager.scheduleInitialize(
177 this.audioManager_.getSampleRate(),
178 'chrome://app-list/okgoogle_hotword.config');
182 document.body.removeChild(recognizer);
183 this.pluginManager_ = null;
184 if (this.state == SpeechState.HOTWORD_RECOGNIZING)
185 this.setState(SpeechState.READY);
190 * Called when the app-list bubble is shown.
192 SpeechManager.prototype.onShown = function() {
194 if (!this.pluginManager_)
197 if (this.state == SpeechState.HOTWORD_RECOGNIZING) {
198 console.warn('Already in recognition state...');
202 this.pluginManager_.startRecognizer();
203 this.audioManager_.start();
204 this.setState_(SpeechState.HOTWORD_RECOGNIZING);
208 * Called when the app-list bubble is hidden.
210 SpeechManager.prototype.onHidden = function() {
212 if (this.pluginManager_)
213 this.pluginManager_.stopRecognizer();
215 // SpeechRecognition is asynchronous.
216 this.audioManager_.stop();
217 if (this.state == SpeechState.RECOGNIZING ||
218 this.state == SpeechState.IN_SPEECH) {
219 this.setState_(SpeechState.STOPPING);
220 this.speechRecognitionManager_.stop();
222 this.setState_(SpeechState.READY);
227 * Toggles the current state of speech recognition.
229 SpeechManager.prototype.toggleSpeechRecognition = function() {
230 if (this.state == SpeechState.RECOGNIZING ||
231 this.state == SpeechState.IN_SPEECH) {
232 this.audioManager_.stop();
233 this.speechRecognitionManager_.stop();
235 if (this.pluginManager_)
236 this.pluginManager_.stopRecognizer();
237 if (this.audioManager_.state == speech.AudioState.STOPPED)
238 this.audioManager_.start();
239 this.speechRecognitionManager_.start();
244 SpeechManager: SpeechManager