Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / app_list / speech_manager.js
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.
4
5 /**
6  * @fileoverview The class to Manage both offline / online speech recognition.
7  */
8
9 <include src="plugin_manager.js"/>
10 <include src="audio_manager.js"/>
11 <include src="speech_recognition_manager.js"/>
12
13 cr.define('speech', function() {
14   'use strict';
15
16   /**
17    * The state of speech recognition.
18    *
19    * @enum {string}
20    */
21   var SpeechState = {
22     READY: 'READY',
23     HOTWORD_RECOGNIZING: 'HOTWORD_RECOGNIZING',
24     RECOGNIZING: 'RECOGNIZING',
25     STOPPING: 'STOPPING'
26   };
27
28   /**
29    * @constructor
30    */
31   function SpeechManager() {
32     this.audioManager_ = new speech.AudioManager();
33     this.audioManager_.addEventListener('audio', this.onAudioLevel_.bind(this));
34     if (speech.isPluginAvailable()) {
35       var pluginManager = new speech.PluginManager(
36           this.onHotwordRecognizerReady_.bind(this),
37           this.onHotwordRecognized_.bind(this));
38       pluginManager.scheduleInitialize(
39           this.audioManager_.getSampleRate(),
40           'chrome://app-list/okgoogle_hotword.config');
41     }
42     this.speechRecognitionManager_ = new speech.SpeechRecognitionManager(this);
43     this.setState_(SpeechState.READY);
44   }
45
46   /**
47    * Updates the state.
48    *
49    * @param {SpeechState} newState The new state.
50    * @private
51    */
52   SpeechManager.prototype.setState_ = function(newState) {
53     this.state = newState;
54   };
55
56   /**
57    * Called with the mean audio level when audio data arrives.
58    *
59    * @param {cr.event.Event} event The event object for the audio data.
60    * @private
61    */
62   SpeechManager.prototype.onAudioLevel_ = function(event) {
63     var data = event.data;
64     var level = 0;
65     for (var i = 0; i < data.length; ++i)
66       level += Math.abs(data[i]);
67     level /= data.length;
68     chrome.send('speechSoundLevel', [level]);
69   };
70
71   /**
72    * Called when the hotword recognizer is ready.
73    *
74    * @param {PluginManager} pluginManager The hotword plugin manager which gets
75    *   ready.
76    * @private
77    */
78   SpeechManager.prototype.onHotwordRecognizerReady_ = function(pluginManager) {
79     this.pluginManager_ = pluginManager;
80     this.audioManager_.addEventListener(
81         'audio', pluginManager.sendAudioData.bind(pluginManager));
82     this.setState_(SpeechState.READY);
83   };
84
85   /**
86    * Called when the hotword is recognized.
87    *
88    * @param {number} confidence The confidence store of the recognition.
89    * @private
90    */
91   SpeechManager.prototype.onHotwordRecognized_ = function(confidence) {
92     if (this.state != SpeechState.HOTWORD_RECOGNIZING)
93       return;
94     this.setState_(SpeechState.READY);
95     this.pluginManager_.stopRecognizer();
96     this.speechRecognitionManager_.start();
97   };
98
99   /**
100    * Called when the speech recognition has happened.
101    *
102    * @param {string} result The speech recognition result.
103    * @param {boolean} isFinal Whether the result is final or not.
104    */
105   SpeechManager.prototype.onSpeechRecognized = function(result, isFinal) {
106     chrome.send('speechResult', [result, isFinal]);
107     if (isFinal)
108       this.speechRecognitionManager_.stop();
109   };
110
111   /**
112    * Called when the speech recognition has started.
113    */
114   SpeechManager.prototype.onSpeechRecognitionStarted = function() {
115     this.setState_(SpeechState.RECOGNIZING);
116     chrome.send('setSpeechRecognitionState', ['on']);
117   };
118
119   /**
120    * Called when the speech recognition has ended.
121    */
122   SpeechManager.prototype.onSpeechRecognitionEnded = function() {
123     // Restarts the hotword recognition.
124     if (this.state != SpeechState.STOPPING && this.pluginManager_) {
125       this.pluginManager_.startRecognizer();
126       this.audioManager_.start();
127       this.setState_(SpeechState.HOTWORD_RECOGNIZING);
128     } else {
129       this.audioManager_.stop();
130     }
131     chrome.send('setSpeechRecognitionState', ['off']);
132   };
133
134   /**
135    * Called when a speech has started.
136    */
137   SpeechManager.prototype.onSpeechStarted = function() {
138     if (this.state == SpeechState.RECOGNIZING)
139       chrome.send('setSpeechRecognitionState', ['in-speech']);
140   };
141
142   /**
143    * Called when a speech has ended.
144    */
145   SpeechManager.prototype.onSpeechEnded = function() {
146     if (this.state == SpeechState.RECOGNIZING)
147       chrome.send('setSpeechRecognitionState', ['on']);
148   };
149
150   /**
151    * Called when an error happened during the speech recognition.
152    *
153    * @param {SpeechRecognitionError} e The error object.
154    */
155   SpeechManager.prototype.onSpeechRecognitionError = function(e) {
156     if (this.state != SpeechState.STOPPING)
157       this.setState_(SpeechState.READY);
158   };
159
160   /**
161    * Starts the speech recognition session.
162    */
163   SpeechManager.prototype.start = function() {
164     if (!this.pluginManager_)
165       return;
166
167     if (this.state == SpeechState.HOTWORD_RECOGNIZING) {
168       console.warn('Already in recognition state...');
169       return;
170     }
171
172     this.pluginManager_.startRecognizer();
173     this.audioManager_.start();
174     this.setState_(SpeechState.HOTWORD_RECOGNIZING);
175   };
176
177   /**
178    * Stops the speech recognition session.
179    */
180   SpeechManager.prototype.stop = function() {
181     if (this.pluginManager_)
182       this.pluginManager_.stopRecognizer();
183
184     // SpeechRecognition is asynchronous.
185     this.audioManager_.stop();
186     if (this.state == SpeechState.RECOGNIZING) {
187       this.setState_(SpeechState.STOPPING);
188       this.speechRecognitionManager_.stop();
189     } else {
190       this.setState_(SpeechState.READY);
191     }
192   };
193
194   /**
195    * Toggles the current state of speech recognition.
196    */
197   SpeechManager.prototype.toggleSpeechRecognition = function() {
198     if (this.state == SpeechState.RECOGNIZING) {
199       this.audioManager_.stop();
200       this.speechRecognitionManager_.stop();
201     } else {
202       if (this.pluginManager_)
203         this.pluginManager_.stopRecognizer();
204       if (this.audioManager_.state == speech.AudioState.STOPPED)
205         this.audioManager_.start();
206       this.speechRecognitionManager_.start();
207     }
208   };
209
210   return {
211     SpeechManager: SpeechManager
212   };
213 });