diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-26 18:46:15 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-26 18:46:15 +0000 |
commit | 50fab53bddb2c3cb24d5682c913a03226ccf49ef (patch) | |
tree | bb04af83ca5f2be010e32c2e10cfd245117a4847 /content/browser/speech/speech_recognizer_unittest.cc | |
parent | 5c557f37629dc12dfd99e8fb55c235c8c46a8098 (diff) | |
download | chromium_src-50fab53bddb2c3cb24d5682c913a03226ccf49ef.zip chromium_src-50fab53bddb2c3cb24d5682c913a03226ccf49ef.tar.gz chromium_src-50fab53bddb2c3cb24d5682c913a03226ccf49ef.tar.bz2 |
Move core pieces of speech from chrome to content.
TBR=satish
Review URL: http://codereview.chromium.org/6591024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/speech/speech_recognizer_unittest.cc')
-rw-r--r-- | content/browser/speech/speech_recognizer_unittest.cc | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/content/browser/speech/speech_recognizer_unittest.cc b/content/browser/speech/speech_recognizer_unittest.cc new file mode 100644 index 0000000..8365396 --- /dev/null +++ b/content/browser/speech/speech_recognizer_unittest.cc @@ -0,0 +1,300 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "chrome/common/net/test_url_fetcher_factory.h" +#include "content/browser/browser_thread.h" +#include "content/browser/speech/speech_recognizer.h" +#include "media/audio/test_audio_input_controller_factory.h" +#include "net/url_request/url_request_status.h" +#include "testing/gtest/include/gtest/gtest.h" + +using media::AudioInputController; +using media::TestAudioInputController; +using media::TestAudioInputControllerFactory; + +namespace speech_input { + +class SpeechRecognizerTest : public SpeechRecognizerDelegate, + public testing::Test { + public: + SpeechRecognizerTest() + : io_thread_(BrowserThread::IO, &message_loop_), + ALLOW_THIS_IN_INITIALIZER_LIST( + recognizer_(new SpeechRecognizer(this, 1, std::string(), + std::string(), std::string(), + std::string()))), + recording_complete_(false), + recognition_complete_(false), + result_received_(false), + error_(SpeechRecognizer::RECOGNIZER_NO_ERROR), + volume_(-1.0f) { + int audio_packet_length_bytes = + (SpeechRecognizer::kAudioSampleRate * + SpeechRecognizer::kAudioPacketIntervalMs * + SpeechRecognizer::kNumAudioChannels * + SpeechRecognizer::kNumBitsPerAudioSample) / (8 * 1000); + audio_packet_.resize(audio_packet_length_bytes); + } + + // SpeechRecognizer::Delegate methods. + virtual void SetRecognitionResult(int caller_id, + bool error, + const SpeechInputResultArray& result) { + result_received_ = true; + } + + virtual void DidCompleteRecording(int caller_id) { + recording_complete_ = true; + } + + virtual void DidCompleteRecognition(int caller_id) { + recognition_complete_ = true; + } + + virtual void DidCompleteEnvironmentEstimation(int caller_id) { + } + + virtual void OnRecognizerError(int caller_id, + SpeechRecognizer::ErrorCode error) { + error_ = error; + } + + virtual void SetInputVolume(int caller_id, float volume) { + volume_ = volume; + } + + // testing::Test methods. + virtual void SetUp() { + URLFetcher::set_factory(&url_fetcher_factory_); + AudioInputController::set_factory(&audio_input_controller_factory_); + } + + virtual void TearDown() { + URLFetcher::set_factory(NULL); + AudioInputController::set_factory(NULL); + } + + void FillPacketWithTestWaveform() { + // Fill the input with a simple pattern, a 125Hz sawtooth waveform. + for (size_t i = 0; i < audio_packet_.size(); ++i) + audio_packet_[i] = static_cast<uint8>(i); + } + + protected: + MessageLoopForIO message_loop_; + BrowserThread io_thread_; + scoped_refptr<SpeechRecognizer> recognizer_; + bool recording_complete_; + bool recognition_complete_; + bool result_received_; + SpeechRecognizer::ErrorCode error_; + TestURLFetcherFactory url_fetcher_factory_; + TestAudioInputControllerFactory audio_input_controller_factory_; + std::vector<uint8> audio_packet_; + float volume_; +}; + +TEST_F(SpeechRecognizerTest, StopNoData) { + // Check for callbacks when stopping record before any audio gets recorded. + EXPECT_TRUE(recognizer_->StartRecording()); + recognizer_->CancelRecognition(); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); +} + +TEST_F(SpeechRecognizerTest, CancelNoData) { + // Check for callbacks when canceling recognition before any audio gets + // recorded. + EXPECT_TRUE(recognizer_->StartRecording()); + recognizer_->StopRecording(); + EXPECT_TRUE(recording_complete_); + EXPECT_TRUE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); +} + +TEST_F(SpeechRecognizerTest, StopWithData) { + // Start recording, give some data and then stop. This should wait for the + // network callback to arrive before completion. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller = audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + MessageLoop::current()->RunAllPending(); + recognizer_->StopRecording(); + EXPECT_TRUE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); + + // Issue the network callback to complete the process. + TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); + ASSERT_TRUE(fetcher); + net::URLRequestStatus status; + status.set_status(net::URLRequestStatus::SUCCESS); + fetcher->delegate()->OnURLFetchComplete( + fetcher, fetcher->original_url(), status, 200, ResponseCookies(), + "{\"hypotheses\":[{\"utterance\":\"123\"}]}"); + EXPECT_TRUE(recognition_complete_); + EXPECT_TRUE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); +} + +TEST_F(SpeechRecognizerTest, CancelWithData) { + // Start recording, give some data and then cancel. This should not create + // a network request and finish immediately. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + MessageLoop::current()->RunAllPending(); + recognizer_->CancelRecognition(); + EXPECT_EQ(NULL, url_fetcher_factory_.GetFetcherByID(0)); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); +} + +TEST_F(SpeechRecognizerTest, AudioControllerErrorNoData) { + // Check if things tear down properly if AudioInputController threw an error. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller->event_handler()->OnError(controller, 0); + MessageLoop::current()->RunAllPending(); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_ERROR_CAPTURE, error_); +} + +TEST_F(SpeechRecognizerTest, AudioControllerErrorWithData) { + // Check if things tear down properly if AudioInputController threw an error + // after giving some audio data. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + controller->event_handler()->OnError(controller, 0); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(NULL, url_fetcher_factory_.GetFetcherByID(0)); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_ERROR_CAPTURE, error_); +} + +TEST_F(SpeechRecognizerTest, NoSpeechCallbackIssued) { + // Start recording and give a lot of packets with audio samples set to zero. + // This should trigger the no-speech detector and issue a callback. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller = audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + + int num_packets = (SpeechRecognizer::kNoSpeechTimeoutSec * 1000) / + SpeechRecognizer::kAudioPacketIntervalMs; + // The vector is already filled with zero value samples on create. + for (int i = 0; i < num_packets; ++i) { + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + } + MessageLoop::current()->RunAllPending(); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + EXPECT_FALSE(result_received_); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_ERROR_NO_SPEECH, error_); +} + +TEST_F(SpeechRecognizerTest, NoSpeechCallbackNotIssued) { + // Start recording and give a lot of packets with audio samples set to zero + // and then some more with reasonably loud audio samples. This should be + // treated as normal speech input and the no-speech detector should not get + // triggered. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller = audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + + int num_packets = (SpeechRecognizer::kNoSpeechTimeoutSec * 1000) / + SpeechRecognizer::kAudioPacketIntervalMs; + + // The vector is already filled with zero value samples on create. + for (int i = 0; i < num_packets / 2; ++i) { + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + } + + FillPacketWithTestWaveform(); + for (int i = 0; i < num_packets / 2; ++i) { + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + } + + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + recognizer_->CancelRecognition(); +} + +TEST_F(SpeechRecognizerTest, SetInputVolumeCallback) { + // Start recording and give a lot of packets with audio samples set to zero + // and then some more with reasonably loud audio samples. Check that we don't + // get the callback during estimation phase, then get zero for the silence + // samples and proper volume for the loud audio. + EXPECT_TRUE(recognizer_->StartRecording()); + TestAudioInputController* controller = + audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + controller = audio_input_controller_factory_.controller(); + ASSERT_TRUE(controller); + + // Feed some samples to begin with for the endpointer to do noise estimation. + int num_packets = SpeechRecognizer::kEndpointerEstimationTimeMs / + SpeechRecognizer::kAudioPacketIntervalMs; + for (int i = 0; i < num_packets; ++i) { + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + } + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(-1.0f, volume_); // No audio volume set yet. + + // The vector is already filled with zero value samples on create. + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(0, volume_); + + FillPacketWithTestWaveform(); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); + MessageLoop::current()->RunAllPending(); + EXPECT_FLOAT_EQ(0.9f, volume_); + + EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); + EXPECT_FALSE(recording_complete_); + EXPECT_FALSE(recognition_complete_); + recognizer_->CancelRecognition(); +} + +} // namespace speech_input |