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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 145 |
144 // Create the AudioInputController object and ensure that it runs on | 146 // Create the AudioInputController object and ensure that it runs on |
145 // the audio-manager thread. | 147 // the audio-manager thread. |
146 scoped_refptr<AudioInputController> controller( | 148 scoped_refptr<AudioInputController> controller( |
147 new AudioInputController(event_handler, sync_writer, user_input_monitor)); | 149 new AudioInputController(event_handler, sync_writer, user_input_monitor)); |
148 controller->task_runner_ = audio_manager->GetTaskRunner(); | 150 controller->task_runner_ = audio_manager->GetTaskRunner(); |
149 | 151 |
150 // Create and open a new audio input stream from the existing | 152 // Create and open a new audio input stream from the existing |
151 // audio-device thread. Use the provided audio-input device. | 153 // audio-device thread. Use the provided audio-input device. |
152 if (!controller->task_runner_->PostTask(FROM_HERE, | 154 if (!controller->task_runner_->PostTask(FROM_HERE, |
153 base::Bind(&AudioInputController::DoCreate, controller, | 155 base::Bind(&AudioInputController::DoCreateForLowLatency, controller, |
154 base::Unretained(audio_manager), params, device_id))) { | 156 base::Unretained(audio_manager), params, device_id))) { |
155 controller = NULL; | 157 controller = NULL; |
156 } | 158 } |
157 | 159 |
158 return controller; | 160 return controller; |
159 } | 161 } |
160 | 162 |
161 // static | 163 // static |
162 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( | 164 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( |
163 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 165 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
(...skipping 67 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 71 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 } |
| 570 } else { |
| 571 if (silence_state_ == SILENCE_STATE_NO_MEASUREMENT) { |
| 572 silence_state_ = SILENCE_STATE_ONLY_AUDIO; |
| 573 } else if (silence_state_ == SILENCE_STATE_ONLY_SILENCE) { |
| 574 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; |
| 575 } else { |
| 576 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || |
| 577 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); |
| 578 } |
| 579 } |
| 580 } |
| 581 |
558 void AudioInputController::LogSilenceState(SilenceState value) { | 582 void AudioInputController::LogSilenceState(SilenceState value) { |
559 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", | 583 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", |
560 value, | 584 value, |
561 SILENCE_STATE_MAX + 1); | 585 SILENCE_STATE_MAX + 1); |
562 } | 586 } |
563 #endif | 587 #endif |
564 | 588 |
565 } // namespace media | 589 } // namespace media |
OLD | NEW |