// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /** * @fileoverview The manager of audio streams. */ cr.define('speech', function() { 'use strict'; /** * The enum of the status of hotword audio recognition. * * @enum {number} */ var AudioState = { STOPPED: 0, LISTENING: 1 }; /** * @constructor * @extends {cr.EventTarget} */ function AudioManager() { var audioContext = new window.AudioContext(); this.sampleRate = audioContext.sampleRate; this.audioProc_ = null; this.audioIn_ = null; this.stream_ = null; this.state = AudioState.STOPPED; }; AudioManager.prototype.__proto__ = cr.EventTarget.prototype; /** * Called when the audio data arrives. * * @param {Event} audioEvent The audio event. * @private */ AudioManager.prototype.onAudioProcess_ = function(audioEvent) { var data = audioEvent.inputBuffer.getChannelData(0); var intData = new Int16Array(data.length); for (var i = 0; i < data.length; ++i) intData[i] = Math.round(data[i] * 32767); var event = new Event('audio'); event.data = intData; this.dispatchEvent(event); }; /** * Called when the audio stream is ready. * * @param {MediaStream} stream The media stream which is now available. * @private */ AudioManager.prototype.onAudioReady_ = function(stream) { var audioContext = new window.AudioContext(); this.stream_ = stream; this.audioIn_ = audioContext.createMediaStreamSource(stream); this.audioProc_ = audioContext.createScriptProcessor( 4096 /* buffer size */, 1 /* channels */, 1 /* channels */); this.audioProc_.onaudioprocess = this.onAudioProcess_.bind(this); this.audioIn_.connect(this.audioProc_); this.audioProc_.connect(audioContext.destination); this.state = AudioState.LISTENING; }; /** * Starts the audio processing. */ AudioManager.prototype.start = function() { if (this.state == AudioState.LISTENING) return; navigator.webkitGetUserMedia( {audio: true}, this.onAudioReady_.bind(this), function(msg) { console.error('Failed to getUserMedia: ' + msg); }); }; /** * Stops the audio processing. */ AudioManager.prototype.stop = function() { if (this.state != AudioState.LISTENING) return; this.audioProc_.disconnect(); this.audioIn_.disconnect(); var audioTracks = this.stream_.getAudioTracks(); for (var i = 0; i < audioTracks.length; ++i) { audioTracks[i].stop(); } this.audioProc_ = null; this.audioIn_ = null; this.stream_ = null; this.state = AudioState.STOPPED; }; return { AudioManager: AudioManager, AudioState: AudioState }; });