summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/audio_handler.cc
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-07 22:02:39 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-07 22:02:39 +0000
commitd032b379df14896af9cadd17b2d4ade3e9af4714 (patch)
tree356fdb6f96e900450a5b734ccb0941d0ce2786b7 /chrome/browser/chromeos/audio_handler.cc
parent13869c3163a6ad68cfd00be2b04a5e39b38a0f1c (diff)
downloadchromium_src-d032b379df14896af9cadd17b2d4ade3e9af4714.zip
chromium_src-d032b379df14896af9cadd17b2d4ade3e9af4714.tar.gz
chromium_src-d032b379df14896af9cadd17b2d4ade3e9af4714.tar.bz2
Using PulseAudio for volume and mute key handling.
Patch by davej@chromium.org: http://codereview.chromium.org/2285004/show BUG=none TEST=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49099 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/audio_handler.cc')
-rw-r--r--chrome/browser/chromeos/audio_handler.cc167
1 files changed, 167 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/audio_handler.cc b/chrome/browser/chromeos/audio_handler.cc
new file mode 100644
index 0000000..d22b737
--- /dev/null
+++ b/chrome/browser/chromeos/audio_handler.cc
@@ -0,0 +1,167 @@
+// Copyright (c) 2010 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 "chrome/browser/chromeos/audio_handler.h"
+
+#include <math.h>
+
+#include "base/logging.h"
+#include "chrome/browser/chromeos/pulse_audio_mixer.h"
+
+namespace chromeos {
+
+namespace {
+
+const double kSilenceDb = -200.0;
+const double kMinVolumeDb = -90.0;
+const double kMaxVolumeDb = 6.0;
+// A value of less than one adjusts quieter volumes in larger steps (giving
+// finer resolution in the higher volumes).
+const double kVolumeBias = 0.7;
+
+} // namespace
+
+// This class will set volume using PulseAudio to adjust volume and mute, and
+// handles the volume level logic.
+
+// TODO(davej): Serialize volume/mute for next startup?
+// TODO(davej): Should we try to regain a connection if for some reason all was
+// initialized fine, but later IsValid() returned false? Maybe N retries?
+
+double AudioHandler::GetVolumeDb() const {
+ if (!SanityCheck())
+ return kSilenceDb;
+
+ double volume_db = mixer_->GetVolumeDb();
+ if (volume_db <= kSilenceDb)
+ return kSilenceDb;
+ return volume_db;
+}
+
+void AudioHandler::SetVolumeDb(double volume_db) {
+ if (!SanityCheck())
+ return;
+
+ mixer_->SetVolumeDb(volume_db);
+}
+
+double AudioHandler::GetVolumePercent() const {
+ if (!SanityCheck())
+ return 0;
+
+ return VolumeDbToPercent(mixer_->GetVolumeDb());
+}
+
+// Set volume using our internal 0-100% range. Notice 0% is a special case of
+// silence, so we set the mixer volume to kSilenceDb instead of kMinVolumeDb.
+void AudioHandler::SetVolumePercent(double volume_percent) {
+ if (!SanityCheck())
+ return;
+ DCHECK(volume_percent >= 0.0);
+
+ double vol_db;
+ if (volume_percent <= 0)
+ vol_db = kSilenceDb;
+ else
+ vol_db = PercentToVolumeDb(volume_percent);
+
+ mixer_->SetVolumeDb(vol_db);
+}
+
+// Volume range is from kMinVolumeDb at just above 0% to kMaxVolumeDb at 100%
+// with a special case at 0% which maps to kSilenceDb.
+void AudioHandler::AdjustVolumeByPercent(double adjust_by_percent) {
+ if (!SanityCheck())
+ return;
+
+ DLOG(INFO) << "Adjusting Volume by " << adjust_by_percent << " percent";
+
+ double vol = mixer_->GetVolumeDb();
+ double pct = VolumeDbToPercent(vol);
+ if (pct < 0)
+ pct = 0;
+ pct = pct + adjust_by_percent;
+ if (pct > 100.0)
+ pct = 100.0;
+
+ double new_volume;
+
+ if (pct <= 0.1)
+ new_volume = kSilenceDb;
+ else
+ new_volume = PercentToVolumeDb(pct);
+
+ if (new_volume != vol)
+ mixer_->SetVolumeDb(new_volume);
+}
+
+bool AudioHandler::IsMute() const {
+ if (!SanityCheck())
+ return false;
+
+ return mixer_->IsMute();
+}
+
+void AudioHandler::SetMute(bool do_mute) {
+ if (!SanityCheck())
+ return;
+
+ DLOG(INFO) << "Setting Mute to " << do_mute;
+
+ mixer_->SetMute(do_mute ? 1 : 0);
+}
+
+void AudioHandler::ToggleMute() {
+ if (!SanityCheck())
+ return;
+
+ mixer_->ToggleMute();
+}
+
+AudioHandler::AudioHandler()
+ : connected_(false) {
+ mixer_.reset(new PulseAudioMixer());
+ if (mixer_->Init()) {
+ connected_ = true;
+ } else {
+ LOG(ERROR) << "Unable to connect to PulseAudio";
+ }
+}
+
+AudioHandler::~AudioHandler() {
+};
+
+inline bool AudioHandler::SanityCheck() const {
+ if (!mixer_->IsValid()) {
+ if (connected_) {
+ LOG(ERROR) << "Lost connection to PulseAudio";
+ }
+ return false;
+ }
+ return true;
+}
+
+// VolumeDbToPercent() and PercentToVolumeDb() conversion functions allow us
+// complete control over how the 0 to 100% range is mapped to actual loudness.
+//
+// The mapping is confined to these two functions to make it easy to adjust and
+// have everything else just work. The range is biased to give finer resolution
+// in the higher volumes if kVolumeBias is less than 1.0.
+
+// static
+double AudioHandler::VolumeDbToPercent(double volume_db) {
+ if (volume_db < kMinVolumeDb)
+ return 0;
+ return 100.0 * pow((volume_db - kMinVolumeDb) /
+ (kMaxVolumeDb - kMinVolumeDb), 1/kVolumeBias);
+}
+
+// static
+double AudioHandler::PercentToVolumeDb(double volume_percent) {
+ return pow(volume_percent / 100.0, kVolumeBias) *
+ (kMaxVolumeDb - kMinVolumeDb) + kMinVolumeDb;
+}
+
+} // namespace chromeos
+