Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: media/audio/audio_input_controller.cc

Issue 287873004: Adds volume level measurements to the AudioInputController for low-latency clients (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/threading/thread_restrictions.h" 8 #include "base/threading/thread_restrictions.h"
9 #include "base/time/time.h"
9 #include "media/base/limits.h" 10 #include "media/base/limits.h"
10 #include "media/base/scoped_histogram_timer.h" 11 #include "media/base/scoped_histogram_timer.h"
11 #include "media/base/user_input_monitor.h" 12 #include "media/base/user_input_monitor.h"
12 13
14 using base::TimeDelta;
15
13 namespace { 16 namespace {
14 const int kMaxInputChannels = 3; 17 const int kMaxInputChannels = 3;
15 18
16 // TODO(henrika): remove usage of timers and add support for proper 19 // TODO(henrika): remove usage of timers and add support for proper
17 // notification of when the input device is removed. This was originally added 20 // notification of when the input device is removed. This was originally added
18 // to resolve http://crbug.com/79936 for Windows platforms. This then caused 21 // to resolve http://crbug.com/79936 for Windows platforms. This then caused
19 // breakage (very hard to repro bugs!) on other platforms: See 22 // breakage (very hard to repro bugs!) on other platforms: See
20 // http://crbug.com/226327 and http://crbug.com/230972. 23 // http://crbug.com/226327 and http://crbug.com/230972.
21 // See also that the timer has been disabled on Mac now due to 24 // See also that the timer has been disabled on Mac now due to
22 // crbug.com/357501. 25 // crbug.com/357501.
23 const int kTimerResetIntervalSeconds = 1; 26 const int kTimerResetIntervalSeconds = 1;
24 // We have received reports that the timer can be too trigger happy on some 27 // We have received reports that the timer can be too trigger happy on some
25 // Mac devices and the initial timer interval has therefore been increased 28 // Mac devices and the initial timer interval has therefore been increased
26 // from 1 second to 5 seconds. 29 // from 1 second to 5 seconds.
27 const int kTimerInitialIntervalSeconds = 5; 30 const int kTimerInitialIntervalSeconds = 5;
31
32 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for
33 // semantics. This value was arbitrarily chosen, but seems to work well.
tommi (sloooow) - chröme 2014/05/17 13:45:00 maybe you can elaborate on how you tested this...
henrika (OOO until Aug 14) 2014/05/19 11:58:51 It is a time constant taken from the initial imple
34 const int kPowerMeasurementTimeConstantMillis = 10;
tommi (sloooow) - chröme 2014/05/17 13:45:00 nit: Milliseconds or Ms
henrika (OOO until Aug 14) 2014/05/19 11:58:51 I had done modifications before this review was fi
35
36 // Time between two successive measurements of audio power levels.
37 const int kPowerMonitorLogIntervalMilliSeconds = 500;
tommi (sloooow) - chröme 2014/05/17 13:45:00 nit: Milliseconds
henrika (OOO until Aug 14) 2014/05/19 11:58:51 Done.
28 } 38 }
29 39
30 namespace media { 40 namespace media {
31 41
32 // static 42 // static
33 AudioInputController::Factory* AudioInputController::factory_ = NULL; 43 AudioInputController::Factory* AudioInputController::factory_ = NULL;
34 44
35 AudioInputController::AudioInputController(EventHandler* handler, 45 AudioInputController::AudioInputController(EventHandler* handler,
36 SyncWriter* sync_writer, 46 SyncWriter* sync_writer,
37 UserInputMonitor* user_input_monitor) 47 UserInputMonitor* user_input_monitor)
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 void AudioInputController::SetAutomaticGainControl(bool enabled) { 176 void AudioInputController::SetAutomaticGainControl(bool enabled) {
167 task_runner_->PostTask(FROM_HERE, base::Bind( 177 task_runner_->PostTask(FROM_HERE, base::Bind(
168 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); 178 &AudioInputController::DoSetAutomaticGainControl, this, enabled));
169 } 179 }
170 180
171 void AudioInputController::DoCreate(AudioManager* audio_manager, 181 void AudioInputController::DoCreate(AudioManager* audio_manager,
172 const AudioParameters& params, 182 const AudioParameters& params,
173 const std::string& device_id) { 183 const std::string& device_id) {
174 DCHECK(task_runner_->BelongsToCurrentThread()); 184 DCHECK(task_runner_->BelongsToCurrentThread());
175 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); 185 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime");
186
187 // Create the audio (power) level meter given the provided audio parameters.
188 audio_level_.reset(new media::AudioPowerMonitor(params.sample_rate(),
189 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)));
190 audio_bus_ = AudioBus::Create(params);
tommi (sloooow) - chröme 2014/05/17 13:45:00 how cpu intensive is it to add this? This seems l
henrika (OOO until Aug 14) 2014/05/19 11:58:51 The plan was to perform measurements at a very low
191 audio_params_ = params;
192
176 // TODO(miu): See TODO at top of file. Until that's resolved, assume all 193 // TODO(miu): See TODO at top of file. Until that's resolved, assume all
177 // platform audio input requires the |no_data_timer_| be used to auto-detect 194 // platform audio input requires the |no_data_timer_| be used to auto-detect
178 // errors. In reality, probably only Windows needs to be treated as 195 // errors. In reality, probably only Windows needs to be treated as
179 // unreliable here. 196 // unreliable here.
180 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id), 197 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id),
181 true); 198 true);
182 } 199 }
183 200
184 void AudioInputController::DoCreateForStream( 201 void AudioInputController::DoCreateForStream(
185 AudioInputStream* stream_to_control, bool enable_nodata_timer) { 202 AudioInputStream* stream_to_control, bool enable_nodata_timer) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 void AudioInputController::DoClose() { 276 void AudioInputController::DoClose() {
260 DCHECK(task_runner_->BelongsToCurrentThread()); 277 DCHECK(task_runner_->BelongsToCurrentThread());
261 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); 278 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime");
262 279
263 if (state_ == CLOSED) 280 if (state_ == CLOSED)
264 return; 281 return;
265 282
266 // Delete the timer on the same thread that created it. 283 // Delete the timer on the same thread that created it.
267 no_data_timer_.reset(); 284 no_data_timer_.reset();
268 285
286 if (audio_level_)
287 audio_level_->Reset();
288
269 DoStopCloseAndClearStream(); 289 DoStopCloseAndClearStream();
270 SetDataIsActive(false); 290 SetDataIsActive(false);
271 291
272 if (SharedMemoryAndSyncSocketMode()) 292 if (SharedMemoryAndSyncSocketMode())
273 sync_writer_->Close(); 293 sync_writer_->Close();
274 294
275 if (user_input_monitor_) 295 if (user_input_monitor_)
276 user_input_monitor_->DisableKeyPressMonitoring(); 296 user_input_monitor_->DisableKeyPressMonitoring();
277 297
278 state_ = CLOSED; 298 state_ = CLOSED;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 key_pressed = current_count != prev_key_down_count_; 390 key_pressed = current_count != prev_key_down_count_;
371 prev_key_down_count_ = current_count; 391 prev_key_down_count_ = current_count;
372 DVLOG_IF(6, key_pressed) << "Detected keypress."; 392 DVLOG_IF(6, key_pressed) << "Detected keypress.";
373 } 393 }
374 394
375 // Use SharedMemory and SyncSocket if the client has created a SyncWriter. 395 // Use SharedMemory and SyncSocket if the client has created a SyncWriter.
376 // Used by all low-latency clients except WebSpeech. 396 // Used by all low-latency clients except WebSpeech.
377 if (SharedMemoryAndSyncSocketMode()) { 397 if (SharedMemoryAndSyncSocketMode()) {
378 sync_writer_->Write(data, size, volume, key_pressed); 398 sync_writer_->Write(data, size, volume, key_pressed);
379 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes); 399 sync_writer_->UpdateRecordedBytes(hardware_delay_bytes);
400
401 if (!audio_level_)
402 return;
403
404 // Perform periodic audio (power) level measurements.
405 if ((base::TimeTicks::Now() - last_audio_level_log_time_).InMilliseconds() >
406 kPowerMonitorLogIntervalMilliSeconds) {
407 last_audio_level_log_time_ = base::TimeTicks::Now();
408 audio_bus_->FromInterleaved(
tommi (sloooow) - chröme 2014/05/17 13:45:00 safe to access these variables on a different thre
henrika (OOO until Aug 14) 2014/05/19 11:58:51 I have rewritten this part in the latest version.
409 data, audio_bus_->frames(), audio_params_.bits_per_sample() / 8);
410 audio_level_->Scan(*audio_bus_, audio_bus_->frames());
411 std::pair<float, bool> result = audio_level_->ReadCurrentPowerAndClip();
412
413 // Get the audible level in the range [0.0,1.0], where 0.0 means
414 // the audio signal is silent and 1.0 means it is at maximum volume.
415 float level_dbfs = result.first;
416 float level = 0;
417 static const float kSilenceThresholdDBFS = -72.24719896f;
tommi (sloooow) - chröme 2014/05/17 13:45:00 how does this translate to a data packet of all ze
henrika (OOO until Aug 14) 2014/05/19 11:58:51 Assume that you by packet mean all audio frames co
418 if (level_dbfs < kSilenceThresholdDBFS)
419 level = 0.0f;
420 else if (level_dbfs > 0.0f)
421 level = 1.0f;
422 else
423 level = 1.0f - level_dbfs / kSilenceThresholdDBFS;
424 DVLOG(1) << "audio_level: " << level;
425
426 audio_level_->Reset();
427 }
428
380 return; 429 return;
tommi (sloooow) - chröme 2014/05/17 13:45:00 nit: remove?
henrika (OOO until Aug 14) 2014/05/19 11:58:51 has been modified.
381 } 430 }
382 431
383 // TODO(henrika): Investigate if we can avoid the extra copy here. 432 // TODO(henrika): Investigate if we can avoid the extra copy here.
384 // (see http://crbug.com/249316 for details). AFAIK, this scope is only 433 // (see http://crbug.com/249316 for details). AFAIK, this scope is only
385 // active for WebSpeech clients. 434 // active for WebSpeech clients.
386 scoped_ptr<uint8[]> audio_data(new uint8[size]); 435 scoped_ptr<uint8[]> audio_data(new uint8[size]);
387 memcpy(audio_data.get(), data, size); 436 memcpy(audio_data.get(), data, size);
388 437
389 // Ownership of the audio buffer will be with the callback until it is run, 438 // Ownership of the audio buffer will be with the callback until it is run,
390 // when ownership is passed to the callback function. 439 // when ownership is passed to the callback function.
(...skipping 29 matching lines...) Expand all
420 469
421 void AudioInputController::SetDataIsActive(bool enabled) { 470 void AudioInputController::SetDataIsActive(bool enabled) {
422 base::subtle::Release_Store(&data_is_active_, enabled); 471 base::subtle::Release_Store(&data_is_active_, enabled);
423 } 472 }
424 473
425 bool AudioInputController::GetDataIsActive() { 474 bool AudioInputController::GetDataIsActive() {
426 return (base::subtle::Acquire_Load(&data_is_active_) != false); 475 return (base::subtle::Acquire_Load(&data_is_active_) != false);
427 } 476 }
428 477
429 } // namespace media 478 } // namespace media
OLDNEW
« media/audio/audio_input_controller.h ('K') | « media/audio/audio_input_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698