Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/audio/audio_handler.h" | 5 #include "chrome/browser/chromeos/audio/audio_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
| 12 #include "chrome/browser/chromeos/audio/audio_mixer_alsa.h" | 12 #include "chrome/browser/chromeos/audio/audio_mixer_alsa.h" |
| 13 #include "chrome/browser/chromeos/system/runtime_environment.h" | |
| 13 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 14 | 15 |
| 15 using std::max; | 16 using std::max; |
| 16 using std::min; | 17 using std::min; |
| 17 | 18 |
| 18 namespace chromeos { | 19 namespace chromeos { |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 // A value of less than one adjusts quieter volumes in larger steps (giving | 23 // A value of less than one adjusts quieter volumes in larger steps (giving |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 42 } | 43 } |
| 43 } | 44 } |
| 44 | 45 |
| 45 // static | 46 // static |
| 46 AudioHandler* AudioHandler::GetInstance() { | 47 AudioHandler* AudioHandler::GetInstance() { |
| 47 VLOG_IF(1, !g_audio_handler) | 48 VLOG_IF(1, !g_audio_handler) |
| 48 << "AudioHandler::GetInstance() called with NULL global instance."; | 49 << "AudioHandler::GetInstance() called with NULL global instance."; |
| 49 return g_audio_handler; | 50 return g_audio_handler; |
| 50 } | 51 } |
| 51 | 52 |
| 52 bool AudioHandler::IsInitialized() { | 53 // static |
| 53 return mixer_->IsInitialized(); | 54 AudioHandler* AudioHandler::GetInstanceIfInitialized() { |
| 55 return g_audio_handler && g_audio_handler->IsMixerInitialized() ? | |
| 56 g_audio_handler : NULL; | |
| 54 } | 57 } |
| 55 | 58 |
| 56 double AudioHandler::GetVolumePercent() { | 59 double AudioHandler::GetVolumePercent() { |
| 57 return VolumeDbToPercent(mixer_->GetVolumeDb()); | 60 return VolumeDbToPercent(mixer_->GetVolumeDb()); |
| 58 } | 61 } |
| 59 | 62 |
| 60 void AudioHandler::SetVolumePercent(double volume_percent) { | 63 void AudioHandler::SetVolumePercent(double volume_percent) { |
| 61 volume_percent = min(max(volume_percent, 0.0), 100.0); | 64 volume_percent = min(max(volume_percent, 0.0), 100.0); |
| 62 mixer_->SetVolumeDb(PercentToVolumeDb(volume_percent)); | 65 mixer_->SetVolumeDb(PercentToVolumeDb(volume_percent)); |
| 66 FOR_EACH_OBSERVER(VolumeObserver, volume_observers_, OnVolumeChanged()); | |
| 63 } | 67 } |
| 64 | 68 |
| 65 void AudioHandler::AdjustVolumeByPercent(double adjust_by_percent) { | 69 void AudioHandler::AdjustVolumeByPercent(double adjust_by_percent) { |
| 66 const double old_volume_db = mixer_->GetVolumeDb(); | 70 const double old_volume_db = mixer_->GetVolumeDb(); |
| 67 const double old_percent = VolumeDbToPercent(old_volume_db); | 71 const double old_percent = VolumeDbToPercent(old_volume_db); |
| 68 SetVolumePercent(old_percent + adjust_by_percent); | 72 SetVolumePercent(old_percent + adjust_by_percent); |
| 69 } | 73 } |
| 70 | 74 |
| 71 bool AudioHandler::IsMuted() { | 75 bool AudioHandler::IsMuted() { |
| 72 return mixer_->IsMuted(); | 76 return mixer_->IsMuted(); |
| 73 } | 77 } |
| 74 | 78 |
| 75 void AudioHandler::SetMuted(bool mute) { | 79 void AudioHandler::SetMuted(bool mute) { |
| 76 mixer_->SetMuted(mute); | 80 mixer_->SetMuted(mute); |
| 81 FOR_EACH_OBSERVER(VolumeObserver, volume_observers_, OnVolumeChanged()); | |
| 77 } | 82 } |
| 78 | 83 |
| 79 AudioHandler::AudioHandler() | 84 AudioHandler::AudioHandler() |
| 80 : mixer_(new AudioMixerAlsa()) { | 85 : mixer_(new AudioMixerAlsa()) { |
| 81 mixer_->Init(); | 86 mixer_->Init(); |
| 82 } | 87 } |
| 83 | 88 |
| 84 AudioHandler::~AudioHandler() { | 89 AudioHandler::~AudioHandler() { |
| 85 mixer_.reset(); | 90 mixer_.reset(); |
| 86 }; | 91 }; |
| 87 | 92 |
| 93 bool AudioHandler::IsMixerInitialized() { | |
| 94 return mixer_->IsInitialized(); | |
| 95 } | |
| 96 | |
| 88 // VolumeDbToPercent() and PercentToVolumeDb() conversion functions allow us | 97 // VolumeDbToPercent() and PercentToVolumeDb() conversion functions allow us |
| 89 // complete control over how the 0 to 100% range is mapped to actual loudness. | 98 // complete control over how the 0 to 100% range is mapped to actual loudness. |
| 90 // | 99 // |
| 91 // The mapping is confined to these two functions to make it easy to adjust and | 100 // The mapping is confined to these two functions to make it easy to adjust and |
| 92 // have everything else just work. The range is biased to give finer resolution | 101 // have everything else just work. The range is biased to give finer resolution |
| 93 // in the higher volumes if kVolumeBias is less than 1.0. | 102 // in the higher volumes if kVolumeBias is less than 1.0. |
| 94 | 103 |
| 95 double AudioHandler::VolumeDbToPercent(double volume_db) const { | 104 double AudioHandler::VolumeDbToPercent(double volume_db) const { |
| 96 double min_volume_db, max_volume_db; | 105 double min_volume_db, max_volume_db; |
| 97 mixer_->GetVolumeLimits(&min_volume_db, &max_volume_db); | 106 mixer_->GetVolumeLimits(&min_volume_db, &max_volume_db); |
| 98 | 107 |
| 99 if (volume_db < min_volume_db) | 108 if (volume_db < min_volume_db) |
| 100 return 0.0; | 109 return 0.0; |
| 101 // TODO(derat): Choose a better mapping between percent and decibels. The | 110 // TODO(derat): Choose a better mapping between percent and decibels. The |
| 102 // bottom twenty-five percent or so is useless on a CR-48's internal speakers; | 111 // bottom twenty-five percent or so is useless on a CR-48's internal speakers; |
| 103 // it's all inaudible. | 112 // it's all inaudible. |
| 104 return 100.0 * pow((volume_db - min_volume_db) / | 113 return 100.0 * pow((volume_db - min_volume_db) / |
| 105 (max_volume_db - min_volume_db), 1/kVolumeBias); | 114 (max_volume_db - min_volume_db), 1/kVolumeBias); |
| 106 } | 115 } |
| 107 | 116 |
| 108 double AudioHandler::PercentToVolumeDb(double volume_percent) const { | 117 double AudioHandler::PercentToVolumeDb(double volume_percent) const { |
| 109 double min_volume_db, max_volume_db; | 118 double min_volume_db, max_volume_db; |
| 110 mixer_->GetVolumeLimits(&min_volume_db, &max_volume_db); | 119 mixer_->GetVolumeLimits(&min_volume_db, &max_volume_db); |
| 111 | 120 |
| 112 return pow(volume_percent / 100.0, kVolumeBias) * | 121 return pow(volume_percent / 100.0, kVolumeBias) * |
| 113 (max_volume_db - min_volume_db) + min_volume_db; | 122 (max_volume_db - min_volume_db) + min_volume_db; |
| 114 } | 123 } |
| 115 | 124 |
| 125 void AudioHandler::AddVolumeObserver(VolumeObserver* observer) { | |
| 126 volume_observers_.AddObserver(observer); | |
| 127 } | |
| 128 | |
| 129 void AudioHandler::RemoveVolumeObserver(VolumeObserver* observer) { | |
| 130 volume_observers_.RemoveObserver(observer); | |
| 131 } | |
| 132 | |
| 133 AudioHandler::VolumeObserver::VolumeObserver() { | |
| 134 // AudioHandler should be initialized here if we are on the device, though | |
| 135 // the mixer may not have finished initializing yet. | |
| 136 DCHECK(AudioHandler::GetInstance() || | |
| 137 !system::runtime_environment::IsRunningOnChromeOS()); | |
| 138 if (AudioHandler::GetInstance()) | |
|
Daniel Erat
2012/01/27 18:03:57
remove the if statement; you already have a DCHECK
achuithb
2012/01/27 18:53:44
AudioHandler::GetInstance() is NULL on chrome-chro
stevenjb
2012/01/27 19:45:02
I'm not sure that this is clearer; how about at th
Daniel Erat
2012/01/27 23:06:54
yeah, i'd also prefer:
if (system::runtime_envi
achuithb
2012/01/31 00:58:43
Well, I was following the pattern in:
http://code.
| |
| 139 AudioHandler::GetInstance()->AddVolumeObserver(this); | |
| 140 } | |
| 141 | |
| 142 AudioHandler::VolumeObserver::~VolumeObserver() { | |
| 143 if (AudioHandler::GetInstance()) | |
| 144 AudioHandler::GetInstance()->RemoveVolumeObserver(this); | |
| 145 } | |
| 146 | |
| 116 } // namespace chromeos | 147 } // namespace chromeos |
| OLD | NEW |