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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |