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" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 result, | 66 result, |
67 CAPTURE_STARTUP_RESULT_MAX + 1); | 67 CAPTURE_STARTUP_RESULT_MAX + 1); |
68 | 68 |
69 } | 69 } |
70 | 70 |
71 namespace media { | 71 namespace media { |
72 | 72 |
73 // static | 73 // static |
74 AudioInputController::Factory* AudioInputController::factory_ = NULL; | 74 AudioInputController::Factory* AudioInputController::factory_ = NULL; |
75 | 75 |
76 AudioInputController::AudioInputController(EventHandler* handler, | 76 AudioInputController::AudioInputController(AudioManager* audio_manager, |
77 EventHandler* handler, | |
77 SyncWriter* sync_writer, | 78 SyncWriter* sync_writer, |
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), |
82 audio_manager_(audio_manager), | |
81 stream_(NULL), | 83 stream_(NULL), |
82 data_is_active_(false), | 84 data_is_active_(false), |
83 state_(CLOSED), | 85 state_(CLOSED), |
84 sync_writer_(sync_writer), | 86 sync_writer_(sync_writer), |
85 max_volume_(0.0), | 87 max_volume_(0.0), |
86 user_input_monitor_(user_input_monitor), | 88 user_input_monitor_(user_input_monitor), |
87 #if defined(AUDIO_POWER_MONITORING) | 89 #if defined(AUDIO_POWER_MONITORING) |
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) { |
(...skipping 13 matching lines...) Expand all Loading... | |
104 UserInputMonitor* user_input_monitor) { | 106 UserInputMonitor* user_input_monitor) { |
105 DCHECK(audio_manager); | 107 DCHECK(audio_manager); |
106 | 108 |
107 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) | 109 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) |
108 return NULL; | 110 return NULL; |
109 | 111 |
110 if (factory_) { | 112 if (factory_) { |
111 return factory_->Create( | 113 return factory_->Create( |
112 audio_manager, event_handler, params, user_input_monitor); | 114 audio_manager, event_handler, params, user_input_monitor); |
113 } | 115 } |
114 scoped_refptr<AudioInputController> controller( | 116 scoped_refptr<AudioInputController> controller(new AudioInputController( |
115 new AudioInputController(event_handler, NULL, user_input_monitor)); | 117 audio_manager, event_handler, NULL, user_input_monitor)); |
116 | 118 |
117 controller->task_runner_ = audio_manager->GetTaskRunner(); | 119 controller->task_runner_ = audio_manager->GetTaskRunner(); |
118 | 120 |
119 // Create and open a new audio input stream from the existing | 121 // Create and open a new audio input stream from the existing |
120 // audio-device thread. | 122 // audio-device thread. |
121 if (!controller->task_runner_->PostTask(FROM_HERE, | 123 if (!controller->task_runner_->PostTask( |
122 base::Bind(&AudioInputController::DoCreate, controller, | 124 FROM_HERE, |
123 base::Unretained(audio_manager), params, device_id))) { | 125 base::Bind(&AudioInputController::DoCreate, |
126 controller, | |
127 params, | |
128 device_id))) { | |
124 controller = NULL; | 129 controller = NULL; |
125 } | 130 } |
126 | 131 |
127 return controller; | 132 return controller; |
128 } | 133 } |
129 | 134 |
130 // static | 135 // static |
131 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( | 136 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( |
132 AudioManager* audio_manager, | 137 AudioManager* audio_manager, |
133 EventHandler* event_handler, | 138 EventHandler* event_handler, |
134 const AudioParameters& params, | 139 const AudioParameters& params, |
135 const std::string& device_id, | 140 const std::string& device_id, |
136 SyncWriter* sync_writer, | 141 SyncWriter* sync_writer, |
137 UserInputMonitor* user_input_monitor) { | 142 UserInputMonitor* user_input_monitor) { |
138 DCHECK(audio_manager); | 143 DCHECK(audio_manager); |
139 DCHECK(sync_writer); | 144 DCHECK(sync_writer); |
140 | 145 |
141 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) | 146 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) |
142 return NULL; | 147 return NULL; |
143 | 148 |
144 // Create the AudioInputController object and ensure that it runs on | 149 // Create the AudioInputController object and ensure that it runs on |
145 // the audio-manager thread. | 150 // the audio-manager thread. |
146 scoped_refptr<AudioInputController> controller( | 151 scoped_refptr<AudioInputController> controller(new AudioInputController( |
147 new AudioInputController(event_handler, sync_writer, user_input_monitor)); | 152 audio_manager, event_handler, sync_writer, user_input_monitor)); |
148 controller->task_runner_ = audio_manager->GetTaskRunner(); | 153 controller->task_runner_ = audio_manager->GetTaskRunner(); |
149 | 154 |
150 // Create and open a new audio input stream from the existing | 155 // Create and open a new audio input stream from the existing |
151 // audio-device thread. Use the provided audio-input device. | 156 // audio-device thread. Use the provided audio-input device. |
152 if (!controller->task_runner_->PostTask(FROM_HERE, | 157 if (!controller->task_runner_->PostTask( |
153 base::Bind(&AudioInputController::DoCreate, controller, | 158 FROM_HERE, |
154 base::Unretained(audio_manager), params, device_id))) { | 159 base::Bind(&AudioInputController::DoCreate, |
160 controller, | |
161 params, | |
162 device_id))) { | |
155 controller = NULL; | 163 controller = NULL; |
156 } | 164 } |
157 | 165 |
158 return controller; | 166 return controller; |
159 } | 167 } |
160 | 168 |
161 // static | 169 // static |
162 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( | 170 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( |
163 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 171 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
164 EventHandler* event_handler, | 172 EventHandler* event_handler, |
165 AudioInputStream* stream, | 173 AudioInputStream* stream, |
166 SyncWriter* sync_writer, | 174 SyncWriter* sync_writer, |
167 UserInputMonitor* user_input_monitor) { | 175 UserInputMonitor* user_input_monitor) { |
168 DCHECK(sync_writer); | 176 DCHECK(sync_writer); |
169 DCHECK(stream); | 177 DCHECK(stream); |
170 | 178 |
171 // Create the AudioInputController object and ensure that it runs on | 179 // Create the AudioInputController object and ensure that it runs on |
172 // the audio-manager thread. | 180 // the audio-manager thread. |
173 scoped_refptr<AudioInputController> controller( | 181 scoped_refptr<AudioInputController> controller(new AudioInputController( |
174 new AudioInputController(event_handler, sync_writer, user_input_monitor)); | 182 NULL, event_handler, sync_writer, user_input_monitor)); |
175 controller->task_runner_ = task_runner; | 183 controller->task_runner_ = task_runner; |
176 | 184 |
177 // TODO(miu): See TODO at top of file. Until that's resolved, we need to | 185 // TODO(miu): See TODO at top of file. Until that's resolved, we need to |
178 // disable the error auto-detection here (since the audio mirroring | 186 // disable the error auto-detection here (since the audio mirroring |
179 // implementation will reliably report error and close events). Note, of | 187 // implementation will reliably report error and close events). Note, of |
180 // course, that we're assuming CreateForStream() has been called for the audio | 188 // course, that we're assuming CreateForStream() has been called for the audio |
181 // mirroring use case only. | 189 // mirroring use case only. |
182 if (!controller->task_runner_->PostTask( | 190 if (!controller->task_runner_->PostTask( |
183 FROM_HERE, | 191 FROM_HERE, |
184 base::Bind(&AudioInputController::DoCreateForStream, | 192 base::Bind(&AudioInputController::DoCreateForStream, |
(...skipping 21 matching lines...) Expand all Loading... | |
206 void AudioInputController::SetVolume(double volume) { | 214 void AudioInputController::SetVolume(double volume) { |
207 task_runner_->PostTask(FROM_HERE, base::Bind( | 215 task_runner_->PostTask(FROM_HERE, base::Bind( |
208 &AudioInputController::DoSetVolume, this, volume)); | 216 &AudioInputController::DoSetVolume, this, volume)); |
209 } | 217 } |
210 | 218 |
211 void AudioInputController::SetAutomaticGainControl(bool enabled) { | 219 void AudioInputController::SetAutomaticGainControl(bool enabled) { |
212 task_runner_->PostTask(FROM_HERE, base::Bind( | 220 task_runner_->PostTask(FROM_HERE, base::Bind( |
213 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); | 221 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); |
214 } | 222 } |
215 | 223 |
216 void AudioInputController::DoCreate(AudioManager* audio_manager, | 224 void AudioInputController::DoCreate(const AudioParameters& params, |
217 const AudioParameters& params, | |
218 const std::string& device_id) { | 225 const std::string& device_id) { |
219 DCHECK(task_runner_->BelongsToCurrentThread()); | 226 DCHECK(task_runner_->BelongsToCurrentThread()); |
220 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); | 227 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); |
228 if (handler_) { | |
229 std::string log_string = | |
230 base::StringPrintf("AIC::DoCreate(device_id=%s)", device_id.c_str()); | |
Henrik Grunell
2014/08/22 16:14:42
What device id is this? Unique in what way? Can it
no longer working on chromium
2014/08/25 08:20:05
This is the uniqie id of the device, we can't log
henrika (OOO until Aug 14)
2014/08/25 12:47:44
Removing. Thanks.
| |
231 handler_->OnLog(this, log_string); | |
232 } | |
221 | 233 |
222 #if defined(AUDIO_POWER_MONITORING) | 234 #if defined(AUDIO_POWER_MONITORING) |
223 // Create the audio (power) level meter given the provided audio parameters. | 235 // Create the audio (power) level meter given the provided audio parameters. |
224 // An AudioBus is also needed to wrap the raw data buffer from the native | 236 // An AudioBus is also needed to wrap the raw data buffer from the native |
225 // layer to match AudioPowerMonitor::Scan(). | 237 // layer to match AudioPowerMonitor::Scan(). |
226 // TODO(henrika): Remove use of extra AudioBus. See http://crbug.com/375155. | 238 // TODO(henrika): Remove use of extra AudioBus. See http://crbug.com/375155. |
227 audio_level_.reset(new media::AudioPowerMonitor( | 239 audio_level_.reset(new media::AudioPowerMonitor( |
228 params.sample_rate(), | 240 params.sample_rate(), |
229 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); | 241 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); |
230 audio_params_ = params; | 242 audio_params_ = params; |
231 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; | 243 silence_state_ = SILENCE_STATE_NO_MEASUREMENT; |
232 #endif | 244 #endif |
233 | 245 |
246 if (audio_manager_) | |
247 audio_manager_->AddStateChangeListener(this); | |
248 | |
234 // TODO(miu): See TODO at top of file. Until that's resolved, assume all | 249 // 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 | 250 // 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 | 251 // errors. In reality, probably only Windows needs to be treated as |
237 // unreliable here. | 252 // unreliable here. |
238 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id)); | 253 DoCreateForStream(audio_manager_->MakeAudioInputStream(params, device_id)); |
239 } | 254 } |
240 | 255 |
241 void AudioInputController::DoCreateForStream( | 256 void AudioInputController::DoCreateForStream( |
242 AudioInputStream* stream_to_control) { | 257 AudioInputStream* stream_to_control) { |
243 DCHECK(task_runner_->BelongsToCurrentThread()); | 258 DCHECK(task_runner_->BelongsToCurrentThread()); |
244 | 259 |
245 DCHECK(!stream_); | 260 DCHECK(!stream_); |
246 stream_ = stream_to_control; | 261 stream_ = stream_to_control; |
247 | 262 |
248 if (!stream_) { | 263 if (!stream_) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); | 306 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); |
292 | 307 |
293 if (state_ != CREATED) | 308 if (state_ != CREATED) |
294 return; | 309 return; |
295 | 310 |
296 { | 311 { |
297 base::AutoLock auto_lock(lock_); | 312 base::AutoLock auto_lock(lock_); |
298 state_ = RECORDING; | 313 state_ = RECORDING; |
299 } | 314 } |
300 | 315 |
316 if (handler_) | |
317 handler_->OnLog(this, "AIC::DoRecord"); | |
no longer working on chromium
2014/08/25 08:20:05
I don't really think you should log these, DoRecor
henrika (OOO until Aug 14)
2014/08/25 12:47:44
Well, if it does that may very well be a reason wh
| |
318 | |
301 if (no_data_timer_) { | 319 if (no_data_timer_) { |
302 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, | 320 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, |
303 // a callback to FirstCheckForNoData() is made. | 321 // a callback to FirstCheckForNoData() is made. |
304 no_data_timer_->Reset(); | 322 no_data_timer_->Reset(); |
305 } | 323 } |
306 | 324 |
307 stream_->Start(this); | 325 stream_->Start(this); |
308 if (handler_) | 326 if (handler_) |
309 handler_->OnRecording(this); | 327 handler_->OnRecording(this); |
310 } | 328 } |
311 | 329 |
312 void AudioInputController::DoClose() { | 330 void AudioInputController::DoClose() { |
313 DCHECK(task_runner_->BelongsToCurrentThread()); | 331 DCHECK(task_runner_->BelongsToCurrentThread()); |
314 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); | 332 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); |
315 | 333 |
316 if (state_ == CLOSED) | 334 if (state_ == CLOSED) |
317 return; | 335 return; |
318 | 336 |
337 if (handler_) | |
338 handler_->OnLog(this, "AIC::DoClose"); | |
339 | |
319 // Delete the timer on the same thread that created it. | 340 // Delete the timer on the same thread that created it. |
320 no_data_timer_.reset(); | 341 no_data_timer_.reset(); |
321 | 342 |
322 DoStopCloseAndClearStream(); | 343 DoStopCloseAndClearStream(); |
323 SetDataIsActive(false); | 344 SetDataIsActive(false); |
324 | 345 |
346 if (audio_manager_) | |
347 audio_manager_->RemoveStateChangeListener(this); | |
Henrik Grunell
2014/08/22 16:14:43
Should the raw |audio_manager_| pointer be set to
henrika (OOO until Aug 14)
2014/08/25 12:47:44
It could but I can't really see the gain actually
| |
348 | |
325 if (SharedMemoryAndSyncSocketMode()) | 349 if (SharedMemoryAndSyncSocketMode()) |
326 sync_writer_->Close(); | 350 sync_writer_->Close(); |
327 | 351 |
328 if (user_input_monitor_) | 352 if (user_input_monitor_) |
329 user_input_monitor_->DisableKeyPressMonitoring(); | 353 user_input_monitor_->DisableKeyPressMonitoring(); |
330 | 354 |
331 #if defined(AUDIO_POWER_MONITORING) | 355 #if defined(AUDIO_POWER_MONITORING) |
332 // Send UMA stats if we have enabled power monitoring. | 356 // Send UMA stats if we have enabled power monitoring. |
333 if (audio_level_) { | 357 if (audio_level_) { |
334 LogSilenceState(silence_state_); | 358 LogSilenceState(silence_state_); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 return; | 400 return; |
377 | 401 |
378 stream_->SetAutomaticGainControl(enabled); | 402 stream_->SetAutomaticGainControl(enabled); |
379 } | 403 } |
380 | 404 |
381 void AudioInputController::FirstCheckForNoData() { | 405 void AudioInputController::FirstCheckForNoData() { |
382 DCHECK(task_runner_->BelongsToCurrentThread()); | 406 DCHECK(task_runner_->BelongsToCurrentThread()); |
383 LogCaptureStartupResult(GetDataIsActive() ? | 407 LogCaptureStartupResult(GetDataIsActive() ? |
384 CAPTURE_STARTUP_OK : | 408 CAPTURE_STARTUP_OK : |
385 CAPTURE_STARTUP_NO_DATA_CALLBACK); | 409 CAPTURE_STARTUP_NO_DATA_CALLBACK); |
410 if (handler_) { | |
411 GetDataIsActive() | |
412 ? handler_->OnLog(this, "AIC::FirstCheckForNoData => data is active") | |
no longer working on chromium
2014/08/25 08:20:05
this does not look like clang format, could you pl
henrika (OOO until Aug 14)
2014/08/25 12:47:44
I did run git cl format and this is what it gives
| |
413 : handler_->OnLog(this, | |
414 "AIC::FirstCheckForNoData => data is NOT active"); | |
415 } | |
386 DoCheckForNoData(); | 416 DoCheckForNoData(); |
387 } | 417 } |
388 | 418 |
389 void AudioInputController::DoCheckForNoData() { | 419 void AudioInputController::DoCheckForNoData() { |
390 DCHECK(task_runner_->BelongsToCurrentThread()); | 420 DCHECK(task_runner_->BelongsToCurrentThread()); |
391 | 421 |
392 if (!GetDataIsActive()) { | 422 if (!GetDataIsActive()) { |
393 // The data-is-active marker will be false only if it has been more than | 423 // The data-is-active marker will be false only if it has been more than |
394 // one second since a data packet was recorded. This can happen if a | 424 // one second since a data packet was recorded. This can happen if a |
395 // capture device has been removed or disabled. | 425 // capture device has been removed or disabled. |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; | 549 silence_state_ = SILENCE_STATE_AUDIO_AND_SILENCE; |
520 else | 550 else |
521 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || | 551 DCHECK(silence_state_ == SILENCE_STATE_ONLY_AUDIO || |
522 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); | 552 silence_state_ == SILENCE_STATE_AUDIO_AND_SILENCE); |
523 } | 553 } |
524 | 554 |
525 handler_->OnLog(this, log_string); | 555 handler_->OnLog(this, log_string); |
526 #endif | 556 #endif |
527 } | 557 } |
528 | 558 |
559 void AudioInputController::OnStateChange(const std::string state) { | |
560 DCHECK(task_runner_->BelongsToCurrentThread()); | |
561 if (handler_) | |
562 handler_->OnLog(this, state); | |
563 } | |
564 | |
529 void AudioInputController::OnError(AudioInputStream* stream) { | 565 void AudioInputController::OnError(AudioInputStream* stream) { |
530 // Handle error on the audio-manager thread. | 566 // Handle error on the audio-manager thread. |
531 task_runner_->PostTask(FROM_HERE, base::Bind( | 567 task_runner_->PostTask(FROM_HERE, base::Bind( |
532 &AudioInputController::DoReportError, this)); | 568 &AudioInputController::DoReportError, this)); |
533 } | 569 } |
534 | 570 |
535 void AudioInputController::DoStopCloseAndClearStream() { | 571 void AudioInputController::DoStopCloseAndClearStream() { |
536 DCHECK(task_runner_->BelongsToCurrentThread()); | 572 DCHECK(task_runner_->BelongsToCurrentThread()); |
537 | 573 |
538 // Allow calling unconditionally and bail if we don't have a stream to close. | 574 // Allow calling unconditionally and bail if we don't have a stream to close. |
(...skipping 17 matching lines...) Expand all Loading... | |
556 | 592 |
557 #if defined(AUDIO_POWER_MONITORING) | 593 #if defined(AUDIO_POWER_MONITORING) |
558 void AudioInputController::LogSilenceState(SilenceState value) { | 594 void AudioInputController::LogSilenceState(SilenceState value) { |
559 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", | 595 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerSessionSilenceReport", |
560 value, | 596 value, |
561 SILENCE_STATE_MAX + 1); | 597 SILENCE_STATE_MAX + 1); |
562 } | 598 } |
563 #endif | 599 #endif |
564 | 600 |
565 } // namespace media | 601 } // namespace media |
OLD | NEW |