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

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

Issue 532303002: Revert of Reland 501823002: Used native deinterleaved and float point format for the input streams (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « media/audio/mac/audio_low_latency_input_mac.h ('k') | media/base/audio_block_fifo.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/mac/audio_manager_mac.h" 12 #include "media/audio/mac/audio_manager_mac.h"
13 #include "media/base/audio_block_fifo.h"
14 #include "media/base/audio_bus.h" 13 #include "media/base/audio_bus.h"
15 #include "media/base/data_buffer.h" 14 #include "media/base/data_buffer.h"
16 15
17 namespace media { 16 namespace media {
18 17
19 // Number of blocks of buffers used in the |fifo_|. 18 // Number of blocks of buffers used in the |fifo_|.
20 const int kNumberOfBlocksBufferInFifo = 2; 19 const int kNumberOfBlocksBufferInFifo = 2;
21 20
22 static std::ostream& operator<<(std::ostream& os, 21 static std::ostream& operator<<(std::ostream& os,
23 const AudioStreamBasicDescription& format) { 22 const AudioStreamBasicDescription& format) {
24 os << "sample rate : " << format.mSampleRate << std::endl 23 os << "sample rate : " << format.mSampleRate << std::endl
25 << "format ID : " << format.mFormatID << std::endl 24 << "format ID : " << format.mFormatID << std::endl
26 << "format flags : " << format.mFormatFlags << std::endl 25 << "format flags : " << format.mFormatFlags << std::endl
27 << "bytes per packet : " << format.mBytesPerPacket << std::endl 26 << "bytes per packet : " << format.mBytesPerPacket << std::endl
28 << "frames per packet : " << format.mFramesPerPacket << std::endl 27 << "frames per packet : " << format.mFramesPerPacket << std::endl
29 << "bytes per frame : " << format.mBytesPerFrame << std::endl 28 << "bytes per frame : " << format.mBytesPerFrame << std::endl
30 << "channels per frame: " << format.mChannelsPerFrame << std::endl 29 << "channels per frame: " << format.mChannelsPerFrame << std::endl
31 << "bits per channel : " << format.mBitsPerChannel; 30 << "bits per channel : " << format.mBitsPerChannel;
32 return os; 31 return os;
33 } 32 }
34 33
35 static void WrapBufferList(AudioBufferList* buffer_list,
36 AudioBus* bus,
37 int frames) {
38 DCHECK(buffer_list);
39 DCHECK(bus);
40 const int channels = bus->channels();
41 const int buffer_list_channels = buffer_list->mNumberBuffers;
42 CHECK_EQ(channels, buffer_list_channels);
43
44 // Copy pointers from AudioBufferList.
45 for (int i = 0; i < channels; ++i)
46 bus->SetChannelData(i, static_cast<float*>(buffer_list->mBuffers[i].mData));
47
48 // Finally set the actual length.
49 bus->set_frames(frames);
50 }
51
52 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" 34 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit"
53 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html 35 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html
54 // for more details and background regarding this implementation. 36 // for more details and background regarding this implementation.
55 37
56 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, 38 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager,
57 const AudioParameters& input_params, 39 const AudioParameters& input_params,
58 AudioDeviceID audio_device_id) 40 AudioDeviceID audio_device_id)
59 : manager_(manager), 41 : manager_(manager),
60 number_of_frames_(input_params.frames_per_buffer()), 42 number_of_frames_(input_params.frames_per_buffer()),
61 sink_(NULL), 43 sink_(NULL),
62 audio_unit_(0), 44 audio_unit_(0),
63 input_device_id_(audio_device_id), 45 input_device_id_(audio_device_id),
64 started_(false), 46 started_(false),
65 hardware_latency_frames_(0), 47 hardware_latency_frames_(0),
66 number_of_channels_in_frame_(0), 48 number_of_channels_in_frame_(0),
67 audio_wrapper_(AudioBus::CreateWrapper(input_params.channels())) { 49 fifo_(input_params.channels(),
50 number_of_frames_,
51 kNumberOfBlocksBufferInFifo) {
68 DCHECK(manager_); 52 DCHECK(manager_);
69 53
70 // Set up the desired (output) format specified by the client. 54 // Set up the desired (output) format specified by the client.
71 format_.mSampleRate = input_params.sample_rate(); 55 format_.mSampleRate = input_params.sample_rate();
72 format_.mFormatID = kAudioFormatLinearPCM; 56 format_.mFormatID = kAudioFormatLinearPCM;
73 format_.mFormatFlags = 57 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked |
74 kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; 58 kLinearPCMFormatFlagIsSignedInteger;
75 size_t bytes_per_sample = sizeof(Float32); 59 format_.mBitsPerChannel = input_params.bits_per_sample();
76 format_.mBitsPerChannel = bytes_per_sample * 8;
77 format_.mChannelsPerFrame = input_params.channels(); 60 format_.mChannelsPerFrame = input_params.channels();
78 format_.mFramesPerPacket = 1; 61 format_.mFramesPerPacket = 1; // uncompressed audio
79 format_.mBytesPerFrame = bytes_per_sample; 62 format_.mBytesPerPacket = (format_.mBitsPerChannel *
80 format_.mBytesPerPacket = format_.mBytesPerFrame * format_.mFramesPerPacket; 63 input_params.channels()) / 8;
64 format_.mBytesPerFrame = format_.mBytesPerPacket;
81 format_.mReserved = 0; 65 format_.mReserved = 0;
82 66
83 DVLOG(1) << "Desired ouput format: " << format_; 67 DVLOG(1) << "Desired ouput format: " << format_;
84 68
85 // Allocate AudioBufferList based on the number of channels. 69 // Derive size (in bytes) of the buffers that we will render to.
86 audio_buffer_list_.reset(static_cast<AudioBufferList*>( 70 UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame;
87 malloc(sizeof(AudioBufferList) * input_params.channels()))); 71 DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size;
88 audio_buffer_list_->mNumberBuffers = input_params.channels();
89 72
90 // Allocate AudioBuffers to be used as storage for the received audio. 73 // Allocate AudioBuffers to be used as storage for the received audio.
91 // The AudioBufferList structure works as a placeholder for the 74 // The AudioBufferList structure works as a placeholder for the
92 // AudioBuffer structure, which holds a pointer to the actual data buffer. 75 // AudioBuffer structure, which holds a pointer to the actual data buffer.
93 UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame; 76 audio_data_buffer_.reset(new uint8[data_byte_size]);
94 audio_data_buffer_.reset(static_cast<float*>(base::AlignedAlloc( 77 audio_buffer_list_.mNumberBuffers = 1;
95 data_byte_size * audio_buffer_list_->mNumberBuffers, 78
96 AudioBus::kChannelAlignment))); 79 AudioBuffer* audio_buffer = audio_buffer_list_.mBuffers;
97 AudioBuffer* audio_buffer = audio_buffer_list_->mBuffers; 80 audio_buffer->mNumberChannels = input_params.channels();
98 for (UInt32 i = 0; i < audio_buffer_list_->mNumberBuffers; ++i) { 81 audio_buffer->mDataByteSize = data_byte_size;
99 audio_buffer[i].mNumberChannels = 1; 82 audio_buffer->mData = audio_data_buffer_.get();
100 audio_buffer[i].mDataByteSize = data_byte_size;
101 audio_buffer[i].mData = audio_data_buffer_.get() + i * data_byte_size;
102 }
103 } 83 }
104 84
105 AUAudioInputStream::~AUAudioInputStream() { 85 AUAudioInputStream::~AUAudioInputStream() {}
106 }
107 86
108 // Obtain and open the AUHAL AudioOutputUnit for recording. 87 // Obtain and open the AUHAL AudioOutputUnit for recording.
109 bool AUAudioInputStream::Open() { 88 bool AUAudioInputStream::Open() {
110 // Verify that we are not already opened. 89 // Verify that we are not already opened.
111 if (audio_unit_) 90 if (audio_unit_)
112 return false; 91 return false;
113 92
114 // Verify that we have a valid device. 93 // Verify that we have a valid device.
115 if (input_device_id_ == kAudioObjectUnknown) { 94 if (input_device_id_ == kAudioObjectUnknown) {
116 NOTREACHED() << "Device ID is unknown"; 95 NOTREACHED() << "Device ID is unknown";
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // Note that, devices can only be set to the AUHAL after enabling IO. 156 // Note that, devices can only be set to the AUHAL after enabling IO.
178 result = AudioUnitSetProperty(audio_unit_, 157 result = AudioUnitSetProperty(audio_unit_,
179 kAudioOutputUnitProperty_CurrentDevice, 158 kAudioOutputUnitProperty_CurrentDevice,
180 kAudioUnitScope_Global, 159 kAudioUnitScope_Global,
181 0, 160 0,
182 &input_device_id_, 161 &input_device_id_,
183 sizeof(input_device_id_)); 162 sizeof(input_device_id_));
184 if (result) { 163 if (result) {
185 HandleError(result); 164 HandleError(result);
186 return false; 165 return false;
166 }
167
168 // Register the input procedure for the AUHAL.
169 // This procedure will be called when the AUHAL has received new data
170 // from the input device.
171 AURenderCallbackStruct callback;
172 callback.inputProc = InputProc;
173 callback.inputProcRefCon = this;
174 result = AudioUnitSetProperty(audio_unit_,
175 kAudioOutputUnitProperty_SetInputCallback,
176 kAudioUnitScope_Global,
177 0,
178 &callback,
179 sizeof(callback));
180 if (result) {
181 HandleError(result);
182 return false;
187 } 183 }
188 184
189 // Set up the the desired (output) format. 185 // Set up the the desired (output) format.
190 // For obtaining input from a device, the device format is always expressed 186 // For obtaining input from a device, the device format is always expressed
191 // on the output scope of the AUHAL's Element 1. 187 // on the output scope of the AUHAL's Element 1.
192 result = AudioUnitSetProperty(audio_unit_, 188 result = AudioUnitSetProperty(audio_unit_,
193 kAudioUnitProperty_StreamFormat, 189 kAudioUnitProperty_StreamFormat,
194 kAudioUnitScope_Output, 190 kAudioUnitScope_Output,
195 1, 191 1,
196 &format_, 192 &format_,
(...skipping 29 matching lines...) Expand all
226 kAudioUnitScope_Output, 222 kAudioUnitScope_Output,
227 1, 223 1,
228 &buffer_size, 224 &buffer_size,
229 sizeof(buffer_size)); 225 sizeof(buffer_size));
230 if (result != noErr) { 226 if (result != noErr) {
231 HandleError(result); 227 HandleError(result);
232 return false; 228 return false;
233 } 229 }
234 } 230 }
235 231
236 // Register the input procedure for the AUHAL.
237 // This procedure will be called when the AUHAL has received new data
238 // from the input device.
239 AURenderCallbackStruct callback;
240 callback.inputProc = InputProc;
241 callback.inputProcRefCon = this;
242 result = AudioUnitSetProperty(audio_unit_,
243 kAudioOutputUnitProperty_SetInputCallback,
244 kAudioUnitScope_Global,
245 0,
246 &callback,
247 sizeof(callback));
248 if (result) {
249 HandleError(result);
250 return false;
251 }
252
253 // Finally, initialize the audio unit and ensure that it is ready to render. 232 // Finally, initialize the audio unit and ensure that it is ready to render.
254 // Allocates memory according to the maximum number of audio frames 233 // Allocates memory according to the maximum number of audio frames
255 // it can produce in response to a single render call. 234 // it can produce in response to a single render call.
256 result = AudioUnitInitialize(audio_unit_); 235 result = AudioUnitInitialize(audio_unit_);
257 if (result) { 236 if (result) {
258 HandleError(result); 237 HandleError(result);
259 return false; 238 return false;
260 } 239 }
261 240
262 // The hardware latency is fixed and will not change during the call. 241 // The hardware latency is fixed and will not change during the call.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 DCHECK_LE(volume, 1.0); 335 DCHECK_LE(volume, 1.0);
357 336
358 // Verify that we have a valid device. 337 // Verify that we have a valid device.
359 if (input_device_id_ == kAudioObjectUnknown) { 338 if (input_device_id_ == kAudioObjectUnknown) {
360 NOTREACHED() << "Device ID is unknown"; 339 NOTREACHED() << "Device ID is unknown";
361 return; 340 return;
362 } 341 }
363 342
364 Float32 volume_float32 = static_cast<Float32>(volume); 343 Float32 volume_float32 = static_cast<Float32>(volume);
365 AudioObjectPropertyAddress property_address = { 344 AudioObjectPropertyAddress property_address = {
366 kAudioDevicePropertyVolumeScalar, 345 kAudioDevicePropertyVolumeScalar,
367 kAudioDevicePropertyScopeInput, 346 kAudioDevicePropertyScopeInput,
368 kAudioObjectPropertyElementMaster 347 kAudioObjectPropertyElementMaster
369 }; 348 };
370 349
371 // Try to set the volume for master volume channel. 350 // Try to set the volume for master volume channel.
372 if (IsVolumeSettableOnChannel(kAudioObjectPropertyElementMaster)) { 351 if (IsVolumeSettableOnChannel(kAudioObjectPropertyElementMaster)) {
373 OSStatus result = AudioObjectSetPropertyData(input_device_id_, 352 OSStatus result = AudioObjectSetPropertyData(input_device_id_,
374 &property_address, 353 &property_address,
375 0, 354 0,
376 NULL, 355 NULL,
377 sizeof(volume_float32), 356 sizeof(volume_float32),
378 &volume_float32); 357 &volume_float32);
(...skipping 25 matching lines...) Expand all
404 // Update the AGC volume level based on the last setting above. Note that, 383 // Update the AGC volume level based on the last setting above. Note that,
405 // the volume-level resolution is not infinite and it is therefore not 384 // the volume-level resolution is not infinite and it is therefore not
406 // possible to assume that the volume provided as input parameter can be 385 // possible to assume that the volume provided as input parameter can be
407 // used directly. Instead, a new query to the audio hardware is required. 386 // used directly. Instead, a new query to the audio hardware is required.
408 // This method does nothing if AGC is disabled. 387 // This method does nothing if AGC is disabled.
409 UpdateAgcVolume(); 388 UpdateAgcVolume();
410 } 389 }
411 390
412 double AUAudioInputStream::GetVolume() { 391 double AUAudioInputStream::GetVolume() {
413 // Verify that we have a valid device. 392 // Verify that we have a valid device.
414 if (input_device_id_ == kAudioObjectUnknown) { 393 if (input_device_id_ == kAudioObjectUnknown){
415 NOTREACHED() << "Device ID is unknown"; 394 NOTREACHED() << "Device ID is unknown";
416 return 0.0; 395 return 0.0;
417 } 396 }
418 397
419 AudioObjectPropertyAddress property_address = { 398 AudioObjectPropertyAddress property_address = {
420 kAudioDevicePropertyVolumeScalar, 399 kAudioDevicePropertyVolumeScalar,
421 kAudioDevicePropertyScopeInput, 400 kAudioDevicePropertyScopeInput,
422 kAudioObjectPropertyElementMaster 401 kAudioObjectPropertyElementMaster
423 }; 402 };
424 403
425 if (AudioObjectHasProperty(input_device_id_, &property_address)) { 404 if (AudioObjectHasProperty(input_device_id_, &property_address)) {
426 // The device supports master volume control, get the volume from the 405 // The device supports master volume control, get the volume from the
427 // master channel. 406 // master channel.
428 Float32 volume_float32 = 0.0; 407 Float32 volume_float32 = 0.0;
429 UInt32 size = sizeof(volume_float32); 408 UInt32 size = sizeof(volume_float32);
430 OSStatus result = AudioObjectGetPropertyData( 409 OSStatus result = AudioObjectGetPropertyData(input_device_id_,
431 input_device_id_, &property_address, 0, NULL, &size, &volume_float32); 410 &property_address,
411 0,
412 NULL,
413 &size,
414 &volume_float32);
432 if (result == noErr) 415 if (result == noErr)
433 return static_cast<double>(volume_float32); 416 return static_cast<double>(volume_float32);
434 } else { 417 } else {
435 // There is no master volume control, try to get the average volume of 418 // There is no master volume control, try to get the average volume of
436 // all the channels. 419 // all the channels.
437 Float32 volume_float32 = 0.0; 420 Float32 volume_float32 = 0.0;
438 int successful_channels = 0; 421 int successful_channels = 0;
439 for (int i = 1; i <= number_of_channels_in_frame_; ++i) { 422 for (int i = 1; i <= number_of_channels_in_frame_; ++i) {
440 property_address.mElement = static_cast<UInt32>(i); 423 property_address.mElement = static_cast<UInt32>(i);
441 if (AudioObjectHasProperty(input_device_id_, &property_address)) { 424 if (AudioObjectHasProperty(input_device_id_, &property_address)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 OSStatus result = AudioUnitRender(audio_input->audio_unit(), 465 OSStatus result = AudioUnitRender(audio_input->audio_unit(),
483 flags, 466 flags,
484 time_stamp, 467 time_stamp,
485 bus_number, 468 bus_number,
486 number_of_frames, 469 number_of_frames,
487 audio_input->audio_buffer_list()); 470 audio_input->audio_buffer_list());
488 if (result) 471 if (result)
489 return result; 472 return result;
490 473
491 // Deliver recorded data to the consumer as a callback. 474 // Deliver recorded data to the consumer as a callback.
492 return audio_input->Provide( 475 return audio_input->Provide(number_of_frames,
493 number_of_frames, audio_input->audio_buffer_list(), time_stamp); 476 audio_input->audio_buffer_list(),
477 time_stamp);
494 } 478 }
495 479
496 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, 480 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames,
497 AudioBufferList* io_data, 481 AudioBufferList* io_data,
498 const AudioTimeStamp* time_stamp) { 482 const AudioTimeStamp* time_stamp) {
499 // Update the capture latency. 483 // Update the capture latency.
500 double capture_latency_frames = GetCaptureLatency(time_stamp); 484 double capture_latency_frames = GetCaptureLatency(time_stamp);
501 485
502 // The AGC volume level is updated once every second on a separate thread. 486 // The AGC volume level is updated once every second on a separate thread.
503 // Note that, |volume| is also updated each time SetVolume() is called 487 // Note that, |volume| is also updated each time SetVolume() is called
504 // through IPC by the render-side AGC. 488 // through IPC by the render-side AGC.
505 double normalized_volume = 0.0; 489 double normalized_volume = 0.0;
506 GetAgcVolume(&normalized_volume); 490 GetAgcVolume(&normalized_volume);
507 491
508 AudioBuffer& buffer = io_data->mBuffers[0]; 492 AudioBuffer& buffer = io_data->mBuffers[0];
509 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); 493 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData);
510 uint32 capture_delay_bytes = static_cast<uint32>( 494 uint32 capture_delay_bytes = static_cast<uint32>
511 (capture_latency_frames + 0.5) * format_.mBytesPerFrame); 495 ((capture_latency_frames + 0.5) * format_.mBytesPerFrame);
512 DCHECK(audio_data); 496 DCHECK(audio_data);
513 if (!audio_data) 497 if (!audio_data)
514 return kAudioUnitErr_InvalidElement; 498 return kAudioUnitErr_InvalidElement;
515 499
516 // Wrap the output AudioBufferList to |audio_wrapper_|. 500 // Copy captured (and interleaved) data into FIFO.
517 WrapBufferList(io_data, audio_wrapper_.get(), number_of_frames); 501 fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8);
518 502
519 // If the stream parameters change for any reason, we need to insert a FIFO 503 // Consume and deliver the data when the FIFO has a block of available data.
520 // since the OnMoreData() pipeline can't handle frame size changes. 504 while (fifo_.available_blocks()) {
521 if (number_of_frames != number_of_frames_) { 505 const AudioBus* audio_bus = fifo_.Consume();
522 // Create a FIFO on the fly to handle any discrepancies in callback rates. 506 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_));
523 if (!fifo_) {
524 fifo_.reset(new AudioBlockFifo(audio_wrapper_->channels(),
525 number_of_frames_,
526 kNumberOfBlocksBufferInFifo));
527 }
528 }
529 507
530 // When FIFO does not kick in, data will be directly passed to the callback. 508 // Compensate the audio delay caused by the FIFO.
531 if (!fifo_) { 509 capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame;
532 CHECK_EQ(audio_wrapper_->frames(), static_cast<int>(number_of_frames_));
533 sink_->OnData(
534 this, audio_wrapper_.get(), capture_delay_bytes, normalized_volume);
535 return noErr;
536 }
537
538 // Compensate the audio delay caused by the FIFO.
539 capture_delay_bytes += fifo_->GetAvailableFrames() * format_.mBytesPerFrame;
540
541 fifo_->Push(audio_wrapper_.get());
542 // Consume and deliver the data when the FIFO has a block of available data.
543 while (fifo_->available_blocks()) {
544 const AudioBus* audio_bus = fifo_->Consume();
545 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_));
546 sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume); 510 sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume);
547 } 511 }
548 512
549 return noErr; 513 return noErr;
550 } 514 }
551 515
552 int AUAudioInputStream::HardwareSampleRate() { 516 int AUAudioInputStream::HardwareSampleRate() {
553 // Determine the default input device's sample-rate. 517 // Determine the default input device's sample-rate.
554 AudioDeviceID device_id = kAudioObjectUnknown; 518 AudioDeviceID device_id = kAudioObjectUnknown;
555 UInt32 info_size = sizeof(device_id); 519 UInt32 info_size = sizeof(device_id);
556 520
557 AudioObjectPropertyAddress default_input_device_address = { 521 AudioObjectPropertyAddress default_input_device_address = {
558 kAudioHardwarePropertyDefaultInputDevice, 522 kAudioHardwarePropertyDefaultInputDevice,
559 kAudioObjectPropertyScopeGlobal, 523 kAudioObjectPropertyScopeGlobal,
560 kAudioObjectPropertyElementMaster 524 kAudioObjectPropertyElementMaster
561 }; 525 };
562 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, 526 OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
563 &default_input_device_address, 527 &default_input_device_address,
564 0, 528 0,
565 0, 529 0,
566 &info_size, 530 &info_size,
567 &device_id); 531 &device_id);
568 if (result != noErr) 532 if (result != noErr)
569 return 0.0; 533 return 0.0;
570 534
571 Float64 nominal_sample_rate; 535 Float64 nominal_sample_rate;
572 info_size = sizeof(nominal_sample_rate); 536 info_size = sizeof(nominal_sample_rate);
573 537
574 AudioObjectPropertyAddress nominal_sample_rate_address = { 538 AudioObjectPropertyAddress nominal_sample_rate_address = {
575 kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, 539 kAudioDevicePropertyNominalSampleRate,
576 kAudioObjectPropertyElementMaster}; 540 kAudioObjectPropertyScopeGlobal,
541 kAudioObjectPropertyElementMaster
542 };
577 result = AudioObjectGetPropertyData(device_id, 543 result = AudioObjectGetPropertyData(device_id,
578 &nominal_sample_rate_address, 544 &nominal_sample_rate_address,
579 0, 545 0,
580 0, 546 0,
581 &info_size, 547 &info_size,
582 &nominal_sample_rate); 548 &nominal_sample_rate);
583 if (result != noErr) 549 if (result != noErr)
584 return 0.0; 550 return 0.0;
585 551
586 return static_cast<int>(nominal_sample_rate); 552 return static_cast<int>(nominal_sample_rate);
(...skipping 12 matching lines...) Expand all
599 kAudioUnitProperty_Latency, 565 kAudioUnitProperty_Latency,
600 kAudioUnitScope_Global, 566 kAudioUnitScope_Global,
601 0, 567 0,
602 &audio_unit_latency_sec, 568 &audio_unit_latency_sec,
603 &size); 569 &size);
604 OSSTATUS_DLOG_IF(WARNING, result != noErr, result) 570 OSSTATUS_DLOG_IF(WARNING, result != noErr, result)
605 << "Could not get audio unit latency"; 571 << "Could not get audio unit latency";
606 572
607 // Get input audio device latency. 573 // Get input audio device latency.
608 AudioObjectPropertyAddress property_address = { 574 AudioObjectPropertyAddress property_address = {
609 kAudioDevicePropertyLatency, 575 kAudioDevicePropertyLatency,
610 kAudioDevicePropertyScopeInput, 576 kAudioDevicePropertyScopeInput,
611 kAudioObjectPropertyElementMaster 577 kAudioObjectPropertyElementMaster
612 }; 578 };
613 UInt32 device_latency_frames = 0; 579 UInt32 device_latency_frames = 0;
614 size = sizeof(device_latency_frames); 580 size = sizeof(device_latency_frames);
615 result = AudioObjectGetPropertyData(input_device_id_, 581 result = AudioObjectGetPropertyData(input_device_id_,
616 &property_address, 582 &property_address,
617 0, 583 0,
618 NULL, 584 NULL,
619 &size, 585 &size,
620 &device_latency_frames); 586 &device_latency_frames);
621 DLOG_IF(WARNING, result != noErr) << "Could not get audio device latency."; 587 DLOG_IF(WARNING, result != noErr) << "Could not get audio device latency.";
622 588
623 return static_cast<double>((audio_unit_latency_sec * format_.mSampleRate) + 589 return static_cast<double>((audio_unit_latency_sec *
624 device_latency_frames); 590 format_.mSampleRate) + device_latency_frames);
625 } 591 }
626 592
627 double AUAudioInputStream::GetCaptureLatency( 593 double AUAudioInputStream::GetCaptureLatency(
628 const AudioTimeStamp* input_time_stamp) { 594 const AudioTimeStamp* input_time_stamp) {
629 // Get the delay between between the actual recording instant and the time 595 // Get the delay between between the actual recording instant and the time
630 // when the data packet is provided as a callback. 596 // when the data packet is provided as a callback.
631 UInt64 capture_time_ns = 597 UInt64 capture_time_ns = AudioConvertHostTimeToNanos(
632 AudioConvertHostTimeToNanos(input_time_stamp->mHostTime); 598 input_time_stamp->mHostTime);
633 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); 599 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
634 double delay_frames = static_cast<double>(1e-9 * (now_ns - capture_time_ns) * 600 double delay_frames = static_cast<double>
635 format_.mSampleRate); 601 (1e-9 * (now_ns - capture_time_ns) * format_.mSampleRate);
636 602
637 // Total latency is composed by the dynamic latency and the fixed 603 // Total latency is composed by the dynamic latency and the fixed
638 // hardware latency. 604 // hardware latency.
639 return (delay_frames + hardware_latency_frames_); 605 return (delay_frames + hardware_latency_frames_);
640 } 606 }
641 607
642 int AUAudioInputStream::GetNumberOfChannelsFromStream() { 608 int AUAudioInputStream::GetNumberOfChannelsFromStream() {
643 // Get the stream format, to be able to read the number of channels. 609 // Get the stream format, to be able to read the number of channels.
644 AudioObjectPropertyAddress property_address = { 610 AudioObjectPropertyAddress property_address = {
645 kAudioDevicePropertyStreamFormat, 611 kAudioDevicePropertyStreamFormat,
646 kAudioDevicePropertyScopeInput, 612 kAudioDevicePropertyScopeInput,
647 kAudioObjectPropertyElementMaster 613 kAudioObjectPropertyElementMaster
648 }; 614 };
649 AudioStreamBasicDescription stream_format; 615 AudioStreamBasicDescription stream_format;
650 UInt32 size = sizeof(stream_format); 616 UInt32 size = sizeof(stream_format);
651 OSStatus result = AudioObjectGetPropertyData( 617 OSStatus result = AudioObjectGetPropertyData(input_device_id_,
652 input_device_id_, &property_address, 0, NULL, &size, &stream_format); 618 &property_address,
619 0,
620 NULL,
621 &size,
622 &stream_format);
653 if (result != noErr) { 623 if (result != noErr) {
654 DLOG(WARNING) << "Could not get stream format"; 624 DLOG(WARNING) << "Could not get stream format";
655 return 0; 625 return 0;
656 } 626 }
657 627
658 return static_cast<int>(stream_format.mChannelsPerFrame); 628 return static_cast<int>(stream_format.mChannelsPerFrame);
659 } 629 }
660 630
661 void AUAudioInputStream::HandleError(OSStatus err) { 631 void AUAudioInputStream::HandleError(OSStatus err) {
662 NOTREACHED() << "error " << GetMacOSStatusErrorString(err) << " (" << err 632 NOTREACHED() << "error " << GetMacOSStatusErrorString(err)
663 << ")"; 633 << " (" << err << ")";
664 if (sink_) 634 if (sink_)
665 sink_->OnError(this); 635 sink_->OnError(this);
666 } 636 }
667 637
668 bool AUAudioInputStream::IsVolumeSettableOnChannel(int channel) { 638 bool AUAudioInputStream::IsVolumeSettableOnChannel(int channel) {
669 Boolean is_settable = false; 639 Boolean is_settable = false;
670 AudioObjectPropertyAddress property_address = { 640 AudioObjectPropertyAddress property_address = {
671 kAudioDevicePropertyVolumeScalar, 641 kAudioDevicePropertyVolumeScalar,
672 kAudioDevicePropertyScopeInput, 642 kAudioDevicePropertyScopeInput,
673 static_cast<UInt32>(channel) 643 static_cast<UInt32>(channel)
674 }; 644 };
675 OSStatus result = AudioObjectIsPropertySettable( 645 OSStatus result = AudioObjectIsPropertySettable(input_device_id_,
676 input_device_id_, &property_address, &is_settable); 646 &property_address,
647 &is_settable);
677 return (result == noErr) ? is_settable : false; 648 return (result == noErr) ? is_settable : false;
678 } 649 }
679 650
680 } // namespace media 651 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/mac/audio_low_latency_input_mac.h ('k') | media/base/audio_block_fifo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698