| 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 FSMEventArgs event_args(EVENT_AUDIO_DATA); | 179 FSMEventArgs event_args(EVENT_AUDIO_DATA); |
| 180 event_args.audio_data = new AudioChunk(data, static_cast<size_t>(size), | 180 event_args.audio_data = new AudioChunk(data, static_cast<size_t>(size), |
| 181 kNumBitsPerAudioSample / 8); | 181 kNumBitsPerAudioSample / 8); |
| 182 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 182 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 183 base::Bind(&SpeechRecognizer::DispatchEvent, | 183 base::Bind(&SpeechRecognizer::DispatchEvent, |
| 184 this, event_args)); | 184 this, event_args)); |
| 185 } | 185 } |
| 186 | 186 |
| 187 void SpeechRecognizer::OnAudioClosed(AudioInputController*) {} | 187 void SpeechRecognizer::OnAudioClosed(AudioInputController*) {} |
| 188 | 188 |
| 189 void SpeechRecognizer::OnSpeechRecognitionEngineResults( | 189 void SpeechRecognizer::OnSpeechRecognitionEngineResult( |
| 190 const SpeechRecognitionResults& results) { | 190 const SpeechRecognitionResult& result) { |
| 191 FSMEventArgs event_args(EVENT_ENGINE_RESULT); | 191 FSMEventArgs event_args(EVENT_ENGINE_RESULT); |
| 192 event_args.engine_results = results; | 192 event_args.engine_result = result; |
| 193 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 193 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 194 base::Bind(&SpeechRecognizer::DispatchEvent, | 194 base::Bind(&SpeechRecognizer::DispatchEvent, |
| 195 this, event_args)); | 195 this, event_args)); |
| 196 } | 196 } |
| 197 | 197 |
| 198 void SpeechRecognizer::OnSpeechRecognitionEngineError( | 198 void SpeechRecognizer::OnSpeechRecognitionEngineError( |
| 199 const SpeechRecognitionError& error) { | 199 const SpeechRecognitionError& error) { |
| 200 FSMEventArgs event_args(EVENT_ENGINE_ERROR); | 200 FSMEventArgs event_args(EVENT_ENGINE_ERROR); |
| 201 event_args.engine_error = error; | 201 event_args.engine_error = error; |
| 202 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 202 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 if (state_ == STATE_ESTIMATING_ENVIRONMENT) { | 547 if (state_ == STATE_ESTIMATING_ENVIRONMENT) { |
| 548 DCHECK(endpointer_.IsEstimatingEnvironment()); | 548 DCHECK(endpointer_.IsEstimatingEnvironment()); |
| 549 endpointer_.SetUserInputMode(); | 549 endpointer_.SetUserInputMode(); |
| 550 listener_->OnEnvironmentEstimationComplete(session_id_); | 550 listener_->OnEnvironmentEstimationComplete(session_id_); |
| 551 } else if (state_ == STATE_WAITING_FOR_SPEECH) { | 551 } else if (state_ == STATE_WAITING_FOR_SPEECH) { |
| 552 listener_->OnSoundStart(session_id_); | 552 listener_->OnSoundStart(session_id_); |
| 553 } else { | 553 } else { |
| 554 DCHECK_EQ(STATE_RECOGNIZING, state_); | 554 DCHECK_EQ(STATE_RECOGNIZING, state_); |
| 555 } | 555 } |
| 556 | 556 |
| 557 listener_->OnRecognitionResults(session_id_, event_args.engine_results); | 557 const SpeechRecognitionResult& result = event_args.engine_result; |
| 558 listener_->OnRecognitionResult(session_id_, result); |
| 558 return STATE_RECOGNIZING; | 559 return STATE_RECOGNIZING; |
| 559 } | 560 } |
| 560 | 561 |
| 561 SpeechRecognizer::FSMState | 562 SpeechRecognizer::FSMState |
| 562 SpeechRecognizer::ProcessFinalResult(const FSMEventArgs& event_args) { | 563 SpeechRecognizer::ProcessFinalResult(const FSMEventArgs& event_args) { |
| 563 const SpeechRecognitionResults& results = event_args.engine_results; | 564 const SpeechRecognitionResult& result = event_args.engine_result; |
| 564 SpeechRecognitionResults::const_iterator i = results.begin(); | 565 if (result.is_provisional) { |
| 565 bool provisional_results_pending = false; | 566 DCHECK(!is_single_shot_); |
| 566 bool results_are_empty = true; | 567 listener_->OnRecognitionResult(session_id_, result); |
| 567 for (; i != results.end(); ++i) { | |
| 568 const SpeechRecognitionResult& result = *i; | |
| 569 if (result.is_provisional) { | |
| 570 provisional_results_pending = true; | |
| 571 DCHECK(!is_single_shot_); | |
| 572 } else if (results_are_empty) { | |
| 573 results_are_empty = result.hypotheses.empty(); | |
| 574 } | |
| 575 } | |
| 576 | |
| 577 if (provisional_results_pending) { | |
| 578 listener_->OnRecognitionResults(session_id_, results); | |
| 579 // We don't end the recognition if a provisional result is received in | 568 // We don't end the recognition if a provisional result is received in |
| 580 // STATE_WAITING_FINAL_RESULT. A definitive result will come next and will | 569 // STATE_WAITING_FINAL_RESULT. A definitive result will come next and will |
| 581 // end the recognition. | 570 // end the recognition. |
| 582 return state_; | 571 return state_; |
| 583 } | 572 } else { |
| 584 | 573 recognition_engine_->EndRecognition(); |
| 585 recognition_engine_->EndRecognition(); | |
| 586 | |
| 587 if (!results_are_empty) { | |
| 588 // We could receive an empty result (which we won't propagate further) | 574 // We could receive an empty result (which we won't propagate further) |
| 589 // in the following (continuous) scenario: | 575 // in the following (continuous) scenario: |
| 590 // 1. The caller start pushing audio and receives some results; | 576 // 1. The caller start pushing audio and receives some results; |
| 591 // 2. A |StopAudioCapture| is issued later; | 577 // 2. A |StopAudioCapture| is issued later; |
| 592 // 3. The final audio frames captured in the interval ]1,2] do not lead to | 578 // 3. The final audio frames captured in the interval ]1,2] do not lead to |
| 593 // any result (nor any error); | 579 // any result (nor any error); |
| 594 // 4. The speech recognition engine, therefore, emits an empty result to | 580 // 4. The speech recognition engine, therefore, emits an empty result to |
| 595 // notify that the recognition is ended with no error, yet neither any | 581 // notify that the recognition is ended with no error, yet neither any |
| 596 // further result. | 582 // further result. |
| 597 listener_->OnRecognitionResults(session_id_, results); | 583 if (result.hypotheses.size() > 0) |
| 584 listener_->OnRecognitionResult(session_id_, result); |
| 585 listener_->OnRecognitionEnd(session_id_); |
| 586 return STATE_IDLE; |
| 598 } | 587 } |
| 599 | |
| 600 listener_->OnRecognitionEnd(session_id_); | |
| 601 return STATE_IDLE; | |
| 602 } | 588 } |
| 603 | 589 |
| 604 SpeechRecognizer::FSMState | 590 SpeechRecognizer::FSMState |
| 605 SpeechRecognizer::DoNothing(const FSMEventArgs&) const { | 591 SpeechRecognizer::DoNothing(const FSMEventArgs&) const { |
| 606 return state_; // Just keep the current state. | 592 return state_; // Just keep the current state. |
| 607 } | 593 } |
| 608 | 594 |
| 609 SpeechRecognizer::FSMState | 595 SpeechRecognizer::FSMState |
| 610 SpeechRecognizer::NotFeasible(const FSMEventArgs& event_args) { | 596 SpeechRecognizer::NotFeasible(const FSMEventArgs& event_args) { |
| 611 NOTREACHED() << "Unfeasible event " << event_args.event | 597 NOTREACHED() << "Unfeasible event " << event_args.event |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 : event(event_value), | 646 : event(event_value), |
| 661 audio_error_code(0), | 647 audio_error_code(0), |
| 662 audio_data(NULL), | 648 audio_data(NULL), |
| 663 engine_error(SPEECH_RECOGNITION_ERROR_NONE) { | 649 engine_error(SPEECH_RECOGNITION_ERROR_NONE) { |
| 664 } | 650 } |
| 665 | 651 |
| 666 SpeechRecognizer::FSMEventArgs::~FSMEventArgs() { | 652 SpeechRecognizer::FSMEventArgs::~FSMEventArgs() { |
| 667 } | 653 } |
| 668 | 654 |
| 669 } // namespace content | 655 } // namespace content |
| OLD | NEW |