| 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/public/browser/speech_recognizer_delegate.h" | 10 #include "content/public/browser/speech_recognizer_delegate.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 #include "content/public/common/speech_input_result.h" | 12 #include "content/public/common/speech_recognition_result.h" |
| 13 #include "net/url_request/url_request_context_getter.h" | 13 #include "net/url_request/url_request_context_getter.h" |
| 14 | 14 |
| 15 using content::BrowserMainLoop; | 15 using content::BrowserMainLoop; |
| 16 using content::BrowserThread; | 16 using content::BrowserThread; |
| 17 using content::SpeechRecognizer; | 17 using content::SpeechRecognizer; |
| 18 using content::SpeechRecognizerDelegate; | 18 using content::SpeechRecognizerDelegate; |
| 19 using media::AudioInputController; | 19 using media::AudioInputController; |
| 20 using std::string; | 20 using std::string; |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 | 54 |
| 55 SpeechRecognizer* SpeechRecognizer::Create( | 55 SpeechRecognizer* SpeechRecognizer::Create( |
| 56 SpeechRecognizerDelegate* delegate, | 56 SpeechRecognizerDelegate* delegate, |
| 57 int caller_id, | 57 int caller_id, |
| 58 const std::string& language, | 58 const std::string& language, |
| 59 const std::string& grammar, | 59 const std::string& grammar, |
| 60 net::URLRequestContextGetter* context_getter, | 60 net::URLRequestContextGetter* context_getter, |
| 61 bool filter_profanities, | 61 bool filter_profanities, |
| 62 const std::string& hardware_info, | 62 const std::string& hardware_info, |
| 63 const std::string& origin_url) { | 63 const std::string& origin_url) { |
| 64 return new speech_input::SpeechRecognizerImpl( | 64 return new speech::SpeechRecognizerImpl( |
| 65 delegate, caller_id, language, grammar, context_getter, | 65 delegate, caller_id, language, grammar, context_getter, |
| 66 filter_profanities, hardware_info, origin_url); | 66 filter_profanities, hardware_info, origin_url); |
| 67 } | 67 } |
| 68 | 68 |
| 69 namespace speech_input { | 69 namespace speech { |
| 70 | 70 |
| 71 const int SpeechRecognizerImpl::kAudioSampleRate = 16000; | 71 const int SpeechRecognizerImpl::kAudioSampleRate = 16000; |
| 72 const int SpeechRecognizerImpl::kAudioPacketIntervalMs = 100; | 72 const int SpeechRecognizerImpl::kAudioPacketIntervalMs = 100; |
| 73 const ChannelLayout SpeechRecognizerImpl::kChannelLayout = CHANNEL_LAYOUT_MONO; | 73 const ChannelLayout SpeechRecognizerImpl::kChannelLayout = CHANNEL_LAYOUT_MONO; |
| 74 const int SpeechRecognizerImpl::kNumBitsPerAudioSample = 16; | 74 const int SpeechRecognizerImpl::kNumBitsPerAudioSample = 16; |
| 75 const int SpeechRecognizerImpl::kNoSpeechTimeoutSec = 8; | 75 const int SpeechRecognizerImpl::kNoSpeechTimeoutSec = 8; |
| 76 const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300; | 76 const int SpeechRecognizerImpl::kEndpointerEstimationTimeMs = 300; |
| 77 | 77 |
| 78 SpeechRecognizerImpl::SpeechRecognizerImpl( | 78 SpeechRecognizerImpl::SpeechRecognizerImpl( |
| 79 SpeechRecognizerDelegate* delegate, | 79 SpeechRecognizerDelegate* delegate, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 201 |
| 202 void SpeechRecognizerImpl::HandleOnError(int error_code) { | 202 void SpeechRecognizerImpl::HandleOnError(int error_code) { |
| 203 LOG(WARNING) << "SpeechRecognizer::HandleOnError, code=" << error_code; | 203 LOG(WARNING) << "SpeechRecognizer::HandleOnError, code=" << error_code; |
| 204 | 204 |
| 205 // Check if we are still recording before canceling recognition, as | 205 // Check if we are still recording before canceling recognition, as |
| 206 // recording might have been stopped after this error was posted to the queue | 206 // recording might have been stopped after this error was posted to the queue |
| 207 // by |OnError|. | 207 // by |OnError|. |
| 208 if (!audio_controller_.get()) | 208 if (!audio_controller_.get()) |
| 209 return; | 209 return; |
| 210 | 210 |
| 211 InformErrorAndCancelRecognition(content::SPEECH_INPUT_ERROR_AUDIO); | 211 InformErrorAndCancelRecognition(content::SPEECH_RECOGNITION_ERROR_AUDIO); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void SpeechRecognizerImpl::OnData(AudioInputController* controller, | 214 void SpeechRecognizerImpl::OnData(AudioInputController* controller, |
| 215 const uint8* data, uint32 size) { | 215 const uint8* data, uint32 size) { |
| 216 if (size == 0) // This could happen when recording stops and is normal. | 216 if (size == 0) // This could happen when recording stops and is normal. |
| 217 return; | 217 return; |
| 218 | 218 |
| 219 string* str_data = new string(reinterpret_cast<const char*>(data), size); | 219 string* str_data = new string(reinterpret_cast<const char*>(data), size); |
| 220 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 220 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 221 base::Bind(&SpeechRecognizerImpl::HandleOnData, | 221 base::Bind(&SpeechRecognizerImpl::HandleOnData, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 endpointer_.SetUserInputMode(); | 265 endpointer_.SetUserInputMode(); |
| 266 delegate_->DidCompleteEnvironmentEstimation(caller_id_); | 266 delegate_->DidCompleteEnvironmentEstimation(caller_id_); |
| 267 } | 267 } |
| 268 return; // No more processing since we are still estimating environment. | 268 return; // No more processing since we are still estimating environment. |
| 269 } | 269 } |
| 270 | 270 |
| 271 // Check if we have waited too long without hearing any speech. | 271 // Check if we have waited too long without hearing any speech. |
| 272 bool speech_was_heard_after_packet = endpointer_.DidStartReceivingSpeech(); | 272 bool speech_was_heard_after_packet = endpointer_.DidStartReceivingSpeech(); |
| 273 if (!speech_was_heard_after_packet && | 273 if (!speech_was_heard_after_packet && |
| 274 num_samples_recorded_ >= kNoSpeechTimeoutSec * kAudioSampleRate) { | 274 num_samples_recorded_ >= kNoSpeechTimeoutSec * kAudioSampleRate) { |
| 275 InformErrorAndCancelRecognition(content::SPEECH_INPUT_ERROR_NO_SPEECH); | 275 InformErrorAndCancelRecognition( |
| 276 content::SPEECH_RECOGNITION_ERROR_NO_SPEECH); |
| 276 return; | 277 return; |
| 277 } | 278 } |
| 278 | 279 |
| 279 if (!speech_was_heard_before_packet && speech_was_heard_after_packet) | 280 if (!speech_was_heard_before_packet && speech_was_heard_after_packet) |
| 280 delegate_->DidStartReceivingSpeech(caller_id_); | 281 delegate_->DidStartReceivingSpeech(caller_id_); |
| 281 | 282 |
| 282 // Calculate the input volume to display in the UI, smoothing towards the | 283 // Calculate the input volume to display in the UI, smoothing towards the |
| 283 // new level. | 284 // new level. |
| 284 float level = (rms - kAudioMeterMinDb) / | 285 float level = (rms - kAudioMeterMinDb) / |
| 285 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); | 286 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 296 kAudioMeterRangeMaxUnclipped); | 297 kAudioMeterRangeMaxUnclipped); |
| 297 | 298 |
| 298 delegate_->SetInputVolume(caller_id_, did_clip ? 1.0f : audio_level_, | 299 delegate_->SetInputVolume(caller_id_, did_clip ? 1.0f : audio_level_, |
| 299 noise_level); | 300 noise_level); |
| 300 | 301 |
| 301 if (endpointer_.speech_input_complete()) | 302 if (endpointer_.speech_input_complete()) |
| 302 StopRecording(); | 303 StopRecording(); |
| 303 } | 304 } |
| 304 | 305 |
| 305 void SpeechRecognizerImpl::SetRecognitionResult( | 306 void SpeechRecognizerImpl::SetRecognitionResult( |
| 306 const content::SpeechInputResult& result) { | 307 const content::SpeechRecognitionResult& result) { |
| 307 if (result.error != content::SPEECH_INPUT_ERROR_NONE) { | 308 if (result.error != content::SPEECH_RECOGNITION_ERROR_NONE) { |
| 308 InformErrorAndCancelRecognition(result.error); | 309 InformErrorAndCancelRecognition(result.error); |
| 309 return; | 310 return; |
| 310 } | 311 } |
| 311 | 312 |
| 312 // Guard against the delegate freeing us until we finish our job. | 313 // Guard against the delegate freeing us until we finish our job. |
| 313 scoped_refptr<SpeechRecognizerImpl> me(this); | 314 scoped_refptr<SpeechRecognizerImpl> me(this); |
| 314 delegate_->SetRecognitionResult(caller_id_, result); | 315 delegate_->SetRecognitionResult(caller_id_, result); |
| 315 delegate_->DidCompleteRecognition(caller_id_); | 316 delegate_->DidCompleteRecognition(caller_id_); |
| 316 } | 317 } |
| 317 | 318 |
| 318 void SpeechRecognizerImpl::InformErrorAndCancelRecognition( | 319 void SpeechRecognizerImpl::InformErrorAndCancelRecognition( |
| 319 content::SpeechInputError error) { | 320 content::SpeechRecognitionErrorCode error) { |
| 320 DCHECK_NE(error, content::SPEECH_INPUT_ERROR_NONE); | 321 DCHECK_NE(error, content::SPEECH_RECOGNITION_ERROR_NONE); |
| 321 CancelRecognition(); | 322 CancelRecognition(); |
| 322 | 323 |
| 323 // Guard against the delegate freeing us until we finish our job. | 324 // Guard against the delegate freeing us until we finish our job. |
| 324 scoped_refptr<SpeechRecognizerImpl> me(this); | 325 scoped_refptr<SpeechRecognizerImpl> me(this); |
| 325 delegate_->OnRecognizerError(caller_id_, error); | 326 delegate_->OnRecognizerError(caller_id_, error); |
| 326 } | 327 } |
| 327 | 328 |
| 328 void SpeechRecognizerImpl::CloseAudioControllerSynchronously() { | 329 void SpeechRecognizerImpl::CloseAudioControllerSynchronously() { |
| 329 VLOG(1) << "SpeechRecognizer stopping record."; | 330 VLOG(1) << "SpeechRecognizer stopping record."; |
| 330 | 331 |
| 331 // TODO(satish): investigate the possibility to utilize the closure | 332 // TODO(satish): investigate the possibility to utilize the closure |
| 332 // and switch to async. version of this method. Compare with how | 333 // and switch to async. version of this method. Compare with how |
| 333 // it's done in e.g. the AudioRendererHost. | 334 // it's done in e.g. the AudioRendererHost. |
| 334 base::WaitableEvent closed_event(true, false); | 335 base::WaitableEvent closed_event(true, false); |
| 335 audio_controller_->Close(base::Bind(&base::WaitableEvent::Signal, | 336 audio_controller_->Close(base::Bind(&base::WaitableEvent::Signal, |
| 336 base::Unretained(&closed_event))); | 337 base::Unretained(&closed_event))); |
| 337 closed_event.Wait(); | 338 closed_event.Wait(); |
| 338 audio_controller_ = NULL; // Releases the ref ptr. | 339 audio_controller_ = NULL; // Releases the ref ptr. |
| 339 } | 340 } |
| 340 | 341 |
| 341 void SpeechRecognizerImpl::SetAudioManagerForTesting( | 342 void SpeechRecognizerImpl::SetAudioManagerForTesting( |
| 342 AudioManager* audio_manager) { | 343 AudioManager* audio_manager) { |
| 343 audio_manager_ = audio_manager; | 344 audio_manager_ = audio_manager; |
| 344 } | 345 } |
| 345 | 346 |
| 346 } // namespace speech_input | 347 } // namespace speech |
| OLD | NEW |