Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: content/browser/speech/speech_recognizer_impl.cc

Issue 9688012: Refactoring of chrome speech recognition architecture (CL1.2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor fix in recognizer unit test due to "others" CL in the middle (9692038) Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/speech/speech_recognizer_impl.h ('k') | content/browser/speech/speech_recognizer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698