1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @fileoverview The manager of speech recognition.
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)cr.define('speech', function() {
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  'use strict';
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @constructor
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  function SpeechRecognitionManager(delegate) {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.isActive = true;
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.delegate_ = delegate;
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_ = new window.webkitSpeechRecognition();
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.continuous = true;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.interimResults = true;
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.lang = navigator.language;
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.onresult = this.onRecognizerResult_.bind(this);
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (this.delegate_) {
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.recognizer_.onstart =
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          this.delegate_.onSpeechRecognitionStarted.bind(this.delegate_);
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.recognizer_.onend =
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          this.delegate_.onSpeechRecognitionEnded.bind(this.delegate_);
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      this.recognizer_.onspeechstart =
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          this.delegate_.onSpeechStarted.bind(this.delegate_);
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      this.recognizer_.onspeechend =
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          this.delegate_.onSpeechEnded.bind(this.delegate_);
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.recognizer_.onerror = this.onRecognizerError_.bind(this);
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Called when new speech recognition results arrive.
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   *
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @param {Event} speechEvent The event to contain the recognition results.
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpeechRecognitionManager.prototype.onRecognizerResult_ = function(
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      speechEvent) {
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Do not collect interim result for now.
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var result = '';
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var isFinal = false;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    for (var i = 0; i < speechEvent.results.length; i++) {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (speechEvent.results[i].isFinal)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        isFinal = true;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      result += speechEvent.results[i][0].transcript;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (this.delegate_)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.delegate_.onSpeechRecognized(result, isFinal);
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Called when an error happens in speech recognition.
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   *
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @param {SpeechRecognitionError} error The error data.
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * @private
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpeechRecognitionManager.prototype.onRecognizerError_ = function(error) {
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (error.error == 'language-not-supported') {
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Falls back to English and restart.
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.recognizer_.lang = 'en-US';
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.start();
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.delegate_.onSpeechRecognitionError(error);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Starts the speech recognition through webkitSpeechRecognition.
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpeechRecognitionManager.prototype.start = function() {
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.start();
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /**
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   * Stops the ongoing speech recognition.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   */
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpeechRecognitionManager.prototype.stop = function() {
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.recognizer_.abort();
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return {
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SpeechRecognitionManager: SpeechRecognitionManager
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)});
92