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

Side by Side Diff: media/audio/mac/audio_low_latency_input_mac.cc

Issue 9702019: Adds Analog Gain Control (AGC) to the WebRTC client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 8 years, 9 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/mac/audio_low_latency_input_mac.h" 5 #include "media/audio/mac/audio_low_latency_input_mac.h"
6 6
7 #include <CoreServices/CoreServices.h> 7 #include <CoreServices/CoreServices.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/mac/mac_logging.h" 11 #include "base/mac/mac_logging.h"
12 #include "media/audio/audio_util.h" 12 #include "media/audio/audio_util.h"
13 #include "media/audio/mac/audio_manager_mac.h" 13 #include "media/audio/mac/audio_manager_mac.h"
14 14
15 static const int kMinIntervalBetweenVolumeUpdatesMs = 1000;
16
15 static std::ostream& operator<<(std::ostream& os, 17 static std::ostream& operator<<(std::ostream& os,
16 const AudioStreamBasicDescription& format) { 18 const AudioStreamBasicDescription& format) {
17 os << "sample rate : " << format.mSampleRate << std::endl 19 os << "sample rate : " << format.mSampleRate << std::endl
18 << "format ID : " << format.mFormatID << std::endl 20 << "format ID : " << format.mFormatID << std::endl
19 << "format flags : " << format.mFormatFlags << std::endl 21 << "format flags : " << format.mFormatFlags << std::endl
20 << "bytes per packet : " << format.mBytesPerPacket << std::endl 22 << "bytes per packet : " << format.mBytesPerPacket << std::endl
21 << "frames per packet : " << format.mFramesPerPacket << std::endl 23 << "frames per packet : " << format.mFramesPerPacket << std::endl
22 << "bytes per frame : " << format.mBytesPerFrame << std::endl 24 << "bytes per frame : " << format.mBytesPerFrame << std::endl
23 << "channels per frame: " << format.mChannelsPerFrame << std::endl 25 << "channels per frame: " << format.mChannelsPerFrame << std::endl
24 << "bits per channel : " << format.mBitsPerChannel; 26 << "bits per channel : " << format.mBitsPerChannel;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 // If the volume is settable, the valid volume range is [0.0, 1.0]. 284 // If the volume is settable, the valid volume range is [0.0, 1.0].
283 if (IsVolumeSettableOnChannel(i)) 285 if (IsVolumeSettableOnChannel(i))
284 return 1.0; 286 return 1.0;
285 } 287 }
286 288
287 // Volume control is not available for the audio stream. 289 // Volume control is not available for the audio stream.
288 return 0.0; 290 return 0.0;
289 } 291 }
290 292
291 void AUAudioInputStream::SetVolume(double volume) { 293 void AUAudioInputStream::SetVolume(double volume) {
292 DCHECK(volume <= 1.0 && volume >= 0.0); 294 DVLOG(1) << "SetVolume(volume=" << volume << ")";
295 DCHECK_GE(volume, 0.0);
296 DCHECK_LE(volume, 1.0);
293 297
294 // Verify that we have a valid device. 298 // Verify that we have a valid device.
295 if (input_device_id_ == kAudioObjectUnknown) { 299 if (input_device_id_ == kAudioObjectUnknown) {
296 NOTREACHED() << "Device ID is unknown"; 300 NOTREACHED() << "Device ID is unknown";
297 return; 301 return;
298 } 302 }
299 303
300 Float32 volume_float32 = static_cast<Float32>(volume); 304 Float32 volume_float32 = static_cast<Float32>(volume);
301 AudioObjectPropertyAddress property_address = { 305 AudioObjectPropertyAddress property_address = {
302 kAudioDevicePropertyVolumeScalar, 306 kAudioDevicePropertyVolumeScalar,
(...skipping 26 matching lines...) Expand all
329 NULL, 333 NULL,
330 sizeof(volume_float32), 334 sizeof(volume_float32),
331 &volume_float32); 335 &volume_float32);
332 if (result == noErr) 336 if (result == noErr)
333 ++successful_channels; 337 ++successful_channels;
334 } 338 }
335 } 339 }
336 340
337 DLOG_IF(WARNING, successful_channels == 0) 341 DLOG_IF(WARNING, successful_channels == 0)
338 << "Failed to set volume to " << volume_float32; 342 << "Failed to set volume to " << volume_float32;
343
344 // Update the AGC volume level based on the last setting above. Note that,
345 // the volume-level resolution is not infinite and it is therefore not
346 // possible to assume that the volume provided as input parameter can be
347 // used directly. Instead, a new query to the audio hardware is required.
348 // This method does nothing if AGC is disabled.
349 UpdateAgcVolume();
339 } 350 }
340 351
341 double AUAudioInputStream::GetVolume() { 352 double AUAudioInputStream::GetVolume() {
342 // Verify that we have a valid device. 353 // Verify that we have a valid device.
343 if (input_device_id_ == kAudioObjectUnknown){ 354 if (input_device_id_ == kAudioObjectUnknown){
344 NOTREACHED() << "Device ID is unknown"; 355 NOTREACHED() << "Device ID is unknown";
345 return 0.0; 356 return 0.0;
346 } 357 }
347 358
348 AudioObjectPropertyAddress property_address = { 359 AudioObjectPropertyAddress property_address = {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 audio_input->audio_buffer_list(), 437 audio_input->audio_buffer_list(),
427 time_stamp); 438 time_stamp);
428 } 439 }
429 440
430 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, 441 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames,
431 AudioBufferList* io_data, 442 AudioBufferList* io_data,
432 const AudioTimeStamp* time_stamp) { 443 const AudioTimeStamp* time_stamp) {
433 // Update the capture latency. 444 // Update the capture latency.
434 double capture_latency_frames = GetCaptureLatency(time_stamp); 445 double capture_latency_frames = GetCaptureLatency(time_stamp);
435 446
447 // Update the AGC volume level once every second. Note that, |volume| is
448 // also updated each time SetVolume() is called through IPC by the
449 // render-side AGC.
450 double normalized_volume = 0.0;
451 QueryAgcVolume(&normalized_volume);
452
436 AudioBuffer& buffer = io_data->mBuffers[0]; 453 AudioBuffer& buffer = io_data->mBuffers[0];
437 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); 454 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData);
438 uint32 capture_delay_bytes = static_cast<uint32> 455 uint32 capture_delay_bytes = static_cast<uint32>
439 ((capture_latency_frames + 0.5) * format_.mBytesPerFrame); 456 ((capture_latency_frames + 0.5) * format_.mBytesPerFrame);
440 DCHECK(audio_data); 457 DCHECK(audio_data);
441 if (!audio_data) 458 if (!audio_data)
442 return kAudioUnitErr_InvalidElement; 459 return kAudioUnitErr_InvalidElement;
443 460
444 sink_->OnData(this, audio_data, buffer.mDataByteSize, capture_delay_bytes); 461 // Deliver data packet, delay estimation and volume level to the user.
462 sink_->OnData(this,
463 audio_data,
464 buffer.mDataByteSize,
465 capture_delay_bytes,
466 normalized_volume);
445 467
446 return noErr; 468 return noErr;
447 } 469 }
448 470
449 int AUAudioInputStream::HardwareSampleRate() { 471 int AUAudioInputStream::HardwareSampleRate() {
450 // Determine the default input device's sample-rate. 472 // Determine the default input device's sample-rate.
451 AudioDeviceID device_id = kAudioObjectUnknown; 473 AudioDeviceID device_id = kAudioObjectUnknown;
452 UInt32 info_size = sizeof(device_id); 474 UInt32 info_size = sizeof(device_id);
453 475
454 AudioObjectPropertyAddress default_input_device_address = { 476 AudioObjectPropertyAddress default_input_device_address = {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 AudioObjectPropertyAddress property_address = { 597 AudioObjectPropertyAddress property_address = {
576 kAudioDevicePropertyVolumeScalar, 598 kAudioDevicePropertyVolumeScalar,
577 kAudioDevicePropertyScopeInput, 599 kAudioDevicePropertyScopeInput,
578 static_cast<UInt32>(channel) 600 static_cast<UInt32>(channel)
579 }; 601 };
580 OSStatus result = AudioObjectIsPropertySettable(input_device_id_, 602 OSStatus result = AudioObjectIsPropertySettable(input_device_id_,
581 &property_address, 603 &property_address,
582 &is_settable); 604 &is_settable);
583 return (result == noErr) ? is_settable : false; 605 return (result == noErr) ? is_settable : false;
584 } 606 }
OLDNEW
« no previous file with comments | « media/audio/mac/audio_low_latency_input_mac.h ('k') | media/audio/mac/audio_low_latency_input_mac_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698