Index: media/audio/audio_input_controller.cc |
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc |
index 3bdec149bfc3c3605bdb7234edf522199fedb783..40afb90474f8cd3e6270301d5cdf045e1ea6dca7 100644 |
--- a/media/audio/audio_input_controller.cc |
+++ b/media/audio/audio_input_controller.cc |
@@ -6,10 +6,13 @@ |
#include "base/bind.h" |
#include "base/threading/thread_restrictions.h" |
+#include "base/time/time.h" |
#include "media/base/limits.h" |
#include "media/base/scoped_histogram_timer.h" |
#include "media/base/user_input_monitor.h" |
+using base::TimeDelta; |
+ |
namespace { |
const int kMaxInputChannels = 3; |
@@ -25,6 +28,13 @@ const int kTimerResetIntervalSeconds = 1; |
// Mac devices and the initial timer interval has therefore been increased |
// from 1 second to 5 seconds. |
const int kTimerInitialIntervalSeconds = 5; |
+ |
+// Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for |
+// semantics. This value was arbitrarily chosen, but seems to work well. |
+const int kPowerMeasurementTimeConstantMillis = 10; |
+ |
+// Time between two successive measurements of audio power levels. |
+const int kPowerMonitorLogIntervalMilliSeconds = 500; |
} |
namespace media { |
@@ -173,6 +183,13 @@ void AudioInputController::DoCreate(AudioManager* audio_manager, |
const std::string& device_id) { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); |
+ |
+ // Create the audio (power) level meter given the provided audio parameters. |
+ audio_level_.reset(new media::AudioPowerMonitor(params.sample_rate(), |
+ TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis))); |
+ audio_bus_ = AudioBus::Create(params); |
+ audio_params_ = params; |
+ |
// TODO(miu): See TODO at top of file. Until that's resolved, assume all |
// platform audio input requires the |no_data_timer_| be used to auto-detect |
// errors. In reality, probably only Windows needs to be treated as |
@@ -266,6 +283,9 @@ void AudioInputController::DoClose() { |
// Delete the timer on the same thread that created it. |
no_data_timer_.reset(); |
+ if (audio_level_) |
no longer working on chromium
2014/05/19 15:15:48
skip if
henrika (OOO until Aug 14)
2014/05/19 15:25:46
It can be NULL.
|
+ audio_level_->Reset(); |
+ |
DoStopCloseAndClearStream(); |
SetDataIsActive(false); |
@@ -377,6 +397,35 @@ void AudioInputController::OnData(AudioInputStream* stream, |
if (SharedMemoryAndSyncSocketMode()) { |
sync_writer_->Write(data, size, volume, key_pressed); |
sync_writer_->UpdateRecordedBytes(hardware_delay_bytes); |
+ |
+ if (!audio_level_) |
no longer working on chromium
2014/05/19 15:15:48
can audio_level be NULL?
henrika (OOO until Aug 14)
2014/05/19 15:25:46
Yes, using new ctor. I can modify and create when
|
+ return; |
+ |
+ // Perform periodic audio (power) level measurements. |
+ if ((base::TimeTicks::Now() - last_audio_level_log_time_).InMilliseconds() > |
+ kPowerMonitorLogIntervalMilliSeconds) { |
+ last_audio_level_log_time_ = base::TimeTicks::Now(); |
+ audio_bus_->FromInterleaved( |
+ data, audio_bus_->frames(), audio_params_.bits_per_sample() / 8); |
+ audio_level_->Scan(*audio_bus_, audio_bus_->frames()); |
+ std::pair<float, bool> result = audio_level_->ReadCurrentPowerAndClip(); |
+ |
+ // Get the audible level in the range [0.0,1.0], where 0.0 means |
+ // the audio signal is silent and 1.0 means it is at maximum volume. |
+ float level_dbfs = result.first; |
+ float level = 0; |
+ static const float kSilenceThresholdDBFS = -72.24719896f; |
+ if (level_dbfs < kSilenceThresholdDBFS) |
+ level = 0.0f; |
+ else if (level_dbfs > 0.0f) |
+ level = 1.0f; |
+ else |
+ level = 1.0f - level_dbfs / kSilenceThresholdDBFS; |
+ DVLOG(1) << "audio_level: " << level; |
+ |
+ audio_level_->Reset(); |
+ } |
+ |
return; |
} |