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 manager of offline hotword speech recognizer plugin.
9 cr
.define('speech', function() {
13 * The type of the plugin state.
19 SAMPLING_RATE_READY
: 2,
25 * The command names of the plugin.
28 var pluginCommands
= {
29 SET_SAMPLING_RATE
: 'h',
31 START_RECOGNIZING
: 'r',
36 * The regexp pattern of the hotword recognition result.
38 var recognitionPattern
= /^HotwordFiredEvent: \[(.*)\] confidence: (.*)/;
41 * Checks the availability of the plugin.
42 * @return {boolean} True only if the plugin is available.
44 function isPluginAvailable() {
45 return !!($('recognizer') && $('recognizer').postMessage
);
51 function PluginManager(onReady
, onRecognized
) {
52 this.state
= PluginState
.UNINITIALIZED
;
53 this.onReady_
= onReady
;
54 this.onRecognized_
= onRecognized
;
55 this.samplingRate_
= null;
57 if (isPluginAvailable()) {
58 $('recognizer').addEventListener('message', this.onMessage_
.bind(this));
59 $('recognizer').addEventListener('load', this.onLoad_
.bind(this));
64 * The event handler of the plugin status.
66 * @param {Event} messageEvent the event object from the plugin.
69 PluginManager
.prototype.onMessage_ = function(messageEvent
) {
70 if (this.state
== PluginState
.LOADED
) {
71 if (messageEvent
.data
== 'stopped')
72 this.state
= PluginState
.SAMPLING_RATE_READY
;
76 if (messageEvent
.data
== 'audio') {
77 if (this.state
< PluginState
.READY
)
79 this.state
= PluginState
.RECOGNIZING
;
80 } else if (messageEvent
.data
== 'stopped') {
81 this.state
= PluginState
.READY
;
83 var matched
= recognitionPattern
.exec(messageEvent
.data
);
84 if (matched
&& matched
[1] == 'hotword_ok_google')
85 this.onRecognized_(Number(matched
[2]));
90 * The event handler when the plugin is loaded.
94 PluginManager
.prototype.onLoad_ = function() {
95 if (this.state
== PluginState
.UNINITIALIZED
) {
96 this.state
= PluginState
.LOADED
;
97 if (this.samplingRate_
&& this.config_
)
98 this.initialize_(this.samplingRate_
, this.config_
);
103 * Sends the initialization messages to the plugin. This method is private.
104 * The initialization will happen from onLoad_ or scheduleInitialize.
106 * @param {number} samplingRate the sampling rate the plugin accepts.
107 * @param {string} config the url of the config file.
110 PluginManager
.prototype.initialize_ = function(samplingRate
, config
) {
111 $('recognizer').postMessage(
112 pluginCommands
.SET_SAMPLING_RATE
+ samplingRate
);
113 $('recognizer').postMessage(pluginCommands
.SET_CONFIG
+ config
);
117 * Initializes the plugin with the specified parameter, or schedules the
118 * initialization if the plugin is not ready.
120 * @param {number} samplingRate the sampling rate the plugin accepts.
121 * @param {string} config the url of the config file.
123 PluginManager
.prototype.scheduleInitialize = function(samplingRate
, config
) {
124 if (this.state
== PluginState
.UNINITIALIZED
) {
125 this.samplingRate_
= samplingRate
;
126 this.config_
= config
;
128 this.initialize_(samplingRate
, config
);
133 * Asks the plugin to start recognizing the hotword.
135 PluginManager
.prototype.startRecognizer = function() {
136 if (this.state
== PluginState
.READY
)
137 $('recognizer').postMessage(pluginCommands
.START_RECOGNIZING
);
141 * Asks the plugin to stop recognizing the hotword.
143 PluginManager
.prototype.stopRecognizer = function() {
144 if (this.state
== PluginState
.RECOGNIZING
)
145 $('recognizer').postMessage(pluginCommands
.STOP_RECOGNIZING
);
149 * Sends the actual audio wave data.
151 * @param {cr.event.Event} event The event for the audio data.
153 PluginManager
.prototype.sendAudioData = function(event
) {
154 if (this.state
== PluginState
.RECOGNIZING
)
155 $('recognizer').postMessage(event
.data
.buffer
);
159 PluginManager
: PluginManager
,
160 PluginState
: PluginState
,
161 isPluginAvailable
: isPluginAvailable