diff options
| -rw-r--r-- | chrome/app/theme/theme_resources.grd | 1 | ||||
| -rw-r--r-- | chrome/browser/speech/speech_input_bubble.cc | 48 | ||||
| -rw-r--r-- | chrome/browser/speech/speech_input_bubble.h | 13 | ||||
| -rw-r--r-- | chrome/browser/speech/speech_input_bubble_controller.cc | 20 | ||||
| -rw-r--r-- | chrome/browser/speech/speech_input_bubble_controller.h | 5 | ||||
| -rw-r--r-- | chrome/browser/speech/speech_input_manager.cc | 24 | ||||
| -rw-r--r-- | content/browser/speech/endpointer/endpointer.h | 3 | ||||
| -rw-r--r-- | content/browser/speech/endpointer/energy_endpointer.cc | 18 | ||||
| -rw-r--r-- | content/browser/speech/endpointer/energy_endpointer.h | 3 | ||||
| -rw-r--r-- | content/browser/speech/speech_input_manager.h | 4 | ||||
| -rw-r--r-- | content/browser/speech/speech_recognizer.cc | 43 | ||||
| -rw-r--r-- | content/browser/speech/speech_recognizer.h | 5 | ||||
| -rw-r--r-- | content/browser/speech/speech_recognizer_unittest.cc | 19 |
13 files changed, 151 insertions, 55 deletions
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 59c7114..d9cae29 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -367,6 +367,7 @@ <include name="IDR_SETTINGS_FAVICON" file="settings_favicon.png" type="BINDATA" /> <include name="IDR_SIDETABS_NEW_TAB" file="sidetabs_new_tab.png" type="BINDATA" /> <include name="IDR_SPEECH_INPUT_MIC_EMPTY" file="speech_input_mic_empty.png" type="BINDATA" /> + <include name="IDR_SPEECH_INPUT_MIC_NOISE" file="speech_input_mic_noise.png" type="BINDATA" /> <include name="IDR_SPEECH_INPUT_MIC_FULL" file="speech_input_mic_full.png" type="BINDATA" /> <include name="IDR_SPEECH_INPUT_MIC_MASK" file="speech_input_mic_mask.png" type="BINDATA" /> <include name="IDR_SPEECH_INPUT_SPINNER" file="speech_input_spinner.png" type="BINDATA" /> diff --git a/chrome/browser/speech/speech_input_bubble.cc b/chrome/browser/speech/speech_input_bubble.cc index 59cfd45..111eaef 100644 --- a/chrome/browser/speech/speech_input_bubble.cc +++ b/chrome/browser/speech/speech_input_bubble.cc @@ -11,9 +11,10 @@ #include "ui/gfx/rect.h" SpeechInputBubble::FactoryMethod SpeechInputBubble::factory_ = NULL; -const int SpeechInputBubble::kBubbleTargetOffsetX = 5; +const int SpeechInputBubble::kBubbleTargetOffsetX = 10; SkBitmap* SpeechInputBubbleBase::mic_empty_ = NULL; +SkBitmap* SpeechInputBubbleBase::mic_noise_ = NULL; SkBitmap* SpeechInputBubbleBase::mic_full_ = NULL; SkBitmap* SpeechInputBubbleBase::mic_mask_ = NULL; SkBitmap* SpeechInputBubbleBase::spinner_ = NULL; @@ -39,6 +40,8 @@ SpeechInputBubbleBase::SpeechInputBubbleBase(TabContents* tab_contents) if (!mic_empty_) { // Static variables. mic_empty_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( IDR_SPEECH_INPUT_MIC_EMPTY); + mic_noise_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_SPEECH_INPUT_MIC_NOISE); mic_full_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( IDR_SPEECH_INPUT_MIC_FULL); mic_mask_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( @@ -93,14 +96,9 @@ void SpeechInputBubbleBase::SetRecordingMode() { void SpeechInputBubbleBase::SetRecognizingMode() { display_mode_ = DISPLAY_MODE_RECOGNIZING; - UpdateLayout(); - animation_step_ = 0; - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - task_factory_.NewRunnableMethod( - &SpeechInputBubbleBase::DoRecognizingAnimationStep), - kRecognizingAnimationStepMs); + DoRecognizingAnimationStep(); + UpdateLayout(); } void SpeechInputBubbleBase::DoRecognizingAnimationStep() { @@ -121,31 +119,39 @@ void SpeechInputBubbleBase::SetMessage(const string16& text) { UpdateLayout(); } -void SpeechInputBubbleBase::SetInputVolume(float volume) { - mic_image_->eraseARGB(0, 0, 0, 0); +void SpeechInputBubbleBase::DrawVolumeOverlay(SkCanvas* canvas, + const SkBitmap& bitmap, + float volume) { buffer_image_->eraseARGB(0, 0, 0, 0); int width = mic_image_->width(); int height = mic_image_->height(); - SkCanvas canvas(*mic_image_); SkCanvas buffer_canvas(*buffer_image_); - // The 'full volume' mic image is drawn clipped to the current volume level, - // and a gradient mask is applied over it with the 'multiply' compositing - // operator to show soft edges at the top. buffer_canvas.save(); - SkScalar clip_top = ((1.0f - volume) * height * 3) / 2.0f - height / 2.0f; - buffer_canvas.clipRect(SkRect::MakeLTRB(0, clip_top, - SkIntToScalar(width), SkIntToScalar(height))); - buffer_canvas.drawBitmap(*mic_full_, 0, 0); + const int kVolumeSteps = 12; + SkScalar clip_right = + (((1.0f - volume) * (width * (kVolumeSteps + 1))) - width) / kVolumeSteps; + buffer_canvas.clipRect(SkRect::MakeLTRB(0, 0, + SkIntToScalar(width) - clip_right, SkIntToScalar(height))); + buffer_canvas.drawBitmap(bitmap, 0, 0); buffer_canvas.restore(); SkPaint multiply_paint; multiply_paint.setXfermode(SkXfermode::Create(SkXfermode::kMultiply_Mode)); - buffer_canvas.drawBitmap(*mic_mask_, 0, clip_top, &multiply_paint); + buffer_canvas.drawBitmap(*mic_mask_, -clip_right, 0, &multiply_paint); + + canvas->drawBitmap(*buffer_image_.get(), 0, 0); +} + +void SpeechInputBubbleBase::SetInputVolume(float volume, float noise_volume) { + mic_image_->eraseARGB(0, 0, 0, 0); + SkCanvas canvas(*mic_image_); - // Draw the empty volume image first and the current volume image on top. + // Draw the empty volume image first and the current volume image on top, + // and then the noise volume image on top of both. canvas.drawBitmap(*mic_empty_, 0, 0); - canvas.drawBitmap(*buffer_image_.get(), 0, 0); + DrawVolumeOverlay(&canvas, *mic_full_, volume); + DrawVolumeOverlay(&canvas, *mic_noise_, noise_volume); SetImage(*mic_image_.get()); } diff --git a/chrome/browser/speech/speech_input_bubble.h b/chrome/browser/speech/speech_input_bubble.h index dd5d21b..65e0cf4 100644 --- a/chrome/browser/speech/speech_input_bubble.h +++ b/chrome/browser/speech/speech_input_bubble.h @@ -13,9 +13,11 @@ #include "base/task.h" namespace gfx { +class Canvas; class Rect; } class SkBitmap; +class SkCanvas; class TabContents; // SpeechInputBubble displays a popup info bubble during speech recognition, @@ -96,8 +98,8 @@ class SpeechInputBubble { // |Delegate::InfoBubbleFocusChanged| as well. virtual void Hide() = 0; - // Updates the current captured audio volume displayed on screen. - virtual void SetInputVolume(float volume) = 0; + // Updates and draws the current captured audio volume displayed on screen. + virtual void SetInputVolume(float volume, float noise_volume) = 0; // Returns the TabContents for which this bubble gets displayed. virtual TabContents* tab_contents() = 0; @@ -129,7 +131,7 @@ class SpeechInputBubbleBase : public SpeechInputBubble { virtual void SetRecordingMode(); virtual void SetRecognizingMode(); virtual void SetMessage(const string16& text); - virtual void SetInputVolume(float volume); + virtual void SetInputVolume(float volume, float noise_volume); virtual TabContents* tab_contents(); protected: @@ -152,6 +154,10 @@ class SpeechInputBubbleBase : public SpeechInputBubble { private: void DoRecognizingAnimationStep(); + void DrawVolumeOverlay(SkCanvas* canvas, + const SkBitmap& bitmap, + float volume); + // Task factory used for animation timer. ScopedRunnableMethodFactory<SpeechInputBubbleBase> task_factory_; int animation_step_; // Current index/step of the animation. @@ -167,6 +173,7 @@ class SpeechInputBubbleBase : public SpeechInputBubble { TabContents* tab_contents_; static SkBitmap* mic_full_; // Mic image with full volume. + static SkBitmap* mic_noise_; // Mic image with full noise volume. static SkBitmap* mic_empty_; // Mic image with zero volume. static SkBitmap* mic_mask_; // Gradient mask used by the volume indicator. static SkBitmap* spinner_; // Spinner image for the progress animation. diff --git a/chrome/browser/speech/speech_input_bubble_controller.cc b/chrome/browser/speech/speech_input_bubble_controller.cc index 77a32a4..58bda78 100644 --- a/chrome/browser/speech/speech_input_bubble_controller.cc +++ b/chrome/browser/speech/speech_input_bubble_controller.cc @@ -52,28 +52,29 @@ void SpeechInputBubbleController::CreateBubble(int caller_id, } void SpeechInputBubbleController::CloseBubble(int caller_id) { - ProcessRequestInUiThread(caller_id, REQUEST_CLOSE, string16(), 0); + ProcessRequestInUiThread(caller_id, REQUEST_CLOSE, string16(), 0, 0); } void SpeechInputBubbleController::SetBubbleRecordingMode(int caller_id) { ProcessRequestInUiThread(caller_id, REQUEST_SET_RECORDING_MODE, - string16(), 0); + string16(), 0, 0); } void SpeechInputBubbleController::SetBubbleRecognizingMode(int caller_id) { ProcessRequestInUiThread(caller_id, REQUEST_SET_RECOGNIZING_MODE, - string16(), 0); + string16(), 0, 0); } void SpeechInputBubbleController::SetBubbleInputVolume(int caller_id, - float volume) { + float volume, + float noise_volume) { ProcessRequestInUiThread(caller_id, REQUEST_SET_INPUT_VOLUME, string16(), - volume); + volume, noise_volume); } void SpeechInputBubbleController::SetBubbleMessage(int caller_id, const string16& text) { - ProcessRequestInUiThread(caller_id, REQUEST_SET_MESSAGE, text, 0); + ProcessRequestInUiThread(caller_id, REQUEST_SET_MESSAGE, text, 0, 0); } void SpeechInputBubbleController::UpdateTabContentsSubscription( @@ -131,11 +132,12 @@ void SpeechInputBubbleController::Observe(NotificationType type, } void SpeechInputBubbleController::ProcessRequestInUiThread( - int caller_id, RequestType type, const string16& text, float volume) { + int caller_id, RequestType type, const string16& text, float volume, + float noise_volume) { if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( this, &SpeechInputBubbleController::ProcessRequestInUiThread, - caller_id, type, text, volume)); + caller_id, type, text, volume, noise_volume)); return; } DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -164,7 +166,7 @@ void SpeechInputBubbleController::ProcessRequestInUiThread( bubble->SetMessage(text); break; case REQUEST_SET_INPUT_VOLUME: - bubble->SetInputVolume(volume); + bubble->SetInputVolume(volume, noise_volume); break; case REQUEST_CLOSE: if (current_bubble_caller_id_ == caller_id) diff --git a/chrome/browser/speech/speech_input_bubble_controller.h b/chrome/browser/speech/speech_input_bubble_controller.h index 04c92b5..cdfe5c3 100644 --- a/chrome/browser/speech/speech_input_bubble_controller.h +++ b/chrome/browser/speech/speech_input_bubble_controller.h @@ -68,7 +68,7 @@ class SpeechInputBubbleController void SetBubbleMessage(int caller_id, const string16& text); // Updates the current captured audio volume displayed on screen. - void SetBubbleInputVolume(int caller_id, float volume); + void SetBubbleInputVolume(int caller_id, float volume, float noise_volume); void CloseBubble(int caller_id); @@ -102,7 +102,8 @@ class SpeechInputBubbleController void ProcessRequestInUiThread(int caller_id, RequestType type, const string16& text, - float volume); + float volume, + float noise_volume); // Called whenever a bubble was added to or removed from the list. If the // bubble was being added, this method registers for close notifications with diff --git a/chrome/browser/speech/speech_input_manager.cc b/chrome/browser/speech/speech_input_manager.cc index 626bf4f..141ed21 100644 --- a/chrome/browser/speech/speech_input_manager.cc +++ b/chrome/browser/speech/speech_input_manager.cc @@ -14,6 +14,7 @@ #include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_thread.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/speech/speech_input_bubble_controller.h" @@ -120,7 +121,7 @@ class SpeechInputManagerImpl : public SpeechInputManager, virtual void OnRecognizerError(int caller_id, SpeechRecognizer::ErrorCode error); virtual void DidCompleteEnvironmentEstimation(int caller_id); - virtual void SetInputVolume(int caller_id, float volume); + virtual void SetInputVolume(int caller_id, float volume, float noise_volume); // SpeechInputBubbleController::Delegate methods. virtual void InfoBubbleButtonClicked(int caller_id, @@ -183,6 +184,22 @@ bool SpeechInputManager::IsFeatureEnabled() { return enabled; } +void SpeechInputManager::ShowAudioInputSettings() { + // Since AudioManager::ShowAudioInputSettings can potentially launch external + // processes, do that in the PROCESS_LAUNCHER thread to not block the calling + // threads. + if (!BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) { + BrowserThread::PostTask( + BrowserThread::PROCESS_LAUNCHER, FROM_HERE, + NewRunnableFunction(&SpeechInputManager::ShowAudioInputSettings)); + return; + } + + DCHECK(AudioManager::GetAudioManager()->CanShowAudioInputSettings()); + if (AudioManager::GetAudioManager()->CanShowAudioInputSettings()) + AudioManager::GetAudioManager()->ShowAudioInputSettings(); +} + SpeechInputManagerImpl::SpeechInputManagerImpl() : recording_caller_id_(0), bubble_controller_(new SpeechInputBubbleController( @@ -340,11 +357,12 @@ void SpeechInputManagerImpl::DidCompleteEnvironmentEstimation(int caller_id) { bubble_controller_->SetBubbleRecordingMode(caller_id); } -void SpeechInputManagerImpl::SetInputVolume(int caller_id, float volume) { +void SpeechInputManagerImpl::SetInputVolume(int caller_id, float volume, + float noise_volume) { DCHECK(HasPendingRequest(caller_id)); DCHECK_EQ(recording_caller_id_, caller_id); - bubble_controller_->SetBubbleInputVolume(caller_id, volume); + bubble_controller_->SetBubbleInputVolume(caller_id, volume, noise_volume); } void SpeechInputManagerImpl::CancelRecognitionAndInformDelegate(int caller_id) { diff --git a/content/browser/speech/endpointer/endpointer.h b/content/browser/speech/endpointer/endpointer.h index be4bd65..c8cf80a 100644 --- a/content/browser/speech/endpointer/endpointer.h +++ b/content/browser/speech/endpointer/endpointer.h @@ -96,6 +96,9 @@ class Endpointer { return speech_input_complete_; } + // RMS background noise level in dB. + float NoiseLevelDb() const { return energy_endpointer_.GetNoiseLevelDb(); } + private: // Reset internal states. Helper method common to initial input utterance // and following input utternaces. diff --git a/content/browser/speech/endpointer/energy_endpointer.cc b/content/browser/speech/endpointer/energy_endpointer.cc index c806aed..edf3edd 100644 --- a/content/browser/speech/endpointer/energy_endpointer.cc +++ b/content/browser/speech/endpointer/energy_endpointer.cc @@ -33,6 +33,13 @@ int64 Secs2Usecs(float seconds) { return static_cast<int64>(0.5 + (1.0e6 * seconds)); } +float GetDecibel(float value) { + const float kVerySmallValue = 1.0e-100f; + if (value < kVerySmallValue) + value = kVerySmallValue; + return 20 * log10(value); +} + } // namespace namespace speech_input { @@ -326,11 +333,12 @@ void EnergyEndpointer::ProcessAudioFrame(int64 time_us, UpdateLevels(rms); ++frame_counter_; - if (rms_out) { - *rms_out = -120.0; - if ((noise_level_ > 0.0) && ((rms / noise_level_ ) > 0.000001)) - *rms_out = static_cast<float>(20.0 * log10(rms / noise_level_)); - } + if (rms_out) + *rms_out = GetDecibel(rms); +} + +float EnergyEndpointer::GetNoiseLevelDb() const { + return GetDecibel(noise_level_); } void EnergyEndpointer::UpdateLevels(float rms) { diff --git a/content/browser/speech/endpointer/energy_endpointer.h b/content/browser/speech/endpointer/energy_endpointer.h index b10d8b7..77ccc55 100644 --- a/content/browser/speech/endpointer/energy_endpointer.h +++ b/content/browser/speech/endpointer/energy_endpointer.h @@ -91,6 +91,9 @@ class EnergyEndpointer { return estimating_environment_; } + // Returns estimated noise level in dB. + float GetNoiseLevelDb() const; + private: class HistoryRing; diff --git a/content/browser/speech/speech_input_manager.h b/content/browser/speech/speech_input_manager.h index a6ba61f..9415910 100644 --- a/content/browser/speech/speech_input_manager.h +++ b/content/browser/speech/speech_input_manager.h @@ -35,6 +35,10 @@ class SpeechInputManager { // information and command line flags. static bool IsFeatureEnabled(); + // Invokes the platform provided microphone settings UI in a non-blocking way, + // via the BrowserThread::PROCESS_LAUNCHER thread. + static void ShowAudioInputSettings(); + // Factory method to access the singleton. We have this method here instead of // using Singleton directly in the calling code to aid tests in injection // mocks. diff --git a/content/browser/speech/speech_recognizer.cc b/content/browser/speech/speech_recognizer.cc index fdc1a4c..b23f4b0 100644 --- a/content/browser/speech/speech_recognizer.cc +++ b/content/browser/speech/speech_recognizer.cc @@ -17,11 +17,32 @@ namespace { // The following constants are related to the volume level indicator shown in // the UI for recorded audio. // Multiplier used when new volume is greater than previous level. -const float kUpSmoothingFactor = 0.9f; +const float kUpSmoothingFactor = 1.0f; // Multiplier used when new volume is lesser than previous level. -const float kDownSmoothingFactor = 0.4f; -const float kAudioMeterMinDb = 10.0f; // Lower bar for volume meter. -const float kAudioMeterDbRange = 25.0f; +const float kDownSmoothingFactor = 0.7f; +// RMS dB value of a maximum (unclipped) sine wave for int16 samples. +const float kAudioMeterMaxDb = 90.31f; +// This value corresponds to RMS dB for int16 with 6 most-significant-bits = 0. +// Values lower than this will display as empty level-meter. +const float kAudioMeterMinDb = 60.21f; +const float kAudioMeterDbRange = kAudioMeterMaxDb - kAudioMeterMinDb; + +// Maximum level to draw to display unclipped meter. (1.0f displays clipping.) +const float kAudioMeterRangeMaxUnclipped = 47.0f / 48.0f; + +// Returns true if more than 5% of the samples are at min or max value. +bool Clipping(const int16* samples, int num_samples) { + int clipping_samples = 0; + const int kThreshold = num_samples / 20; + for (int i = 0; i < num_samples; ++i) { + if (samples[i] <= -32767 || samples[i] >= 32767) { + if (++clipping_samples > kThreshold) + return true; + } + } + return false; +} + } // namespace namespace speech_input { @@ -220,14 +241,22 @@ void SpeechRecognizer::HandleOnData(string* data) { // Calculate the input volume to display in the UI, smoothing towards the // new level. - float level = (rms - kAudioMeterMinDb) / kAudioMeterDbRange; - level = std::min(std::max(0.0f, level), 1.0f); + float level = (rms - kAudioMeterMinDb) / + (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); + level = std::min(std::max(0.0f, level), kAudioMeterRangeMaxUnclipped); if (level > audio_level_) { audio_level_ += (level - audio_level_) * kUpSmoothingFactor; } else { audio_level_ += (level - audio_level_) * kDownSmoothingFactor; } - delegate_->SetInputVolume(caller_id_, audio_level_); + + float noise_level = (endpointer_.NoiseLevelDb() - kAudioMeterMinDb) / + (kAudioMeterDbRange / kAudioMeterRangeMaxUnclipped); + noise_level = std::min(std::max(0.0f, noise_level), + kAudioMeterRangeMaxUnclipped); + + delegate_->SetInputVolume(caller_id_, + Clipping(samples, num_samples) ? 1.0f : audio_level_, noise_level); if (endpointer_.speech_input_complete()) { StopRecording(); diff --git a/content/browser/speech/speech_recognizer.h b/content/browser/speech/speech_recognizer.h index a54a59d..f8df0c2 100644 --- a/content/browser/speech/speech_recognizer.h +++ b/content/browser/speech/speech_recognizer.h @@ -65,8 +65,9 @@ class SpeechRecognizer // Informs of a change in the captured audio level, useful if displaying // a microphone volume indicator while recording. - // The value of |volume| is in the [0.0, 1.0] range. - virtual void SetInputVolume(int caller_id, float volume) = 0; + // The value of |volume| and |noise_volume| is in the [0.0, 1.0] range. + virtual void SetInputVolume(int caller_id, float volume, + float noise_volume) = 0; protected: virtual ~Delegate() {} diff --git a/content/browser/speech/speech_recognizer_unittest.cc b/content/browser/speech/speech_recognizer_unittest.cc index 8365396..4b16259 100644 --- a/content/browser/speech/speech_recognizer_unittest.cc +++ b/content/browser/speech/speech_recognizer_unittest.cc @@ -62,8 +62,9 @@ class SpeechRecognizerTest : public SpeechRecognizerDelegate, error_ = error; } - virtual void SetInputVolume(int caller_id, float volume) { + virtual void SetInputVolume(int caller_id, float volume, float noise_volume) { volume_ = volume; + noise_volume_ = noise_volume; } // testing::Test methods. @@ -83,6 +84,15 @@ class SpeechRecognizerTest : public SpeechRecognizerDelegate, audio_packet_[i] = static_cast<uint8>(i); } + void FillPacketWithNoise() { + int value = 0; + int factor = 175; + for (size_t i = 0; i < audio_packet_.size(); ++i) { + value += factor; + audio_packet_[i] = value % 100; + } + } + protected: MessageLoopForIO message_loop_; BrowserThread io_thread_; @@ -95,6 +105,7 @@ class SpeechRecognizerTest : public SpeechRecognizerDelegate, TestAudioInputControllerFactory audio_input_controller_factory_; std::vector<uint8> audio_packet_; float volume_; + float noise_volume_; }; TEST_F(SpeechRecognizerTest, StopNoData) { @@ -272,6 +283,7 @@ TEST_F(SpeechRecognizerTest, SetInputVolumeCallback) { // Feed some samples to begin with for the endpointer to do noise estimation. int num_packets = SpeechRecognizer::kEndpointerEstimationTimeMs / SpeechRecognizer::kAudioPacketIntervalMs; + FillPacketWithNoise(); for (int i = 0; i < num_packets; ++i) { controller->event_handler()->OnData(controller, &audio_packet_[0], audio_packet_.size()); @@ -283,13 +295,14 @@ TEST_F(SpeechRecognizerTest, SetInputVolumeCallback) { controller->event_handler()->OnData(controller, &audio_packet_[0], audio_packet_.size()); MessageLoop::current()->RunAllPending(); - EXPECT_EQ(0, volume_); + EXPECT_FLOAT_EQ(0.51877826f, volume_); FillPacketWithTestWaveform(); controller->event_handler()->OnData(controller, &audio_packet_[0], audio_packet_.size()); MessageLoop::current()->RunAllPending(); - EXPECT_FLOAT_EQ(0.9f, volume_); + EXPECT_FLOAT_EQ(0.81907868f, volume_); + EXPECT_FLOAT_EQ(0.52143687f, noise_volume_); EXPECT_EQ(SpeechRecognizer::RECOGNIZER_NO_ERROR, error_); EXPECT_FALSE(recording_complete_); |
