OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Function to convert an array of bytes to a base64 string | 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. | 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. | 10 * @param {string} bytes String containing the bytes we want to convert. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 this.repetitions_ = params.repetitions || 3; | 42 this.repetitions_ = params.repetitions || 3; |
43 | 43 |
44 this.whisperNacl_ = whisperNacl; | 44 this.whisperNacl_ = whisperNacl; |
45 this.whisperNacl_.addListener(this.onNaclMessage_.bind(this)); | 45 this.whisperNacl_.addListener(this.onNaclMessage_.bind(this)); |
46 | 46 |
47 var msg = { | 47 var msg = { |
48 type: 'initialize_encoder', | 48 type: 'initialize_encoder', |
49 sample_rate: params.sampleRate || 48000.0, | 49 sample_rate: params.sampleRate || 48000.0, |
50 upsampling_factor: params.bitsPerSample || 16, | 50 upsampling_factor: params.bitsPerSample || 16, |
51 }; | 51 }; |
52 this.whisperNacl_.send(JSON.stringify(msg)); | 52 this.whisperNacl_.send(msg); |
53 } | 53 } |
54 | 54 |
55 /** | 55 /** |
56 * Method to encode a token. | 56 * Method to encode a token. |
57 * @param {string} token Token to encode. | 57 * @param {string} token Token to encode. |
58 * @param {boolean} audible Whether we should use encode audible samples. | 58 * @param {boolean} audible Whether we should use encode audible samples. |
59 * @param {boolean} raw Whether we should return the encoded samples in raw | 59 * @param {boolean} raw Whether we should return the encoded samples in raw |
60 * format or as a Wave file. | 60 * format or as a Wave file. |
61 */ | 61 */ |
62 WhisperEncoder.prototype.encode = function(token, audible, raw) { | 62 WhisperEncoder.prototype.encode = function(token, audible, raw) { |
63 var msg = { | 63 var msg = { |
64 type: 'encode_token', | 64 type: 'encode_token', |
65 // Trying to send the token in binary form to Nacl doesn't work correctly. | 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 | 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 | 67 // true of returning a binary string too; hence we communicate back and |
68 // forth by converting the bytes into an array of integers. | 68 // forth by converting the bytes into an array of integers. |
69 token: stringToArray(token), | 69 token: stringToArray(token), |
70 repetitions: this.repetitions_, | 70 repetitions: this.repetitions_, |
71 use_dtmf: audible, | 71 use_dtmf: audible, |
72 return_raw_samples: raw | 72 return_raw_samples: raw |
73 }; | 73 }; |
74 this.whisperNacl_.send(JSON.stringify(msg)); | 74 this.whisperNacl_.send(msg); |
75 }; | 75 }; |
76 | 76 |
77 /** | 77 /** |
78 * Method to set the callback for encoded audio data received from the encoder | 78 * Method to set the callback for encoded audio data received from the encoder |
79 * when we finish encoding a token. | 79 * when we finish encoding a token. |
80 * @param {function(string, ArrayBuffer)} callback Callback which will receive | 80 * @param {function(string, ArrayBuffer)} callback Callback which will receive |
81 * the audio samples. | 81 * the audio samples. |
82 */ | 82 */ |
83 WhisperEncoder.prototype.setAudioDataCallback = function(callback) { | 83 WhisperEncoder.prototype.setAudioDataCallback = function(callback) { |
84 this.audioDataCallback_ = callback; | 84 this.audioDataCallback_ = callback; |
(...skipping 27 matching lines...) Expand all Loading... | |
112 this.whisperNacl_.addListener(this.onNaclMessage_.bind(this)); | 112 this.whisperNacl_.addListener(this.onNaclMessage_.bind(this)); |
113 | 113 |
114 var msg = { | 114 var msg = { |
115 type: 'initialize_decoder', | 115 type: 'initialize_decoder', |
116 channels: params.channels || 1, | 116 channels: params.channels || 1, |
117 sample_rate: params.sampleRate || 48000.0, | 117 sample_rate: params.sampleRate || 48000.0, |
118 upsampling_factor: params.bitsPerSample || 16, | 118 upsampling_factor: params.bitsPerSample || 16, |
119 max_candidates: 1, | 119 max_candidates: 1, |
120 max_buffer_duration_in_seconds: 3 | 120 max_buffer_duration_in_seconds: 3 |
121 }; | 121 }; |
122 this.whisperNacl_.send(JSON.stringify(msg)); | 122 this.whisperNacl_.send(msg); |
123 } | 123 } |
124 | 124 |
125 /** | 125 /** |
126 * Method to request the decoder to wipe its internal buffer. | 126 * Method to request the decoder to wipe its internal buffer. |
127 */ | 127 */ |
128 WhisperDecoder.prototype.wipeDecoder = function() { | 128 WhisperDecoder.prototype.wipeDecoder = function() { |
129 var msg = { | 129 var msg = { |
130 type: 'wipe_decode_buffer' | 130 type: 'wipe_decode_buffer' |
131 }; | 131 }; |
132 this.whisperNacl_.send(JSON.stringify(msg)); | 132 this.whisperNacl_.send(msg); |
133 }; | 133 }; |
134 | 134 |
135 /** | 135 /** |
136 * Method to request the decoder to detect a broadcast. | 136 * Method to request the decoder to detect a broadcast. |
137 */ | 137 */ |
138 WhisperDecoder.prototype.detectBroadcast = function() { | 138 WhisperDecoder.prototype.detectBroadcast = function() { |
139 var msg = { | 139 var msg = { |
140 type: 'detect_broadcast' | 140 type: 'detect_broadcast' |
141 }; | 141 }; |
142 this.whisperNacl_.send(JSON.stringify(msg)); | 142 this.whisperNacl_.send(msg); |
143 }; | 143 }; |
144 | 144 |
145 /** | 145 /** |
146 * Method to request the decoder to process samples. | 146 * Method to request the decoder to process samples. |
147 * @param {string} type Type of decoding to perform. | |
Daniel Erat
2014/10/17 22:25:59
same here
rkc
2014/10/18 00:21:54
Ditto.
| |
147 * @param {ArrayBuffer} samples Array of samples to process. | 148 * @param {ArrayBuffer} samples Array of samples to process. |
148 */ | 149 */ |
149 WhisperDecoder.prototype.processSamples = function(samples) { | 150 WhisperDecoder.prototype.processSamples = function(type, samples) { |
150 // For sample processing, the Nacl module doesn't expect any frills in the | 151 // We set the type value to 01b for audible, 10b for inaudible and 11b for |
151 // message, just send the samples directly. | 152 // both. This is due to not having any other way of actually sharing enum |
152 this.whisperNacl_.send(samples); | 153 // values across JS/Nacl boundaries - hence, viva la 1980's coding vida! |
154 var typeVal = 0; | |
155 if (type == 'audible') { | |
156 typeVal = 1; | |
157 } else if (type == 'inaudible') { | |
158 typeVal = 2; | |
159 } else if (type == 'both') { | |
160 typeVal = 3; | |
161 } | |
162 | |
163 var msg = { | |
164 type: 'decode_tokens', | |
165 request_type: typeVal, | |
166 data: samples, | |
167 }; | |
168 | |
169 this.whisperNacl_.send(msg); | |
153 }; | 170 }; |
154 | 171 |
155 /** | 172 /** |
156 * Method to set the callback for decoded tokens received from the decoder. | 173 * Method to set the callback for decoded tokens received from the decoder. |
157 * @param {function(!Array.string)} callback Callback to receive the list of | 174 * @param {function(!Array.string)} callback Callback to receive the list of |
158 * decoded tokens. | 175 * decoded tokens. |
159 */ | 176 */ |
160 WhisperDecoder.prototype.setReceiveCallback = function(callback) { | 177 WhisperDecoder.prototype.setReceiveCallback = function(callback) { |
161 this.tokenCallback_ = callback; | 178 this.tokenCallback_ = callback; |
162 }; | 179 }; |
163 | 180 |
164 /** | 181 /** |
165 * Method to set the callback for receiving the detect callback status received | 182 * Method to set the callback for receiving the detect callback status received |
166 * from the decoder. | 183 * from the decoder. |
167 * @param {function()} callback Callback to set to receive the detect broadcast | 184 * @param {function()} callback Callback to set to receive the detect broadcast |
168 * status. | 185 * status. |
169 */ | 186 */ |
170 WhisperDecoder.prototype.onDetectBroadcast = function(callback) { | 187 WhisperDecoder.prototype.onDetectBroadcast = function(callback) { |
171 this.detectBroadcastCallback_ = callback; | 188 this.detectBroadcastCallback_ = callback; |
172 }; | 189 }; |
173 | 190 |
174 /** | 191 /** |
175 * Method to handle messages from the whispernet NaCl wrapper. | 192 * Method to handle messages from the whispernet NaCl wrapper. |
176 * @param {Event} e Event from the whispernet wrapper. | 193 * @param {Event} e Event from the whispernet wrapper. |
177 * @private | 194 * @private |
178 */ | 195 */ |
179 WhisperDecoder.prototype.onNaclMessage_ = function(e) { | 196 WhisperDecoder.prototype.onNaclMessage_ = function(e) { |
180 var msg = e.data; | 197 var msg = e.data; |
181 if (msg.type == 'decode_tokens_response') { | 198 if (msg.type == 'decode_tokens_response') { |
182 this.handleCandidates_(JSON.parse(msg.tokens), msg.audible); | 199 this.handleCandidates_(msg.tokens, msg.audible); |
183 } else if (msg.type == 'detect_broadcast_response') { | 200 } else if (msg.type == 'detect_broadcast_response') { |
184 this.detectBroadcastCallback_(msg.detected); | 201 this.detectBroadcastCallback_(msg.detected); |
185 } | 202 } |
186 }; | 203 }; |
187 | 204 |
188 /** | 205 /** |
189 * Method to receive tokens from the decoder and process and forward them to the | 206 * Method to receive tokens from the decoder and process and forward them to the |
190 * token callback registered with us. | 207 * token callback registered with us. |
191 * @param {!Array.string} candidates Array of token candidates. | 208 * @param {!Array.string} candidates Array of token candidates. |
192 * @param {boolean} audible Whether the received candidates are from the audible | 209 * @param {boolean} audible Whether the received candidates are from the audible |
193 * decoder or not. | 210 * decoder or not. |
194 * @private | 211 * @private |
195 */ | 212 */ |
196 WhisperDecoder.prototype.handleCandidates_ = function(candidates, audible) { | 213 WhisperDecoder.prototype.handleCandidates_ = function(candidates, audible) { |
197 if (!this.tokenCallback_ || !candidates || candidates.length == 0) | 214 if (!this.tokenCallback_ || !candidates || candidates.length == 0) |
198 return; | 215 return; |
199 | 216 |
200 var returnCandidates = []; | 217 var returnCandidates = []; |
201 for (var i = 0; i < candidates.length; ++i) { | 218 for (var i = 0; i < candidates.length; ++i) { |
202 returnCandidates[i] = { token: bytesToBase64(candidates[i]), | 219 returnCandidates[i] = { token: bytesToBase64(candidates[i]), |
203 audible: audible }; | 220 audible: audible }; |
204 } | 221 } |
205 this.tokenCallback_(returnCandidates); | 222 this.tokenCallback_(returnCandidates); |
206 }; | 223 }; |
207 | 224 |
OLD | NEW |