Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / whispernet_proxy / js / wrapper.js
1 // Copyright 2014 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 'use strict';
6
7 /**
8  * Function to convert an array of bytes to a base64 string
9  * TODO(rkc): Change this to use a Uint8array instead of a string.
10  * @param {string} bytes String containing the bytes we want to convert.
11  * @return {string} String containing the base64 representation.
12  */
13 function bytesToBase64(bytes) {
14   var bstr = '';
15   for (var i = 0; i < bytes.length; ++i)
16     bstr += String.fromCharCode(bytes[i]);
17   return btoa(bstr);
18 }
19
20 /**
21  * Function to convert a string to an array of bytes.
22  * @param {string} str String to convert.
23  * @return {Array} Array containing the string.
24  */
25 function stringToArray(str) {
26   var buffer = [];
27   for (var i = 0; i < str.length; ++i)
28     buffer[i] = str.charCodeAt(i);
29   return buffer;
30 }
31
32 /**
33  * Creates a whispernet encoder.
34  * @constructor
35  * @param {Object} params Dictionary of parameters used to initialize the
36  * whispernet encoder.
37  * @param {Object} whisperNacl The NaclBridge object to use to communicate with
38  * the whispernet wrapper.
39  */
40 function WhisperEncoder(params, whisperNacl) {
41   params = params || {};
42   this.repetitions_ = params.repetitions || 3;
43
44   this.whisperNacl_ = whisperNacl;
45   this.whisperNacl_.addListener(this.onNaclMessage_.bind(this));
46
47   var msg = {
48     type: 'initialize_encoder',
49     sample_rate: params.sampleRate || 48000.0,
50     upsampling_factor: params.bitsPerSample || 16,
51   };
52   this.whisperNacl_.send(msg);
53 }
54
55 /**
56  * Method to encode a token.
57  * @param {string} token Token to encode.
58  * @param {boolean} audible Whether we should use encode audible samples.
59  * @param {boolean} raw Whether we should return the encoded samples in raw
60  * format or as a Wave file.
61  */
62 WhisperEncoder.prototype.encode = function(token, audible, raw) {
63   var msg = {
64     type: 'encode_token',
65     // Trying to send the token in binary form to Nacl doesn't work correctly.
66     // We end up with the correct string + a bunch of extra characters. This is
67     // true of returning a binary string too; hence we communicate back and
68     // forth by converting the bytes into an array of integers.
69     token: stringToArray(token),
70     repetitions: this.repetitions_,
71     use_dtmf: audible,
72     return_raw_samples: raw
73   };
74   this.whisperNacl_.send(msg);
75 };
76
77 /**
78  * Method to set the callback for encoded audio data received from the encoder
79  * when we finish encoding a token.
80  * @param {function(string, ArrayBuffer)} callback Callback which will receive
81  * the audio samples.
82  */
83 WhisperEncoder.prototype.setAudioDataCallback = function(callback) {
84   this.audioDataCallback_ = callback;
85 };
86
87 /**
88  * Method to handle messages from the whispernet NaCl wrapper.
89  * @param {Event} e Event from the whispernet wrapper.
90  * @private
91  */
92 WhisperEncoder.prototype.onNaclMessage_ = function(e) {
93   var msg = e.data;
94   if (msg.type == 'encode_token_response') {
95     this.audioDataCallback_(
96         { token: bytesToBase64(msg.token), audible: msg.audible }, msg.samples);
97   }
98 };
99
100 /**
101  * Creates a whispernet decoder.
102  * @constructor
103  * @param {Object} params Dictionary of parameters used to initialize the
104  * whispernet decoder.
105  * @param {Object} whisperNacl The NaclBridge object to use to communicate with
106  * the whispernet wrapper.
107  */
108 function WhisperDecoder(params, whisperNacl) {
109   params = params || {};
110
111   this.whisperNacl_ = whisperNacl;
112   this.whisperNacl_.addListener(this.onNaclMessage_.bind(this));
113
114   var msg = {
115     type: 'initialize_decoder',
116     channels: params.channels || 1,
117     sample_rate: params.sampleRate || 48000.0,
118     upsampling_factor: params.bitsPerSample || 16,
119     max_candidates: 1,
120     max_buffer_duration_in_seconds: 3
121   };
122   this.whisperNacl_.send(msg);
123 }
124
125 /**
126  * Method to request the decoder to wipe its internal buffer.
127  */
128 WhisperDecoder.prototype.wipeDecoder = function() {
129   var msg = {
130     type: 'wipe_decode_buffer'
131   };
132   this.whisperNacl_.send(msg);
133 };
134
135 /**
136  * Method to request the decoder to detect a broadcast.
137  */
138 WhisperDecoder.prototype.detectBroadcast = function() {
139   var msg = {
140     type: 'detect_broadcast'
141   };
142   this.whisperNacl_.send(msg);
143 };
144
145 /**
146  * Method to request the decoder to process samples.
147  * @param {ArrayBuffer} samples Array of samples to process.
148  * @param {Object} type Type of decoding to perform.
149  */
150 WhisperDecoder.prototype.processSamples = function(samples, type) {
151   var msg = {
152     type: 'decode_tokens',
153     decode_audible: type.decodeAudible,
154     decode_inaudible: type.decodeInaudible,
155     data: samples,
156   };
157
158   this.whisperNacl_.send(msg);
159 };
160
161 /**
162  * Method to set the callback for decoded tokens received from the decoder.
163  * @param {function(!Array.string)} callback Callback to receive the list of
164  * decoded tokens.
165  */
166 WhisperDecoder.prototype.setReceiveCallback = function(callback) {
167   this.tokenCallback_ = callback;
168 };
169
170 /**
171  * Method to set the callback for receiving the detect callback status received
172  * from the decoder.
173  * @param {function()} callback Callback to set to receive the detect broadcast
174  * status.
175  */
176 WhisperDecoder.prototype.onDetectBroadcast = function(callback) {
177   this.detectBroadcastCallback_ = callback;
178 };
179
180 /**
181  * Method to handle messages from the whispernet NaCl wrapper.
182  * @param {Event} e Event from the whispernet wrapper.
183  * @private
184  */
185 WhisperDecoder.prototype.onNaclMessage_ = function(e) {
186   var msg = e.data;
187   if (msg.type == 'decode_tokens_response') {
188     this.handleCandidates_(msg.tokens, msg.audible);
189   } else if (msg.type == 'detect_broadcast_response') {
190     this.detectBroadcastCallback_(msg.detected);
191   }
192 };
193
194 /**
195  * Method to receive tokens from the decoder and process and forward them to the
196  * token callback registered with us.
197  * @param {!Array.string} candidates Array of token candidates.
198  * @param {boolean} audible Whether the received candidates are from the audible
199  *     decoder or not.
200  * @private
201  */
202 WhisperDecoder.prototype.handleCandidates_ = function(candidates, audible) {
203   if (!this.tokenCallback_ || !candidates || candidates.length == 0)
204     return;
205
206   var returnCandidates = [];
207   for (var i = 0; i < candidates.length; ++i) {
208     returnCandidates[i] = { token: bytesToBase64(candidates[i]),
209                             audible: audible };
210   }
211   this.tokenCallback_(returnCandidates);
212 };
213