diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 22:02:39 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-07 22:02:39 +0000 |
commit | d032b379df14896af9cadd17b2d4ade3e9af4714 (patch) | |
tree | 356fdb6f96e900450a5b734ccb0941d0ce2786b7 /chrome/browser/chromeos/audio_handler.cc | |
parent | 13869c3163a6ad68cfd00be2b04a5e39b38a0f1c (diff) | |
download | chromium_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.cc | 167 |
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 + |