Index: media/audio/win/audio_low_latency_input_win.cc |
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc |
index 839ace84c46fa4825166fa0970921285548ba813..18cf6605efa34277d0302ff3e6e64be1846ad1d0 100644 |
--- a/media/audio/win/audio_low_latency_input_win.cc |
+++ b/media/audio/win/audio_low_latency_input_win.cc |
@@ -11,6 +11,8 @@ |
#include "media/audio/win/audio_manager_win.h" |
#include "media/audio/win/avrt_wrapper_win.h" |
+static const int kMinIntervalBetweenVolumeUpdatesMs = 1000; |
+ |
using base::win::ScopedComPtr; |
using base::win::ScopedCOMInitializer; |
@@ -24,7 +26,9 @@ WASAPIAudioInputStream::WASAPIAudioInputStream( |
started_(false), |
endpoint_buffer_size_frames_(0), |
device_id_(device_id), |
- sink_(NULL) { |
+ sink_(NULL), |
+ volume_(0.0), |
+ agc_is_enabled_(0) { |
DCHECK(manager_); |
// Load the Avrt DLL if not already loaded. Required to support MMCSS. |
@@ -192,6 +196,7 @@ double WASAPIAudioInputStream::GetMaxVolume() { |
} |
void WASAPIAudioInputStream::SetVolume(double volume) { |
+ DVLOG(1) << "SetVolume(volume=" << volume << ")"; |
DCHECK(CalledOnValidThread()); |
DCHECK(volume <= 1.0 && volume >= 0.0); |
@@ -202,8 +207,18 @@ void WASAPIAudioInputStream::SetVolume(double volume) { |
// Set a new master volume level. Valid volume levels are in the range |
// 0.0 to 1.0. Ignore volume-change events. |
HRESULT hr = simple_audio_volume_->SetMasterVolume(static_cast<float>(volume), |
- NULL); |
+ NULL); |
tommi (sloooow) - chröme
2012/03/16 13:31:05
indent
henrika (OOO until Aug 14)
2012/03/21 10:16:04
Done.
|
DLOG_IF(WARNING, FAILED(hr)) << "Failed to set new input master volume."; |
+ |
+ // We take new volume samples once every second when the AGC is enabled. |
+ // To ensure that a new setting has an immediate effect, the new volume |
+ // setting is cached here. It will ensure that the next OnData() callback |
+ // will contain a new valid volume level. If this approach was not taken, |
+ // we could report invalid volume levels to the client for a time period |
+ // of up to one second. |
+ if (GetAutomaticGainControl()) { |
+ volume_ = GetVolume(); |
+ } |
} |
double WASAPIAudioInputStream::GetVolume() { |
@@ -220,6 +235,14 @@ double WASAPIAudioInputStream::GetVolume() { |
return static_cast<double>(level); |
} |
+void WASAPIAudioInputStream::SetAutomaticGainControl(bool enabled) { |
tommi (sloooow) - chröme
2012/03/16 13:31:05
seems like we have a lot of similar or exactly the
henrika (OOO until Aug 14)
2012/03/21 10:16:04
I feel the same way. Let me try to come up with so
|
+ base::subtle::Release_Store(&agc_is_enabled_, enabled); |
+} |
+ |
+bool WASAPIAudioInputStream::GetAutomaticGainControl() { |
+ return (base::subtle::Acquire_Load(&agc_is_enabled_) == 1); |
+} |
+ |
// static |
double WASAPIAudioInputStream::HardwareSampleRate( |
const std::string& device_id) { |
@@ -389,6 +412,21 @@ void WASAPIAudioInputStream::Run() { |
first_audio_frame_timestamp) / 10000.0) * ms_to_frame_count_ + |
buffer_frame_index - num_frames_to_read; |
+ // Query a new volume level if AGC is enabled and if it is time to |
+ // update the old value. |
+ if (GetAutomaticGainControl()) { |
tommi (sloooow) - chröme
2012/03/16 13:31:05
this code looks the same too
|
+ base::Time now = base::Time::Now(); |
+ if ((now - last_volume_update_time_).InMilliseconds() > |
+ kMinIntervalBetweenVolumeUpdatesMs) { |
+ // Retrieve the current volume level. Range is [0.0,1.0]. |
+ float level = 0.0f; |
+ HRESULT hr = simple_audio_volume_->GetMasterVolume(&level); |
+ if (SUCCEEDED(hr)) |
+ volume_ = static_cast<double>(level); |
+ last_volume_update_time_ = now; |
+ } |
+ } |
+ |
// Deliver captured data to the registered consumer using a packet |
// size which was specified at construction. |
uint32 delay_frames = static_cast<uint32>(audio_delay_frames + 0.5); |
@@ -396,11 +434,13 @@ void WASAPIAudioInputStream::Run() { |
uint8* audio_data = |
reinterpret_cast<uint8*>(capture_buffer.get()); |
- // Deliver data packet and delay estimation to the user. |
+ // Deliver data packet, delay estimation and volume level to |
+ // the user. |
sink_->OnData(this, |
audio_data, |
packet_size_bytes_, |
- delay_frames * frame_size_); |
+ delay_frames * frame_size_, |
+ volume_); |
// Store parts of the recorded data which can't be delivered |
// using the current packet size. The stored section will be used |