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, | |
tommi (sloooow) - chröme
2014/08/21 18:06:58
why do we need a new function? Can't we just add
Henrik Grunell
2014/08/22 08:24:09
So that it's only logged in the low latency case.
Henrik Grunell
2014/08/22 08:51:18
Ah, now I chatted with Shijing offline and I under
| |
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 || | |
tommi (sloooow) - chröme
2014/08/21 18:06:58
{} (and subsequently add {} to all cases)
Henrik Grunell
2014/08/22 08:24:09
Done.
| |
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 |