OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "content/browser/speech/speech_recognizer_impl.h" | 5 #include "content/browser/speech/speech_recognizer_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/time.h" | 8 #include "base/time.h" |
9 #include "content/browser/browser_main_loop.h" | 9 #include "content/browser/browser_main_loop.h" |
10 #include "content/browser/speech/audio_buffer.h" | 10 #include "content/browser/speech/audio_buffer.h" |
11 #include "content/public/browser/speech_recognizer_delegate.h" | 11 #include "content/public/browser/speech_recognition_event_listener.h" |
12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
13 #include "content/public/common/speech_recognition_result.h" | 13 #include "content/public/common/speech_recognition_result.h" |
14 #include "net/url_request/url_request_context_getter.h" | 14 #include "net/url_request/url_request_context_getter.h" |
15 | 15 |
16 using content::BrowserMainLoop; | 16 using content::BrowserMainLoop; |
17 using content::BrowserThread; | 17 using content::BrowserThread; |
| 18 using content::SpeechRecognitionEventListener; |
18 using content::SpeechRecognizer; | 19 using content::SpeechRecognizer; |
19 using content::SpeechRecognizerDelegate; | |
20 using media::AudioInputController; | 20 using media::AudioInputController; |
21 using std::string; | 21 using std::string; |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 // The following constants are related to the volume level indicator shown in | 25 // The following constants are related to the volume level indicator shown in |
26 // the UI for recorded audio. | 26 // the UI for recorded audio. |
27 // Multiplier used when new volume is greater than previous level. | 27 // Multiplier used when new volume is greater than previous level. |
28 const float kUpSmoothingFactor = 1.0f; | 28 const float kUpSmoothingFactor = 1.0f; |
29 // Multiplier used when new volume is lesser than previous level. | 29 // Multiplier used when new volume is lesser than previous level. |
(...skipping 19 matching lines...) Expand all Loading... |
49 if (++clipping_samples > kThreshold) | 49 if (++clipping_samples > kThreshold) |
50 return true; | 50 return true; |
51 } | 51 } |
52 } | 52 } |
53 return false; | 53 return false; |
54 } | 54 } |
55 | 55 |
56 } // namespace | 56 } // namespace |
57 | 57 |
58 SpeechRecognizer* SpeechRecognizer::Create( | 58 SpeechRecognizer* SpeechRecognizer::Create( |
59 SpeechRecognizerDelegate* delegate, | 59 SpeechRecognitionEventListener* listener, |
60 int caller_id, | 60 int caller_id, |
61 const std::string& language, | 61 const std::string& language, |
62 const std::string& grammar, | 62 const std::string& grammar, |
63 net::URLRequestContextGetter* context_getter, | 63 net::URLRequestContextGetter* context_getter, |
64 bool filter_profanities, | 64 bool filter_profanities, |
65 const std::string& hardware_info, | 65 const std::string& hardware_info, |
66 const std::string& origin_url) { | 66 const std::string& origin_url) { |
67 return new speech::SpeechRecognizerImpl( | 67 return new speech::SpeechRecognizerImpl( |
68 delegate, caller_id, language, grammar, context_getter, | 68 listener, caller_id, language, grammar, context_getter, |
69 filter_profanities, hardware_info, origin_url); | 69 filter_profanities, hardware_info, origin_url); |
70 } | 70 } |
71 | 71 |
72 namespace speech { | 72 namespace speech { |
73 | 73 |
74 const int SpeechRecognizerImpl::kAudioSampleRate = 16000; | 74 const int SpeechRecognizerImpl::kAudioSampleRate = 16000; |
75 const int SpeechRecognizerImpl::kAudioPacketIntervalMs = 100; | 75 const int SpeechRecognizerImpl::kAudioPacketIntervalMs = 100; |
76 const ChannelLayout SpeechRecognizerImpl::kChannelLayout = CHANNEL_LAYOUT_MONO; | 76 const ChannelLayout SpeechRecognizerImpl::kChannelLayout = CHANNEL_LAYOUT_MONO; |
77 const int SpeechRecognizerImpl::kNumBitsPerAudioSample = 16; | 77 const int SpeechRecognizerImpl::kNumBitsPerAudioSample = 16; |
78 const int SpeechRecognizerImpl::kNoSpeechTimeoutSec = 8; | 78 const int SpeechRecognizerImpl::kNoSpeechTimeoutSec = 8; |
79 const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300; | 79 const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300; |
80 | 80 |
81 SpeechRecognizerImpl::SpeechRecognizerImpl( | 81 SpeechRecognizerImpl::SpeechRecognizerImpl( |
82 SpeechRecognizerDelegate* delegate, | 82 SpeechRecognitionEventListener* listener, |
83 int caller_id, | 83 int caller_id, |
84 const std::string& language, | 84 const std::string& language, |
85 const std::string& grammar, | 85 const std::string& grammar, |
86 net::URLRequestContextGetter* context_getter, | 86 net::URLRequestContextGetter* context_getter, |
87 bool filter_profanities, | 87 bool filter_profanities, |
88 const std::string& hardware_info, | 88 const std::string& hardware_info, |
89 const std::string& origin_url) | 89 const std::string& origin_url) |
90 : delegate_(delegate), | 90 : listener_(listener), |
91 caller_id_(caller_id), | 91 caller_id_(caller_id), |
92 language_(language), | 92 language_(language), |
93 grammar_(grammar), | 93 grammar_(grammar), |
94 filter_profanities_(filter_profanities), | 94 filter_profanities_(filter_profanities), |
95 hardware_info_(hardware_info), | 95 hardware_info_(hardware_info), |
96 origin_url_(origin_url), | 96 origin_url_(origin_url), |
97 context_getter_(context_getter), | 97 context_getter_(context_getter), |
98 codec_(AudioEncoder::CODEC_FLAC), | 98 codec_(AudioEncoder::CODEC_FLAC), |
99 encoder_(NULL), | 99 encoder_(NULL), |
100 endpointer_(kAudioSampleRate), | 100 endpointer_(kAudioSampleRate), |
(...skipping 10 matching lines...) Expand all Loading... |
111 | 111 |
112 SpeechRecognizerImpl::~SpeechRecognizerImpl() { | 112 SpeechRecognizerImpl::~SpeechRecognizerImpl() { |
113 // Recording should have stopped earlier due to the endpointer or | 113 // Recording should have stopped earlier due to the endpointer or |
114 // |StopRecording| being called. | 114 // |StopRecording| being called. |
115 DCHECK(!audio_controller_.get()); | 115 DCHECK(!audio_controller_.get()); |
116 DCHECK(!request_.get() || !request_->HasPendingRequest()); | 116 DCHECK(!request_.get() || !request_->HasPendingRequest()); |
117 DCHECK(!encoder_.get()); | 117 DCHECK(!encoder_.get()); |
118 endpointer_.EndSession(); | 118 endpointer_.EndSession(); |
119 } | 119 } |
120 | 120 |
121 bool SpeechRecognizerImpl::StartRecording() { | 121 bool SpeechRecognizerImpl::StartRecognition() { |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
123 DCHECK(!audio_controller_.get()); | 123 DCHECK(!audio_controller_.get()); |
124 DCHECK(!request_.get() || !request_->HasPendingRequest()); | 124 DCHECK(!request_.get() || !request_->HasPendingRequest()); |
125 DCHECK(!encoder_.get()); | 125 DCHECK(!encoder_.get()); |
126 | 126 |
127 // The endpointer needs to estimate the environment/background noise before | 127 // The endpointer needs to estimate the environment/background noise before |
128 // starting to treat the audio as user input. In |HandleOnData| we wait until | 128 // starting to treat the audio as user input. In |HandleOnData| we wait until |
129 // such time has passed before switching to user input mode. | 129 // such time has passed before switching to user input mode. |
130 endpointer_.SetEnvironmentEstimationMode(); | 130 endpointer_.SetEnvironmentEstimationMode(); |
131 | 131 |
132 encoder_.reset(AudioEncoder::Create(codec_, kAudioSampleRate, | 132 encoder_.reset(AudioEncoder::Create(codec_, kAudioSampleRate, |
133 kNumBitsPerAudioSample)); | 133 kNumBitsPerAudioSample)); |
134 int samples_per_packet = (kAudioSampleRate * kAudioPacketIntervalMs) / 1000; | 134 int samples_per_packet = (kAudioSampleRate * kAudioPacketIntervalMs) / 1000; |
135 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, | 135 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, |
136 kAudioSampleRate, kNumBitsPerAudioSample, | 136 kAudioSampleRate, kNumBitsPerAudioSample, |
137 samples_per_packet); | 137 samples_per_packet); |
138 audio_controller_ = AudioInputController::Create( | 138 audio_controller_ = AudioInputController::Create( |
139 audio_manager_ ? audio_manager_ : BrowserMainLoop::GetAudioManager(), | 139 audio_manager_ ? audio_manager_ : BrowserMainLoop::GetAudioManager(), |
140 this, params); | 140 this, params); |
141 DCHECK(audio_controller_.get()); | 141 DCHECK(audio_controller_.get()); |
142 VLOG(1) << "SpeechRecognizer starting record."; | 142 VLOG(1) << "SpeechRecognizer starting record."; |
143 num_samples_recorded_ = 0; | 143 num_samples_recorded_ = 0; |
144 audio_controller_->Record(); | 144 audio_controller_->Record(); |
145 | 145 |
146 return true; | 146 return true; |
147 } | 147 } |
148 | 148 |
149 void SpeechRecognizerImpl::CancelRecognition() { | 149 void SpeechRecognizerImpl::AbortRecognition() { |
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
151 DCHECK(audio_controller_.get() || request_.get()); | 151 DCHECK(audio_controller_.get() || request_.get()); |
152 | 152 |
153 // Stop recording if required. | 153 // Stop recording if required. |
154 if (audio_controller_.get()) { | 154 if (audio_controller_.get()) { |
155 CloseAudioControllerSynchronously(); | 155 CloseAudioControllerSynchronously(); |
156 } | 156 } |
157 | 157 |
158 VLOG(1) << "SpeechRecognizer canceling recognition."; | 158 VLOG(1) << "SpeechRecognizer canceling recognition."; |
159 encoder_.reset(); | 159 encoder_.reset(); |
160 request_.reset(); | 160 request_.reset(); |
161 } | 161 } |
162 | 162 |
163 void SpeechRecognizerImpl::StopRecording() { | 163 void SpeechRecognizerImpl::StopAudioCapture() { |
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
165 | 165 |
166 // If audio recording has already stopped and we are in recognition phase, | 166 // If audio recording has already stopped and we are in recognition phase, |
167 // silently ignore any more calls to stop recording. | 167 // silently ignore any more calls to stop recording. |
168 if (!audio_controller_.get()) | 168 if (!audio_controller_.get()) |
169 return; | 169 return; |
170 | 170 |
171 CloseAudioControllerSynchronously(); | 171 CloseAudioControllerSynchronously(); |
172 | 172 |
173 delegate_->DidStopReceivingSpeech(caller_id_); | 173 listener_->OnSoundEnd(caller_id_); |
174 delegate_->DidCompleteRecording(caller_id_); | 174 listener_->OnAudioEnd(caller_id_); |
175 | 175 |
176 // UploadAudioChunk requires a non-empty final buffer. So we encode a packet | 176 // UploadAudioChunk requires a non-empty final buffer. So we encode a packet |
177 // of silence in case encoder had no data already. | 177 // of silence in case encoder had no data already. |
178 std::vector<short> samples((kAudioSampleRate * kAudioPacketIntervalMs) / | 178 std::vector<short> samples((kAudioSampleRate * kAudioPacketIntervalMs) / |
179 1000); | 179 1000); |
180 AudioChunk dummy_chunk(reinterpret_cast<uint8*>(&samples[0]), | 180 AudioChunk dummy_chunk(reinterpret_cast<uint8*>(&samples[0]), |
181 samples.size() * sizeof(short), | 181 samples.size() * sizeof(short), |
182 encoder_->bits_per_sample() / 8); | 182 encoder_->bits_per_sample() / 8); |
183 encoder_->Encode(dummy_chunk); | 183 encoder_->Encode(dummy_chunk); |
184 encoder_->Flush(); | 184 encoder_->Flush(); |
185 scoped_ptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear()); | 185 scoped_ptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear()); |
186 DCHECK(!encoded_data->IsEmpty()); | 186 DCHECK(!encoded_data->IsEmpty()); |
187 encoder_.reset(); | 187 encoder_.reset(); |
188 | 188 |
189 // If we haven't got any audio yet end the recognition sequence here. | 189 // If we haven't got any audio yet end the recognition sequence here. |
190 if (request_ == NULL) { | 190 if (request_ == NULL) { |
191 // Guard against the delegate freeing us until we finish our job. | 191 // Guard against the listener freeing us until we finish our job. |
192 scoped_refptr<SpeechRecognizerImpl> me(this); | 192 scoped_refptr<SpeechRecognizerImpl> me(this); |
193 delegate_->DidCompleteRecognition(caller_id_); | 193 listener_->OnRecognitionEnd(caller_id_); |
194 } else { | 194 } else { |
195 request_->UploadAudioChunk(*encoded_data, true /* is_last_chunk */); | 195 request_->UploadAudioChunk(*encoded_data, true /* is_last_chunk */); |
196 } | 196 } |
197 } | 197 } |
198 | 198 |
199 // Invoked in the audio thread. | 199 // Invoked in the audio thread. |
200 void SpeechRecognizerImpl::OnError(AudioInputController* controller, | 200 void SpeechRecognizerImpl::OnError(AudioInputController* controller, |
201 int error_code) { | 201 int error_code) { |
202 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 202 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
203 base::Bind(&SpeechRecognizerImpl::HandleOnError, | 203 base::Bind(&SpeechRecognizerImpl::HandleOnError, |
204 this, error_code)); | 204 this, error_code)); |
205 } | 205 } |
206 | 206 |
207 void SpeechRecognizerImpl::HandleOnError(int error_code) { | 207 void SpeechRecognizerImpl::HandleOnError(int error_code) { |
208 LOG(WARNING) << "SpeechRecognizer::HandleOnError, code=" << error_code; | 208 LOG(WARNING) << "SpeechRecognizer::HandleOnError, code=" << error_code; |
209 | 209 |
210 // Check if we are still recording before canceling recognition, as | 210 // Check if we are still recording before canceling recognition, as |
211 // recording might have been stopped after this error was posted to the queue | 211 // recording might have been stopped after this error was posted to the queue |
212 // by |OnError|. | 212 // by |OnError|. |
213 if (!audio_controller_.get()) | 213 if (!audio_controller_.get()) |
214 return; | 214 return; |
215 | 215 |
216 InformErrorAndCancelRecognition(content::SPEECH_RECOGNITION_ERROR_AUDIO); | 216 InformErrorAndAbortRecognition(content::SPEECH_RECOGNITION_ERROR_AUDIO); |
217 } | 217 } |
218 | 218 |
219 void SpeechRecognizerImpl::OnData(AudioInputController* controller, | 219 void SpeechRecognizerImpl::OnData(AudioInputController* controller, |
220 const uint8* data, uint32 size) { | 220 const uint8* data, uint32 size) { |
221 if (size == 0) // This could happen when recording stops and is normal. | 221 if (size == 0) // This could happen when recording stops and is normal. |
222 return; | 222 return; |
223 AudioChunk* raw_audio = new AudioChunk(data, static_cast<size_t>(size), | 223 AudioChunk* raw_audio = new AudioChunk(data, static_cast<size_t>(size), |
224 kNumBitsPerAudioSample / 8); | 224 kNumBitsPerAudioSample / 8); |
225 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 225 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
226 base::Bind(&SpeechRecognizerImpl::HandleOnData, | 226 base::Bind(&SpeechRecognizerImpl::HandleOnData, |
(...skipping 11 matching lines...) Expand all Loading... |
238 bool speech_was_heard_before_packet = endpointer_.DidStartReceivingSpeech(); | 238 bool speech_was_heard_before_packet = endpointer_.DidStartReceivingSpeech(); |
239 | 239 |
240 encoder_->Encode(*raw_audio); | 240 encoder_->Encode(*raw_audio); |
241 float rms; | 241 float rms; |
242 endpointer_.ProcessAudio(*raw_audio, &rms); | 242 endpointer_.ProcessAudio(*raw_audio, &rms); |
243 bool did_clip = DetectClipping(*raw_audio); | 243 bool did_clip = DetectClipping(*raw_audio); |
244 num_samples_recorded_ += raw_audio->NumSamples(); | 244 num_samples_recorded_ += raw_audio->NumSamples(); |
245 | 245 |
246 if (request_ == NULL) { | 246 if (request_ == NULL) { |
247 // This was the first audio packet recorded, so start a request to the | 247 // This was the first audio packet recorded, so start a request to the |
248 // server to send the data and inform the delegate. | 248 // server to send the data and inform the listener. |
249 delegate_->DidStartReceivingAudio(caller_id_); | 249 listener_->OnAudioStart(caller_id_); |
250 request_.reset(new SpeechRecognitionRequest(context_getter_.get(), this)); | 250 request_.reset(new SpeechRecognitionRequest(context_getter_.get(), this)); |
251 request_->Start(language_, grammar_, filter_profanities_, | 251 request_->Start(language_, grammar_, filter_profanities_, |
252 hardware_info_, origin_url_, encoder_->mime_type()); | 252 hardware_info_, origin_url_, encoder_->mime_type()); |
253 } | 253 } |
254 | 254 |
255 scoped_ptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear()); | 255 scoped_ptr<AudioChunk> encoded_data(encoder_->GetEncodedDataAndClear()); |
256 DCHECK(!encoded_data->IsEmpty()); | 256 DCHECK(!encoded_data->IsEmpty()); |
257 request_->UploadAudioChunk(*encoded_data, false /* is_last_chunk */); | 257 request_->UploadAudioChunk(*encoded_data, false /* is_last_chunk */); |
258 | 258 |
259 if (endpointer_.IsEstimatingEnvironment()) { | 259 if (endpointer_.IsEstimatingEnvironment()) { |
260 // Check if we have gathered enough audio for the endpointer to do | 260 // Check if we have gathered enough audio for the endpointer to do |
261 // environment estimation and should move on to detect speech/end of speech. | 261 // environment estimation and should move on to detect speech/end of speech. |
262 if (num_samples_recorded_ >= (kEndpointerEstimationTimeMs * | 262 if (num_samples_recorded_ >= (kEndpointerEstimationTimeMs * |
263 kAudioSampleRate) / 1000) { | 263 kAudioSampleRate) / 1000) { |
264 endpointer_.SetUserInputMode(); | 264 endpointer_.SetUserInputMode(); |
265 delegate_->DidCompleteEnvironmentEstimation(caller_id_); | 265 listener_->OnEnvironmentEstimationComplete(caller_id_); |
266 } | 266 } |
267 return; // No more processing since we are still estimating environment. | 267 return; // No more processing since we are still estimating environment. |
268 } | 268 } |
269 | 269 |
270 // Check if we have waited too long without hearing any speech. | 270 // Check if we have waited too long without hearing any speech. |
271 bool speech_was_heard_after_packet = endpointer_.DidStartReceivingSpeech(); | 271 bool speech_was_heard_after_packet = endpointer_.DidStartReceivingSpeech(); |
272 if (!speech_was_heard_after_packet && | 272 if (!speech_was_heard_after_packet && |
273 num_samples_recorded_ >= kNoSpeechTimeoutSec * kAudioSampleRate) { | 273 num_samples_recorded_ >= kNoSpeechTimeoutSec * kAudioSampleRate) { |
274 InformErrorAndCancelRecognition( | 274 InformErrorAndAbortRecognition( |
275 content::SPEECH_RECOGNITION_ERROR_NO_SPEECH); | 275 content::SPEECH_RECOGNITION_ERROR_NO_SPEECH); |
276 return; | 276 return; |
277 } | 277 } |
278 | 278 |
279 if (!speech_was_heard_before_packet && speech_was_heard_after_packet) | 279 if (!speech_was_heard_before_packet && speech_was_heard_after_packet) |
280 delegate_->DidStartReceivingSpeech(caller_id_); | 280 listener_->OnSoundStart(caller_id_); |
281 | 281 |
282 // Calculate the input volume to display in the UI, smoothing towards the | 282 // Calculate the input volume to display in the UI, smoothing towards the |
283 // new level. | 283 // new level. |
284 float level = (rms - kAudioMeterMinDb) / | 284 float level = (rms - kAudioMeterMinDb) / |
285 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); | 285 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); |
286 level = std::min(std::max(0.0f, level), kAudioMeterRangeMaxUnclipped); | 286 level = std::min(std::max(0.0f, level), kAudioMeterRangeMaxUnclipped); |
287 if (level > audio_level_) { | 287 if (level > audio_level_) { |
288 audio_level_ += (level - audio_level_) * kUpSmoothingFactor; | 288 audio_level_ += (level - audio_level_) * kUpSmoothingFactor; |
289 } else { | 289 } else { |
290 audio_level_ += (level - audio_level_) * kDownSmoothingFactor; | 290 audio_level_ += (level - audio_level_) * kDownSmoothingFactor; |
291 } | 291 } |
292 | 292 |
293 float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) / | 293 float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) / |
294 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); | 294 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); |
295 noise_level = std::min(std::max(0.0f, noise_level), | 295 noise_level = std::min(std::max(0.0f, noise_level), |
296 kAudioMeterRangeMaxUnclipped); | 296 kAudioMeterRangeMaxUnclipped); |
297 | 297 |
298 delegate_->SetInputVolume(caller_id_, did_clip ? 1.0f : audio_level_, | 298 listener_->OnAudioLevelsChange(caller_id_, did_clip ? 1.0f : audio_level_, |
299 noise_level); | 299 noise_level); |
300 | 300 |
301 if (endpointer_.speech_input_complete()) | 301 if (endpointer_.speech_input_complete()) |
302 StopRecording(); | 302 StopAudioCapture(); |
303 } | 303 } |
304 | 304 |
305 void SpeechRecognizerImpl::SetRecognitionResult( | 305 void SpeechRecognizerImpl::SetRecognitionResult( |
306 const content::SpeechRecognitionResult& result) { | 306 const content::SpeechRecognitionResult& result) { |
307 if (result.error != content::SPEECH_RECOGNITION_ERROR_NONE) { | 307 if (result.error != content::SPEECH_RECOGNITION_ERROR_NONE) { |
308 InformErrorAndCancelRecognition(result.error); | 308 InformErrorAndAbortRecognition(result.error); |
309 return; | 309 return; |
310 } | 310 } |
311 | 311 |
312 // Guard against the delegate freeing us until we finish our job. | 312 // Guard against the listener freeing us until we finish our job. |
313 scoped_refptr<SpeechRecognizerImpl> me(this); | 313 scoped_refptr<SpeechRecognizerImpl> me(this); |
314 delegate_->SetRecognitionResult(caller_id_, result); | 314 listener_->OnRecognitionResult(caller_id_, result); |
315 delegate_->DidCompleteRecognition(caller_id_); | 315 listener_->OnRecognitionEnd(caller_id_); |
316 } | 316 } |
317 | 317 |
318 void SpeechRecognizerImpl::InformErrorAndCancelRecognition( | 318 void SpeechRecognizerImpl::InformErrorAndAbortRecognition( |
319 content::SpeechRecognitionErrorCode error) { | 319 content::SpeechRecognitionErrorCode error) { |
320 DCHECK_NE(error, content::SPEECH_RECOGNITION_ERROR_NONE); | 320 DCHECK_NE(error, content::SPEECH_RECOGNITION_ERROR_NONE); |
321 CancelRecognition(); | 321 AbortRecognition(); |
322 | 322 |
323 // Guard against the delegate freeing us until we finish our job. | 323 // Guard against the listener freeing us until we finish our job. |
324 scoped_refptr<SpeechRecognizerImpl> me(this); | 324 scoped_refptr<SpeechRecognizerImpl> me(this); |
325 delegate_->OnRecognizerError(caller_id_, error); | 325 listener_->OnRecognitionError(caller_id_, error); |
326 } | 326 } |
327 | 327 |
328 void SpeechRecognizerImpl::CloseAudioControllerSynchronously() { | 328 void SpeechRecognizerImpl::CloseAudioControllerSynchronously() { |
329 VLOG(1) << "SpeechRecognizer stopping record."; | 329 VLOG(1) << "SpeechRecognizer stopping record."; |
330 | 330 |
331 // TODO(satish): investigate the possibility to utilize the closure | 331 // TODO(satish): investigate the possibility to utilize the closure |
332 // and switch to async. version of this method. Compare with how | 332 // and switch to async. version of this method. Compare with how |
333 // it's done in e.g. the AudioRendererHost. | 333 // it's done in e.g. the AudioRendererHost. |
334 base::WaitableEvent closed_event(true, false); | 334 base::WaitableEvent closed_event(true, false); |
335 audio_controller_->Close(base::Bind(&base::WaitableEvent::Signal, | 335 audio_controller_->Close(base::Bind(&base::WaitableEvent::Signal, |
336 base::Unretained(&closed_event))); | 336 base::Unretained(&closed_event))); |
337 closed_event.Wait(); | 337 closed_event.Wait(); |
338 audio_controller_ = NULL; // Releases the ref ptr. | 338 audio_controller_ = NULL; // Releases the ref ptr. |
339 } | 339 } |
340 | 340 |
341 void SpeechRecognizerImpl::SetAudioManagerForTesting( | 341 void SpeechRecognizerImpl::SetAudioManagerForTesting( |
342 AudioManager* audio_manager) { | 342 AudioManager* audio_manager) { |
343 audio_manager_ = audio_manager; | 343 audio_manager_ = audio_manager; |
344 } | 344 } |
345 | 345 |
| 346 bool SpeechRecognizerImpl::IsActive() const { |
| 347 return (request_.get() != NULL); |
| 348 } |
| 349 |
| 350 bool SpeechRecognizerImpl::IsCapturingAudio() const { |
| 351 return (audio_controller_.get() != NULL); |
| 352 } |
| 353 |
346 } // namespace speech | 354 } // namespace speech |
OLD | NEW |