summaryrefslogtreecommitdiffstats
path: root/content/browser/speech/speech_recognizer.cc
diff options
context:
space:
mode:
authorsatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 18:38:36 +0000
committersatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-01 18:38:36 +0000
commit3b283d6e8c6285efde6a1a34273a3bdb9061bd44 (patch)
tree9c221cc4d11dacf4f20e9c05287fde698d6721c6 /content/browser/speech/speech_recognizer.cc
parent229fa74de71e0771f734cc788063515da62f30b4 (diff)
downloadchromium_src-3b283d6e8c6285efde6a1a34273a3bdb9061bd44.zip
chromium_src-3b283d6e8c6285efde6a1a34273a3bdb9061bd44.tar.gz
chromium_src-3b283d6e8c6285efde6a1a34273a3bdb9061bd44.tar.bz2
Add a noise indicator to the speech bubble volume indicator.
The noise indicator is drawn as a light blue area at the beginning and if there was clipping that is denoted with a red area at the end of the meter. The noise level comes from the endpointer -> SpeechRecognizer -> SpeechInputBubbleController -> SpeechInputBubble hence a bunch of volume setting methods are updated with the new parameter. I have also added a new utility method to SpeechInputManager to invoke the platform provided microphone settings UI, this will be used in the next CL which contains windows, mac and linux specific UI changes. BUG=69886 TEST=manual, invoke speech input and check the bubble volume indicator to see background noise and clipping. Review URL: http://codereview.chromium.org/6597071 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76395 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/speech/speech_recognizer.cc')
-rw-r--r--content/browser/speech/speech_recognizer.cc43
1 files changed, 36 insertions, 7 deletions
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();