summaryrefslogtreecommitdiffstats
path: root/chrome
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 /chrome
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 'chrome')
-rw-r--r--chrome/app/theme/theme_resources.grd1
-rw-r--r--chrome/browser/speech/speech_input_bubble.cc48
-rw-r--r--chrome/browser/speech/speech_input_bubble.h13
-rw-r--r--chrome/browser/speech/speech_input_bubble_controller.cc20
-rw-r--r--chrome/browser/speech/speech_input_bubble_controller.h5
-rw-r--r--chrome/browser/speech/speech_input_manager.cc24
6 files changed, 73 insertions, 38 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) {