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/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "media/audio/audio_parameters.h" | |
11 #include "media/base/limits.h" | 12 #include "media/base/limits.h" |
12 #include "media/base/scoped_histogram_timer.h" | 13 #include "media/base/scoped_histogram_timer.h" |
13 #include "media/base/user_input_monitor.h" | 14 #include "media/base/user_input_monitor.h" |
14 | 15 |
15 using base::TimeDelta; | 16 using base::TimeDelta; |
16 | 17 |
17 namespace { | 18 namespace { |
18 const int kMaxInputChannels = 3; | 19 const int kMaxInputChannels = 3; |
19 | 20 |
20 // TODO(henrika): remove usage of timers and add support for proper | 21 // TODO(henrika): remove usage of timers and add support for proper |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 UserInputMonitor* user_input_monitor) | 79 UserInputMonitor* user_input_monitor) |
79 : creator_task_runner_(base::MessageLoopProxy::current()), | 80 : creator_task_runner_(base::MessageLoopProxy::current()), |
80 handler_(handler), | 81 handler_(handler), |
81 stream_(NULL), | 82 stream_(NULL), |
82 data_is_active_(false), | 83 data_is_active_(false), |
83 state_(CLOSED), | 84 state_(CLOSED), |
84 sync_writer_(sync_writer), | 85 sync_writer_(sync_writer), |
85 max_volume_(0.0), | 86 max_volume_(0.0), |
86 user_input_monitor_(user_input_monitor), | 87 user_input_monitor_(user_input_monitor), |
87 #if defined(AUDIO_POWER_MONITORING) | 88 #if defined(AUDIO_POWER_MONITORING) |
89 log_silence_state_(false), | |
88 silence_state_(SILENCE_STATE_NO_MEASUREMENT), | 90 silence_state_(SILENCE_STATE_NO_MEASUREMENT), |
89 #endif | 91 #endif |
90 prev_key_down_count_(0) { | 92 prev_key_down_count_(0) { |
91 DCHECK(creator_task_runner_.get()); | 93 DCHECK(creator_task_runner_.get()); |
92 } | 94 } |
93 | 95 |
94 AudioInputController::~AudioInputController() { | 96 AudioInputController::~AudioInputController() { |
95 DCHECK_EQ(state_, CLOSED); | 97 DCHECK_EQ(state_, CLOSED); |
96 } | 98 } |
97 | 99 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; | 233 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; |
232 #endif | 234 #endif |
233 | 235 |
234 // TODO(miu): See TODO at top of file. Until that's resolved, assume all | 236 // TODO(miu): See TODO at top of file. Until that's resolved, assume all |
235 // platform audio input requires the |no_data_timer_| be used to auto-detect | 237 // platform audio input requires the |no_data_timer_| be used to auto-detect |
236 // errors. In reality, probably only Windows needs to be treated as | 238 // errors. In reality, probably only Windows needs to be treated as |
237 // unreliable here. | 239 // unreliable here. |
238 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); | 240 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); |
239 } | 241 } |
240 | 242 |
243 void AudioInputController::DoCreateForLowLatency(AudioManager* audio_manager, | |
244 const AudioParameters& params, | |
245 const std::string& device_id) { | |
246 DCHECK(task_runner_->BelongsToCurrentThread()); | |
247 | |
248 #if defined(AUDIO_POWER_MONITORING) | |
249 // We only log silence state UMA stats for low latency mode and if we use a | |
250 // real device. | |
251 if (params.format() != AudioParameters::AUDIO_FAKE) | |
252 log_silence_state_ = true; | |
253 #endif | |
254 | |
255 DoCreate(audio_manager, params, device_id); | |
256 } | |
257 | |
241 void AudioInputController::DoCreateForStream( | 258 void AudioInputController::DoCreateForStream( |
242 AudioInputStream* stream_to_control) { | 259 AudioInputStream* stream_to_control) { |
243 DCHECK(task_runner_->BelongsToCurrentThread()); | 260 DCHECK(task_runner_->BelongsToCurrentThread()); |
244 | 261 |
245 DCHECK(!stream_); | 262 DCHECK(!stream_); |
246 stream_ = stream_to_control; | 263 stream_ = stream_to_control; |
247 | 264 |
248 if (!stream_) { | 265 if (!stream_) { |
249 if (handler_) | 266 if (handler_) |
250 handler_->OnError(this, STREAM_CREATE_ERROR); | 267 handler_->OnError(this, STREAM_CREATE_ERROR); |
(...skipping 13 matching lines...) Expand all Loading... | |
264 DCHECK(!no_data_timer_.get()); | 281 DCHECK(!no_data_timer_.get()); |
265 | 282 |
266 // Create the data timer which will call FirstCheckForNoData(). The timer | 283 // Create the data timer which will call FirstCheckForNoData(). The timer |
267 // is started in DoRecord() and restarted in each DoCheckForNoData() | 284 // is started in DoRecord() and restarted in each DoCheckForNoData() |
268 // callback. | 285 // callback. |
269 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered | 286 // The timer is enabled for logging purposes. The NO_DATA_ERROR triggered |
270 // from the timer must be ignored by the EventHandler. | 287 // from the timer must be ignored by the EventHandler. |
271 // TODO(henrika): remove usage of timer when it has been verified on Canary | 288 // TODO(henrika): remove usage of timer when it has been verified on Canary |
272 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and | 289 // that we are safe doing so. Goal is to get rid of |no_data_timer_| and |
273 // everything that is tied to it. crbug.com/357569. | 290 // everything that is tied to it. crbug.com/357569. |
274 no_data_timer_.reset(new base::Timer( | 291 no_data_timer_.reset(new base::Timer( |
no longer working on chromium
2014/08/21 09:11:56
could you please also change the code here, we wo
Henrik Grunell
2014/08/21 11:06:10
I think that's outside the scope of this CL.
| |
275 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds), | 292 FROM_HERE, base::TimeDelta::FromSeconds(kTimerInitialIntervalSeconds), |
276 base::Bind(&AudioInputController::FirstCheckForNoData, | 293 base::Bind(&AudioInputController::FirstCheckForNoData, |
277 base::Unretained(this)), false)); | 294 base::Unretained(this)), false)); |
278 | 295 |
279 state_ = CREATED; | 296 state_ = CREATED; |
280 if (handler_) | 297 if (handler_) |
281 handler_->OnCreated(this); | 298 handler_->OnCreated(this); |
282 | 299 |
283 if (user_input_monitor_) { | 300 if (user_input_monitor_) { |
284 user_input_monitor_->EnableKeyPressMonitoring(); | 301 user_input_monitor_->EnableKeyPressMonitoring(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 DoStopCloseAndClearStream(); | 339 DoStopCloseAndClearStream(); |
323 SetDataIsActive(false); | 340 SetDataIsActive(false); |
324 | 341 |
325 if (SharedMemoryAndSyncSocketMode()) | 342 if (SharedMemoryAndSyncSocketMode()) |
326 sync_writer_->Close(); | 343 sync_writer_->Close(); |
327 | 344 |
328 if (user_input_monitor_) | 345 if (user_input_monitor_) |
329 user_input_monitor_->DisableKeyPressMonitoring(); | 346 user_input_monitor_->DisableKeyPressMonitoring(); |
330 | 347 |
331 #if defined(AUDIO_POWER_MONITORING) | 348 #if defined(AUDIO_POWER_MONITORING) |
332 // Send UMA stats if we have enabled power monitoring. | 349 // Send UMA stats if enabled. |
333 if (audio_level_) { | 350 if (log_silence_state_) |
334 LogSilenceState(silence_state_); | 351 LogSilenceState(silence_state_); |
335 } | 352 log_silence_state_ = false; |
336 #endif | 353 #endif |
337 | 354 |
338 state_ = CLOSED; | 355 state_ = CLOSED; |
339 } | 356 } |
340 | 357 |
341 void AudioInputController::DoReportError() { | 358 void AudioInputController::DoReportError() { |
342 DCHECK(task_runner_->BelongsToCurrentThread()); | 359 DCHECK(task_runner_->BelongsToCurrentThread()); |
343 if (handler_) | 360 if (handler_) |
344 handler_->OnError(this, STREAM_ERROR); | 361 handler_->OnError(this, STREAM_ERROR); |
345 } | 362 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 | 513 |
497 void AudioInputController::DoLogAudioLevel(float level_dbfs) { | 514 void AudioInputController::DoLogAudioLevel(float level_dbfs) { |
498 #if defined(AUDIO_POWER_MONITORING) | 515 #if defined(AUDIO_POWER_MONITORING) |
499 DCHECK(task_runner_->BelongsToCurrentThread()); | 516 DCHECK(task_runner_->BelongsToCurrentThread()); |
500 if (!handler_) | 517 if (!handler_) |
501 return; | 518 return; |
502 | 519 |
503 std::string log_string = base::StringPrintf( | 520 std::string log_string = base::StringPrintf( |
504 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); | 521 "AIC::OnData: average audio level=%.2f dBFS", level_dbfs); |
505 static const float kSilenceThresholdDBFS = -72.24719896f; | 522 static const float kSilenceThresholdDBFS = -72.24719896f; |
506 if (level_dbfs < kSilenceThresholdDBFS) { | 523 if (level_dbfs < kSilenceThresholdDBFS) |
507 log_string += " <=> no audio input!"; | 524 log_string += " <=> no audio input!"; |
508 if (silence_state_ == SILENCE_STATE_NO_MEASUREMENT) | 525 handler_->OnLog(this, log_string); |
509 silence_state_ = SILENCE_STATE_ONLY_SILENCE; | |
510 else if (silence_state_ == SILENCE_STATE_ONLY_AUDIO) | |
511 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; | |
512 else | |
513 DCHECK(silence_state_ == SILENCE_STATE_ONLY_SILENCE || | |
514 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); | |
515 } else { | |
516 if (silence_state_ == SILENCE_STATE_NO_MEASUREMENT) | |
517 silence_state_ = SILENCE_STATE_ONLY_AUDIO; | |
518 else if (silence_state_ == SILENCE_STATE_ONLY_SILENCE) | |
519 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; | |
520 else | |
521 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || | |
522 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); | |
523 } | |
524 | 526 |
525 handler_->OnLog(this, log_string); | 527 UpdateSilenceState(level_dbfs < kSilenceThresholdDBFS); |
526 #endif | 528 #endif |
527 } | 529 } |
528 | 530 |
529 void AudioInputController::OnError(AudioInputStream* stream) { | 531 void AudioInputController::OnError(AudioInputStream* stream) { |
530 // Handle error on the audio-manager thread. | 532 // Handle error on the audio-manager thread. |
531 task_runner_->PostTask(FROM_HERE, base::Bind( | 533 task_runner_->PostTask(FROM_HERE, base::Bind( |
532 &AudioInputController::DoReportError, this)); | 534 &AudioInputController::DoReportError, this)); |
533 } | 535 } |
534 | 536 |
535 void AudioInputController::DoStopCloseAndClearStream() { | 537 void AudioInputController::DoStopCloseAndClearStream() { |
(...skipping 12 matching lines...) Expand all Loading... | |
548 | 550 |
549 void AudioInputController::SetDataIsActive(bool enabled) { | 551 void AudioInputController::SetDataIsActive(bool enabled) { |
550 base::subtle::Release_Store(&data_is_active_, enabled); | 552 base::subtle::Release_Store(&data_is_active_, enabled); |
551 } | 553 } |
552 | 554 |
553 bool AudioInputController::GetDataIsActive() { | 555 bool AudioInputController::GetDataIsActive() { |
554 return (base::subtle::Acquire_Load(&data_is_active_) != false); | 556 return (base::subtle::Acquire_Load(&data_is_active_) != false); |
555 } | 557 } |
556 | 558 |
557 #if defined(AUDIO_POWER_MONITORING) | 559 #if defined(AUDIO_POWER_MONITORING) |
560 void AudioInputController::UpdateSilenceState(bool silence) { | |
561 if (silence) { | |
562 if (silence_state_ == SILENCE_STATE_NO_MEASUREMENT) | |
563 silence_state_ = SILENCE_STATE_ONLY_SILENCE; | |
564 else if (silence_state_ == SILENCE_STATE_ONLY_AUDIO) | |
565 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; | |
566 else | |
567 DCHECK(silence_state_ == SILENCE_STATE_ONLY_SILENCE || | |
568 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); | |
569 } else { | |
570 if (silence_state_ == SILENCE_STATE_NO_MEASUREMENT) | |
571 silence_state_ = SILENCE_STATE_ONLY_AUDIO; | |
572 else if (silence_state_ == SILENCE_STATE_ONLY_SILENCE) | |
573 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; | |
574 else | |
575 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || | |
576 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); | |
577 } | |
578 } | |
579 | |
558 void AudioInputController::LogSilenceState(SilenceState value) { | 580 void AudioInputController::LogSilenceState(SilenceState value) { |
559 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", | 581 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", |
560 value, | 582 value, |
561 SILENCE_STATE_MAX + 1); | 583 SILENCE_STATE_MAX + 1); |
562 } | 584 } |
563 #endif | 585 #endif |
564 | 586 |
565 } // namespace media | 587 } // namespace media |
OLD | NEW |