| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/sys_byteorder.h" | 10 #include "base/sys_byteorder.h" |
| 11 #include "content/browser/browser_thread_impl.h" | 11 #include "content/browser/browser_thread_impl.h" |
| 12 #include "content/browser/speech/google_streaming_remote_engine.h" | |
| 13 #include "content/browser/speech/proto/google_streaming_api.pb.h" | 12 #include "content/browser/speech/proto/google_streaming_api.pb.h" |
| 13 #include "content/browser/speech/speech_recognition_engine.h" |
| 14 #include "content/browser/speech/speech_recognizer_impl.h" | 14 #include "content/browser/speech/speech_recognizer_impl.h" |
| 15 #include "content/public/browser/speech_recognition_event_listener.h" | 15 #include "content/public/browser/speech_recognition_event_listener.h" |
| 16 #include "media/audio/audio_manager_base.h" | 16 #include "media/audio/audio_manager_base.h" |
| 17 #include "media/audio/fake_audio_input_stream.h" | 17 #include "media/audio/fake_audio_input_stream.h" |
| 18 #include "media/audio/fake_audio_output_stream.h" | 18 #include "media/audio/fake_audio_output_stream.h" |
| 19 #include "media/audio/mock_audio_manager.h" | 19 #include "media/audio/mock_audio_manager.h" |
| 20 #include "media/audio/test_audio_input_controller_factory.h" | 20 #include "media/audio/test_audio_input_controller_factory.h" |
| 21 #include "media/base/audio_bus.h" | 21 #include "media/base/audio_bus.h" |
| 22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 23 #include "net/url_request/test_url_fetcher_factory.h" | 23 #include "net/url_request/test_url_fetcher_factory.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 43 recognition_ended_(false), | 43 recognition_ended_(false), |
| 44 result_received_(false), | 44 result_received_(false), |
| 45 audio_started_(false), | 45 audio_started_(false), |
| 46 audio_ended_(false), | 46 audio_ended_(false), |
| 47 sound_started_(false), | 47 sound_started_(false), |
| 48 sound_ended_(false), | 48 sound_ended_(false), |
| 49 error_(SPEECH_RECOGNITION_ERROR_NONE), | 49 error_(SPEECH_RECOGNITION_ERROR_NONE), |
| 50 volume_(-1.0f) { | 50 volume_(-1.0f) { |
| 51 // SpeechRecognizer takes ownership of sr_engine. | 51 // SpeechRecognizer takes ownership of sr_engine. |
| 52 SpeechRecognitionEngine* sr_engine = | 52 SpeechRecognitionEngine* sr_engine = |
| 53 new GoogleStreamingRemoteEngine(NULL /* URLRequestContextGetter */); | 53 new SpeechRecognitionEngine(NULL /* URLRequestContextGetter */); |
| 54 SpeechRecognitionEngineConfig config; | 54 SpeechRecognitionEngine::Config config; |
| 55 config.audio_num_bits_per_sample = | 55 config.audio_num_bits_per_sample = |
| 56 SpeechRecognizerImpl::kNumBitsPerAudioSample; | 56 SpeechRecognizerImpl::kNumBitsPerAudioSample; |
| 57 config.audio_sample_rate = SpeechRecognizerImpl::kAudioSampleRate; | 57 config.audio_sample_rate = SpeechRecognizerImpl::kAudioSampleRate; |
| 58 config.filter_profanities = false; | 58 config.filter_profanities = false; |
| 59 sr_engine->SetConfig(config); | 59 sr_engine->SetConfig(config); |
| 60 | 60 |
| 61 const int kTestingSessionId = 1; | 61 const int kTestingSessionId = 1; |
| 62 recognizer_ = new SpeechRecognizerImpl( | 62 recognizer_ = new SpeechRecognizerImpl( |
| 63 this, kTestingSessionId, false, false, sr_engine); | 63 this, kTestingSessionId, false, false, sr_engine); |
| 64 audio_manager_.reset(new media::MockAudioManager( | 64 audio_manager_.reset(new media::MockAudioManager( |
| 65 base::MessageLoop::current()->task_runner().get())); | 65 base::MessageLoop::current()->task_runner().get())); |
| 66 recognizer_->SetAudioManagerForTesting(audio_manager_.get()); | 66 recognizer_->SetAudioManagerForTesting(audio_manager_.get()); |
| 67 | 67 |
| 68 int audio_packet_length_bytes = | 68 int audio_packet_length_bytes = |
| 69 (SpeechRecognizerImpl::kAudioSampleRate * | 69 (SpeechRecognizerImpl::kAudioSampleRate * |
| 70 GoogleStreamingRemoteEngine::kAudioPacketIntervalMs * | 70 SpeechRecognitionEngine::kAudioPacketIntervalMs * |
| 71 ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout) * | 71 ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout) * |
| 72 SpeechRecognizerImpl::kNumBitsPerAudioSample) / (8 * 1000); | 72 SpeechRecognizerImpl::kNumBitsPerAudioSample) / (8 * 1000); |
| 73 audio_packet_.resize(audio_packet_length_bytes); | 73 audio_packet_.resize(audio_packet_length_bytes); |
| 74 | 74 |
| 75 const int channels = | 75 const int channels = |
| 76 ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout); | 76 ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout); |
| 77 bytes_per_sample_ = SpeechRecognizerImpl::kNumBitsPerAudioSample / 8; | 77 bytes_per_sample_ = SpeechRecognizerImpl::kNumBitsPerAudioSample / 8; |
| 78 const int frames = audio_packet_length_bytes / channels / bytes_per_sample_; | 78 const int frames = audio_packet_length_bytes / channels / bytes_per_sample_; |
| 79 audio_bus_ = media::AudioBus::Create(channels, frames); | 79 audio_bus_ = media::AudioBus::Create(channels, frames); |
| 80 audio_bus_->Zero(); | 80 audio_bus_->Zero(); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 proto_alternative->set_confidence(0.5f); | 270 proto_alternative->set_confidence(0.5f); |
| 271 proto_alternative->set_transcript("123"); | 271 proto_alternative->set_transcript("123"); |
| 272 std::string msg_string; | 272 std::string msg_string; |
| 273 proto_event.SerializeToString(&msg_string); | 273 proto_event.SerializeToString(&msg_string); |
| 274 uint32_t prefix = | 274 uint32_t prefix = |
| 275 base::HostToNet32(base::checked_cast<uint32_t>(msg_string.size())); | 275 base::HostToNet32(base::checked_cast<uint32_t>(msg_string.size())); |
| 276 msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix)); | 276 msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix)); |
| 277 | 277 |
| 278 // Issue the network callback to complete the process. | 278 // Issue the network callback to complete the process. |
| 279 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID( | 279 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID( |
| 280 GoogleStreamingRemoteEngine::kDownstreamUrlFetcherIdForTesting); | 280 SpeechRecognitionEngine::kDownstreamUrlFetcherIdForTesting); |
| 281 ASSERT_TRUE(fetcher); | 281 ASSERT_TRUE(fetcher); |
| 282 fetcher->set_url(fetcher->GetOriginalURL()); | 282 fetcher->set_url(fetcher->GetOriginalURL()); |
| 283 fetcher->set_status(net::URLRequestStatus()); | 283 fetcher->set_status(net::URLRequestStatus()); |
| 284 fetcher->set_response_code(200); | 284 fetcher->set_response_code(200); |
| 285 fetcher->SetResponseString(msg_string); | 285 fetcher->SetResponseString(msg_string); |
| 286 fetcher->delegate()->OnURLFetchComplete(fetcher); | 286 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 287 | 287 |
| 288 base::MessageLoop::current()->RunUntilIdle(); | 288 base::MessageLoop::current()->RunUntilIdle(); |
| 289 EXPECT_TRUE(recognition_ended_); | 289 EXPECT_TRUE(recognition_ended_); |
| 290 EXPECT_TRUE(result_received_); | 290 EXPECT_TRUE(result_received_); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackIssued) { | 420 TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackIssued) { |
| 421 // Start recording and give a lot of packets with audio samples set to zero. | 421 // Start recording and give a lot of packets with audio samples set to zero. |
| 422 // This should trigger the no-speech detector and issue a callback. | 422 // This should trigger the no-speech detector and issue a callback. |
| 423 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); | 423 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); |
| 424 base::MessageLoop::current()->RunUntilIdle(); | 424 base::MessageLoop::current()->RunUntilIdle(); |
| 425 TestAudioInputController* controller = | 425 TestAudioInputController* controller = |
| 426 audio_input_controller_factory_.controller(); | 426 audio_input_controller_factory_.controller(); |
| 427 ASSERT_TRUE(controller); | 427 ASSERT_TRUE(controller); |
| 428 | 428 |
| 429 int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / | 429 int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / |
| 430 GoogleStreamingRemoteEngine::kAudioPacketIntervalMs + 1; | 430 SpeechRecognitionEngine::kAudioPacketIntervalMs + 1; |
| 431 // The vector is already filled with zero value samples on create. | 431 // The vector is already filled with zero value samples on create. |
| 432 for (int i = 0; i < num_packets; ++i) { | 432 for (int i = 0; i < num_packets; ++i) { |
| 433 controller->event_handler()->OnData(controller, audio_bus_.get()); | 433 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 434 } | 434 } |
| 435 base::MessageLoop::current()->RunUntilIdle(); | 435 base::MessageLoop::current()->RunUntilIdle(); |
| 436 EXPECT_TRUE(recognition_started_); | 436 EXPECT_TRUE(recognition_started_); |
| 437 EXPECT_TRUE(audio_started_); | 437 EXPECT_TRUE(audio_started_); |
| 438 EXPECT_FALSE(result_received_); | 438 EXPECT_FALSE(result_received_); |
| 439 EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NO_SPEECH, error_); | 439 EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NO_SPEECH, error_); |
| 440 CheckFinalEventsConsistency(); | 440 CheckFinalEventsConsistency(); |
| 441 } | 441 } |
| 442 | 442 |
| 443 TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackNotIssued) { | 443 TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackNotIssued) { |
| 444 // Start recording and give a lot of packets with audio samples set to zero | 444 // Start recording and give a lot of packets with audio samples set to zero |
| 445 // and then some more with reasonably loud audio samples. This should be | 445 // and then some more with reasonably loud audio samples. This should be |
| 446 // treated as normal speech input and the no-speech detector should not get | 446 // treated as normal speech input and the no-speech detector should not get |
| 447 // triggered. | 447 // triggered. |
| 448 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); | 448 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); |
| 449 base::MessageLoop::current()->RunUntilIdle(); | 449 base::MessageLoop::current()->RunUntilIdle(); |
| 450 TestAudioInputController* controller = | 450 TestAudioInputController* controller = |
| 451 audio_input_controller_factory_.controller(); | 451 audio_input_controller_factory_.controller(); |
| 452 ASSERT_TRUE(controller); | 452 ASSERT_TRUE(controller); |
| 453 controller = audio_input_controller_factory_.controller(); | 453 controller = audio_input_controller_factory_.controller(); |
| 454 ASSERT_TRUE(controller); | 454 ASSERT_TRUE(controller); |
| 455 | 455 |
| 456 int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / | 456 int num_packets = (SpeechRecognizerImpl::kNoSpeechTimeoutMs) / |
| 457 GoogleStreamingRemoteEngine::kAudioPacketIntervalMs; | 457 SpeechRecognitionEngine::kAudioPacketIntervalMs; |
| 458 | 458 |
| 459 // The vector is already filled with zero value samples on create. | 459 // The vector is already filled with zero value samples on create. |
| 460 for (int i = 0; i < num_packets / 2; ++i) { | 460 for (int i = 0; i < num_packets / 2; ++i) { |
| 461 controller->event_handler()->OnData(controller, audio_bus_.get()); | 461 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 462 } | 462 } |
| 463 | 463 |
| 464 FillPacketWithTestWaveform(); | 464 FillPacketWithTestWaveform(); |
| 465 for (int i = 0; i < num_packets / 2; ++i) { | 465 for (int i = 0; i < num_packets / 2; ++i) { |
| 466 controller->event_handler()->OnData(controller, audio_bus_.get()); | 466 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 467 } | 467 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 484 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); | 484 recognizer_->StartRecognition(media::AudioManagerBase::kDefaultDeviceId); |
| 485 base::MessageLoop::current()->RunUntilIdle(); | 485 base::MessageLoop::current()->RunUntilIdle(); |
| 486 TestAudioInputController* controller = | 486 TestAudioInputController* controller = |
| 487 audio_input_controller_factory_.controller(); | 487 audio_input_controller_factory_.controller(); |
| 488 ASSERT_TRUE(controller); | 488 ASSERT_TRUE(controller); |
| 489 controller = audio_input_controller_factory_.controller(); | 489 controller = audio_input_controller_factory_.controller(); |
| 490 ASSERT_TRUE(controller); | 490 ASSERT_TRUE(controller); |
| 491 | 491 |
| 492 // Feed some samples to begin with for the endpointer to do noise estimation. | 492 // Feed some samples to begin with for the endpointer to do noise estimation. |
| 493 int num_packets = SpeechRecognizerImpl::kEndpointerEstimationTimeMs / | 493 int num_packets = SpeechRecognizerImpl::kEndpointerEstimationTimeMs / |
| 494 GoogleStreamingRemoteEngine::kAudioPacketIntervalMs; | 494 SpeechRecognitionEngine::kAudioPacketIntervalMs; |
| 495 FillPacketWithNoise(); | 495 FillPacketWithNoise(); |
| 496 for (int i = 0; i < num_packets; ++i) { | 496 for (int i = 0; i < num_packets; ++i) { |
| 497 controller->event_handler()->OnData(controller, audio_bus_.get()); | 497 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 498 } | 498 } |
| 499 base::MessageLoop::current()->RunUntilIdle(); | 499 base::MessageLoop::current()->RunUntilIdle(); |
| 500 EXPECT_EQ(-1.0f, volume_); // No audio volume set yet. | 500 EXPECT_EQ(-1.0f, volume_); // No audio volume set yet. |
| 501 | 501 |
| 502 // The vector is already filled with zero value samples on create. | 502 // The vector is already filled with zero value samples on create. |
| 503 controller->event_handler()->OnData(controller, audio_bus_.get()); | 503 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 504 base::MessageLoop::current()->RunUntilIdle(); | 504 base::MessageLoop::current()->RunUntilIdle(); |
| 505 EXPECT_FLOAT_EQ(0.74939233f, volume_); | 505 EXPECT_FLOAT_EQ(0.74939233f, volume_); |
| 506 | 506 |
| 507 FillPacketWithTestWaveform(); | 507 FillPacketWithTestWaveform(); |
| 508 controller->event_handler()->OnData(controller, audio_bus_.get()); | 508 controller->event_handler()->OnData(controller, audio_bus_.get()); |
| 509 base::MessageLoop::current()->RunUntilIdle(); | 509 base::MessageLoop::current()->RunUntilIdle(); |
| 510 EXPECT_NEAR(0.89926866f, volume_, 0.00001f); | 510 EXPECT_NEAR(0.89926866f, volume_, 0.00001f); |
| 511 EXPECT_FLOAT_EQ(0.75071919f, noise_volume_); | 511 EXPECT_FLOAT_EQ(0.75071919f, noise_volume_); |
| 512 | 512 |
| 513 EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 513 EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
| 514 EXPECT_FALSE(audio_ended_); | 514 EXPECT_FALSE(audio_ended_); |
| 515 EXPECT_FALSE(recognition_ended_); | 515 EXPECT_FALSE(recognition_ended_); |
| 516 recognizer_->AbortRecognition(); | 516 recognizer_->AbortRecognition(); |
| 517 base::MessageLoop::current()->RunUntilIdle(); | 517 base::MessageLoop::current()->RunUntilIdle(); |
| 518 CheckFinalEventsConsistency(); | 518 CheckFinalEventsConsistency(); |
| 519 } | 519 } |
| 520 | 520 |
| 521 } // namespace content | 521 } // namespace content |
| OLD | NEW |