OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/audio/audio_input_controller.h" | 5 #include "media/audio/audio_input_controller.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 // breakage (very hard to repro bugs!) on other platforms: See | 25 // breakage (very hard to repro bugs!) on other platforms: See |
26 // http://crbug.com/226327 and http://crbug.com/230972. | 26 // http://crbug.com/226327 and http://crbug.com/230972. |
27 // See also that the timer has been disabled on Mac now due to | 27 // See also that the timer has been disabled on Mac now due to |
28 // crbug.com/357501. | 28 // crbug.com/357501. |
29 const int kTimerResetIntervalSeconds = 1; | 29 const int kTimerResetIntervalSeconds = 1; |
30 // We have received reports that the timer can be too trigger happy on some | 30 // We have received reports that the timer can be too trigger happy on some |
31 // Mac devices and the initial timer interval has therefore been increased | 31 // Mac devices and the initial timer interval has therefore been increased |
32 // from 1 second to 5 seconds. | 32 // from 1 second to 5 seconds. |
33 const int kTimerInitialIntervalSeconds = 5; | 33 const int kTimerInitialIntervalSeconds = 5; |
34 | 34 |
35 // A warning will be logged when the microphone audio volume is below this | |
36 // threshold. | |
37 const int kLowLevelMicrophoneLevelInPercent = 10; | |
Henrik Grunell
2014/09/09 08:11:31
Nit: Remove "In".
henrika (OOO until Aug 14)
2014/09/09 08:52:30
Done.
| |
38 | |
35 #if defined(AUDIO_POWER_MONITORING) | 39 #if defined(AUDIO_POWER_MONITORING) |
36 // Time constant for AudioPowerMonitor. | 40 // Time constant for AudioPowerMonitor. |
37 // The utilized smoothing factor (alpha) in the exponential filter is given | 41 // The utilized smoothing factor (alpha) in the exponential filter is given |
38 // by 1-exp(-1/(fs*ts)), where fs is the sample rate in Hz and ts is the time | 42 // by 1-exp(-1/(fs*ts)), where fs is the sample rate in Hz and ts is the time |
39 // constant given by |kPowerMeasurementTimeConstantMilliseconds|. | 43 // constant given by |kPowerMeasurementTimeConstantMilliseconds|. |
40 // Example: fs=44100, ts=10e-3 => alpha~0.022420 | 44 // Example: fs=44100, ts=10e-3 => alpha~0.022420 |
41 // fs=44100, ts=20e-3 => alpha~0.165903 | 45 // fs=44100, ts=20e-3 => alpha~0.165903 |
42 // A large smoothing factor corresponds to a faster filter response to input | 46 // A large smoothing factor corresponds to a faster filter response to input |
43 // changes since y(n)=alpha*x(n)+(1-alpha)*y(n-1), where x(n) is the input | 47 // changes since y(n)=alpha*x(n)+(1-alpha)*y(n-1), where x(n) is the input |
44 // and y(n) is the output. | 48 // and y(n) is the output. |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 kPowerMonitorLogIntervalSeconds) { | 507 kPowerMonitorLogIntervalSeconds) { |
504 // Wrap data into an AudioBus to match AudioPowerMonitor::Scan. | 508 // Wrap data into an AudioBus to match AudioPowerMonitor::Scan. |
505 // TODO(henrika): remove this section when capture side uses AudioBus. | 509 // TODO(henrika): remove this section when capture side uses AudioBus. |
506 // See http://crbug.com/375155 for details. | 510 // See http://crbug.com/375155 for details. |
507 audio_level_->Scan(*source, source->frames()); | 511 audio_level_->Scan(*source, source->frames()); |
508 | 512 |
509 // Get current average power level and add it to the log. | 513 // Get current average power level and add it to the log. |
510 // Possible range is given by [-inf, 0] dBFS. | 514 // Possible range is given by [-inf, 0] dBFS. |
511 std::pair<float, bool> result = audio_level_->ReadCurrentPowerAndClip(); | 515 std::pair<float, bool> result = audio_level_->ReadCurrentPowerAndClip(); |
512 | 516 |
517 // Add current microphone volume to log and UMA histogram. | |
518 const int mic_volume_percent = static_cast<int>(100.0 * volume); | |
519 | |
513 // Use event handler on the audio thread to relay a message to the ARIH | 520 // Use event handler on the audio thread to relay a message to the ARIH |
514 // in content which does the actual logging on the IO thread. | 521 // in content which does the actual logging on the IO thread. |
515 task_runner_->PostTask( | 522 task_runner_->PostTask(FROM_HERE, |
516 FROM_HERE, | 523 base::Bind(&AudioInputController::DoLogAudioLevels, |
517 base::Bind( | 524 this, |
518 &AudioInputController::DoLogAudioLevel, this, result.first)); | 525 result.first, |
526 mic_volume_percent)); | |
519 | 527 |
520 last_audio_level_log_time_ = base::TimeTicks::Now(); | 528 last_audio_level_log_time_ = base::TimeTicks::Now(); |
521 | 529 |
522 // Reset the average power level (since we don't log continuously). | 530 // Reset the average power level (since we don't log continuously). |
523 audio_level_->Reset(); | 531 audio_level_->Reset(); |
524 } | 532 } |
525 #endif | 533 #endif |
526 return; | 534 return; |
527 } | 535 } |
528 | 536 |
(...skipping 11 matching lines...) Expand all Loading... | |
540 base::Bind( | 548 base::Bind( |
541 &AudioInputController::DoOnData, this, base::Passed(&audio_data))); | 549 &AudioInputController::DoOnData, this, base::Passed(&audio_data))); |
542 } | 550 } |
543 | 551 |
544 void AudioInputController::DoOnData(scoped_ptr<AudioBus> data) { | 552 void AudioInputController::DoOnData(scoped_ptr<AudioBus> data) { |
545 DCHECK(task_runner_->BelongsToCurrentThread()); | 553 DCHECK(task_runner_->BelongsToCurrentThread()); |
546 if (handler_) | 554 if (handler_) |
547 handler_->OnData(this, data.get()); | 555 handler_->OnData(this, data.get()); |
548 } | 556 } |
549 | 557 |
550 void AudioInputController::DoLogAudioLevel(float level_dbfs) { | 558 void AudioInputController::DoLogAudioLevels(float level_dbfs, |
559 int microphone_volume_percent) { | |
551 #if defined(AUDIO_POWER_MONITORING) | 560 #if defined(AUDIO_POWER_MONITORING) |
552 DCHECK(task_runner_->BelongsToCurrentThread()); | 561 DCHECK(task_runner_->BelongsToCurrentThread()); |
553 if (!handler_) | 562 if (!handler_) |
554 return; | 563 return; |
555 | 564 |
556 std::string log_string = base::StringPrintf( | 565 std::string log_string = base::StringPrintf( |
557 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); | 566 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); |
558 static const float kSilenceThresholdDBFS = -72.24719896f; | 567 static const float kSilenceThresholdDBFS = -72.24719896f; |
559 if (level_dbfs < kSilenceThresholdDBFS) | 568 if (level_dbfs < kSilenceThresholdDBFS) |
560 log_string += " <=> no audio input!"; | 569 log_string += " <=> no audio input!"; |
561 handler_->OnLog(this, log_string); | 570 handler_->OnLog(this, log_string); |
562 | 571 |
563 UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS); | 572 UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS); |
573 | |
574 UMA_HISTOGRAM_PERCENTAGE("Media.MicrophoneVolume", microphone_volume_percent); | |
575 log_string = base::StringPrintf( | |
576 "AIC::OnData: microphone volume=%d percent", microphone_volume_percent); | |
Henrik Grunell
2014/09/09 08:11:31
Nit: Replace "percent" with "%" in the string. Mai
henrika (OOO until Aug 14)
2014/09/09 08:52:30
Done.
| |
577 if (microphone_volume_percent < kLowLevelMicrophoneLevelInPercent) | |
578 log_string += " <=> low microphone level!"; | |
tommi (sloooow) - chröme
2014/09/08 18:38:40
nit: ":" instead of <=>
Can we log the actual valu
Henrik Grunell
2014/09/09 08:11:31
But the actual value is just 1/100 of the % value.
henrika (OOO until Aug 14)
2014/09/09 08:52:30
Done.
henrika (OOO until Aug 14)
2014/09/09 08:52:30
It is logged. Note that I add an extra warning to
| |
579 handler_->OnLog(this, log_string); | |
564 #endif | 580 #endif |
565 } | 581 } |
566 | 582 |
567 void AudioInputController::OnError(AudioInputStream* stream) { | 583 void AudioInputController::OnError(AudioInputStream* stream) { |
568 // Handle error on the audio-manager thread. | 584 // Handle error on the audio-manager thread. |
569 task_runner_->PostTask(FROM_HERE, base::Bind( | 585 task_runner_->PostTask(FROM_HERE, base::Bind( |
570 &AudioInputController::DoReportError, this)); | 586 &AudioInputController::DoReportError, this)); |
571 } | 587 } |
572 | 588 |
573 void AudioInputController::DoStopCloseAndClearStream() { | 589 void AudioInputController::DoStopCloseAndClearStream() { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 } | 632 } |
617 | 633 |
618 void AudioInputController::LogSilenceState(SilenceState value) { | 634 void AudioInputController::LogSilenceState(SilenceState value) { |
619 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", | 635 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", |
620 value, | 636 value, |
621 SILENCE_STATE_MAX + 1); | 637 SILENCE_STATE_MAX + 1); |
622 } | 638 } |
623 #endif | 639 #endif |
624 | 640 |
625 } // namespace media | 641 } // namespace media |
OLD | NEW |