| 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.h" | 5 #include "content/browser/speech/speech_recognizer.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "content/browser/browser_main_loop.h" | 10 #include "content/browser/browser_main_loop.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 66 |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 namespace speech { | 69 namespace speech { |
| 70 | 70 |
| 71 const int SpeechRecognizer::kAudioSampleRate = 16000; | 71 const int SpeechRecognizer::kAudioSampleRate = 16000; |
| 72 const ChannelLayout SpeechRecognizer::kChannelLayout = CHANNEL_LAYOUT_MONO; | 72 const ChannelLayout SpeechRecognizer::kChannelLayout = CHANNEL_LAYOUT_MONO; |
| 73 const int SpeechRecognizer::kNumBitsPerAudioSample = 16; | 73 const int SpeechRecognizer::kNumBitsPerAudioSample = 16; |
| 74 const int SpeechRecognizer::kNoSpeechTimeoutMs = 8000; | 74 const int SpeechRecognizer::kNoSpeechTimeoutMs = 8000; |
| 75 const int SpeechRecognizer::kEndpointerEstimationTimeMs = 300; | 75 const int SpeechRecognizer::kEndpointerEstimationTimeMs = 300; |
| 76 media::AudioManager* SpeechRecognizer::audio_manager_for_tests_ = NULL; |
| 76 | 77 |
| 77 COMPILE_ASSERT(SpeechRecognizer::kNumBitsPerAudioSample % 8 == 0, | 78 COMPILE_ASSERT(SpeechRecognizer::kNumBitsPerAudioSample % 8 == 0, |
| 78 kNumBitsPerAudioSample_must_be_a_multiple_of_8); | 79 kNumBitsPerAudioSample_must_be_a_multiple_of_8); |
| 79 | 80 |
| 80 SpeechRecognizer::SpeechRecognizer( | 81 SpeechRecognizer::SpeechRecognizer( |
| 81 SpeechRecognitionEventListener* listener, | 82 SpeechRecognitionEventListener* listener, |
| 82 int session_id, | 83 int session_id, |
| 83 bool is_single_shot, | 84 bool is_single_shot, |
| 84 SpeechRecognitionEngine* engine) | 85 SpeechRecognitionEngine* engine) |
| 85 : listener_(listener), | 86 : listener_(listener), |
| 86 testing_audio_manager_(NULL), | |
| 87 recognition_engine_(engine), | 87 recognition_engine_(engine), |
| 88 endpointer_(kAudioSampleRate), | 88 endpointer_(kAudioSampleRate), |
| 89 session_id_(session_id), | 89 session_id_(session_id), |
| 90 is_dispatching_event_(false), | 90 is_dispatching_event_(false), |
| 91 is_single_shot_(is_single_shot), | 91 is_single_shot_(is_single_shot), |
| 92 state_(STATE_IDLE) { | 92 state_(STATE_IDLE) { |
| 93 DCHECK(listener_ != NULL); | 93 DCHECK(listener_ != NULL); |
| 94 DCHECK(recognition_engine_ != NULL); | 94 DCHECK(recognition_engine_ != NULL); |
| 95 if (is_single_shot) { | 95 if (is_single_shot) { |
| 96 // In single shot recognition, the session is automatically ended after: | 96 // In single shot recognition, the session is automatically ended after: |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 scoped_refptr<SpeechRecognizer> me(this); | 235 scoped_refptr<SpeechRecognizer> me(this); |
| 236 | 236 |
| 237 if (event_args.event == EVENT_AUDIO_DATA) { | 237 if (event_args.event == EVENT_AUDIO_DATA) { |
| 238 DCHECK(event_args.audio_data.get() != NULL); | 238 DCHECK(event_args.audio_data.get() != NULL); |
| 239 ProcessAudioPipeline(*event_args.audio_data); | 239 ProcessAudioPipeline(*event_args.audio_data); |
| 240 } | 240 } |
| 241 | 241 |
| 242 // The audio pipeline must be processed before the event dispatch, otherwise | 242 // The audio pipeline must be processed before the event dispatch, otherwise |
| 243 // it would take actions according to the future state instead of the current. | 243 // it would take actions according to the future state instead of the current. |
| 244 state_ = ExecuteTransitionAndGetNextState(event_args); | 244 state_ = ExecuteTransitionAndGetNextState(event_args); |
| 245 | |
| 246 is_dispatching_event_ = false; | 245 is_dispatching_event_ = false; |
| 247 } | 246 } |
| 248 | 247 |
| 249 SpeechRecognizer::FSMState | 248 SpeechRecognizer::FSMState |
| 250 SpeechRecognizer::ExecuteTransitionAndGetNextState( | 249 SpeechRecognizer::ExecuteTransitionAndGetNextState( |
| 251 const FSMEventArgs& event_args) { | 250 const FSMEventArgs& event_args) { |
| 252 const FSMEvent event = event_args.event; | 251 const FSMEvent event = event_args.event; |
| 253 switch (state_) { | 252 switch (state_) { |
| 254 case STATE_IDLE: | 253 case STATE_IDLE: |
| 255 switch (event) { | 254 switch (event) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 if (route_to_sr_engine) { | 385 if (route_to_sr_engine) { |
| 387 DCHECK(recognition_engine_.get() != NULL); | 386 DCHECK(recognition_engine_.get() != NULL); |
| 388 recognition_engine_->TakeAudioChunk(raw_audio); | 387 recognition_engine_->TakeAudioChunk(raw_audio); |
| 389 } | 388 } |
| 390 } | 389 } |
| 391 | 390 |
| 392 SpeechRecognizer::FSMState | 391 SpeechRecognizer::FSMState |
| 393 SpeechRecognizer::StartRecording(const FSMEventArgs&) { | 392 SpeechRecognizer::StartRecording(const FSMEventArgs&) { |
| 394 DCHECK(recognition_engine_.get() != NULL); | 393 DCHECK(recognition_engine_.get() != NULL); |
| 395 DCHECK(!IsCapturingAudio()); | 394 DCHECK(!IsCapturingAudio()); |
| 396 AudioManager* audio_manager = (testing_audio_manager_ != NULL) ? | 395 AudioManager* audio_manager = (audio_manager_for_tests_ != NULL) ? |
| 397 testing_audio_manager_ : | 396 audio_manager_for_tests_ : |
| 398 BrowserMainLoop::GetAudioManager(); | 397 BrowserMainLoop::GetAudioManager(); |
| 399 DCHECK(audio_manager != NULL); | 398 DCHECK(audio_manager != NULL); |
| 400 | 399 |
| 401 DVLOG(1) << "SpeechRecognizer starting audio capture."; | 400 DVLOG(1) << "SpeechRecognizer starting audio capture."; |
| 402 num_samples_recorded_ = 0; | 401 num_samples_recorded_ = 0; |
| 403 audio_level_ = 0; | 402 audio_level_ = 0; |
| 404 listener_->OnRecognitionStart(session_id_); | 403 listener_->OnRecognitionStart(session_id_); |
| 405 | 404 |
| 406 if (!audio_manager->HasAudioInputDevices()) { | 405 if (!audio_manager->HasAudioInputDevices()) { |
| 407 return Abort(SpeechRecognitionError( | 406 return Abort(SpeechRecognitionError( |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 | 641 |
| 643 float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) / | 642 float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) / |
| 644 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); | 643 (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); |
| 645 noise_level = std::min(std::max(0.0f, noise_level), | 644 noise_level = std::min(std::max(0.0f, noise_level), |
| 646 kAudioMeterRangeMaxUnclipped); | 645 kAudioMeterRangeMaxUnclipped); |
| 647 | 646 |
| 648 listener_->OnAudioLevelsChange( | 647 listener_->OnAudioLevelsChange( |
| 649 session_id_, clip_detected ? 1.0f : audio_level_, noise_level); | 648 session_id_, clip_detected ? 1.0f : audio_level_, noise_level); |
| 650 } | 649 } |
| 651 | 650 |
| 652 void SpeechRecognizer::SetAudioManagerForTesting( | 651 void SpeechRecognizer::SetAudioManagerForTests( |
| 653 AudioManager* audio_manager) { | 652 AudioManager* audio_manager) { |
| 654 testing_audio_manager_ = audio_manager; | 653 audio_manager_for_tests_ = audio_manager; |
| 655 } | 654 } |
| 656 | 655 |
| 657 SpeechRecognizer::FSMEventArgs::FSMEventArgs(FSMEvent event_value) | 656 SpeechRecognizer::FSMEventArgs::FSMEventArgs(FSMEvent event_value) |
| 658 : event(event_value), | 657 : event(event_value), |
| 659 audio_error_code(0), | 658 audio_error_code(0), |
| 660 audio_data(NULL), | 659 audio_data(NULL), |
| 661 engine_error(content::SPEECH_RECOGNITION_ERROR_NONE) { | 660 engine_error(content::SPEECH_RECOGNITION_ERROR_NONE) { |
| 662 } | 661 } |
| 663 | 662 |
| 664 SpeechRecognizer::FSMEventArgs::~FSMEventArgs() { | 663 SpeechRecognizer::FSMEventArgs::~FSMEventArgs() { |
| 665 } | 664 } |
| 666 | 665 |
| 667 } // namespace speech | 666 } // namespace speech |
| OLD | NEW |