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
3 // found in the LICENSE file.
5 #include "media/audio/mac/audio_low_latency_input_mac.h"
7 #include <CoreServices/CoreServices.h>
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/mac/mac_logging.h"
12 #include "base/metrics/sparse_histogram.h"
13 #include "media/audio/mac/audio_manager_mac.h"
14 #include "media/base/audio_bus.h"
15 #include "media/base/data_buffer.h"
19 // Number of blocks of buffers used in the |fifo_|.
20 const int kNumberOfBlocksBufferInFifo
= 2;
22 static std::ostream
& operator<<(std::ostream
& os
,
23 const AudioStreamBasicDescription
& format
) {
24 os
<< "sample rate : " << format
.mSampleRate
<< std::endl
25 << "format ID : " << format
.mFormatID
<< std::endl
26 << "format flags : " << format
.mFormatFlags
<< std::endl
27 << "bytes per packet : " << format
.mBytesPerPacket
<< std::endl
28 << "frames per packet : " << format
.mFramesPerPacket
<< std::endl
29 << "bytes per frame : " << format
.mBytesPerFrame
<< std::endl
30 << "channels per frame: " << format
.mChannelsPerFrame
<< std::endl
31 << "bits per channel : " << format
.mBitsPerChannel
;
35 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit"
36 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html
37 // for more details and background regarding this implementation.
39 AUAudioInputStream::AUAudioInputStream(AudioManagerMac
* manager
,
40 const AudioParameters
& input_params
,
41 AudioDeviceID audio_device_id
)
43 number_of_frames_(input_params
.frames_per_buffer()),
46 input_device_id_(audio_device_id
),
48 hardware_latency_frames_(0),
49 number_of_channels_in_frame_(0),
50 fifo_(input_params
.channels(),
52 kNumberOfBlocksBufferInFifo
) {
55 // Set up the desired (output) format specified by the client.
56 format_
.mSampleRate
= input_params
.sample_rate();
57 format_
.mFormatID
= kAudioFormatLinearPCM
;
58 format_
.mFormatFlags
= kLinearPCMFormatFlagIsPacked
|
59 kLinearPCMFormatFlagIsSignedInteger
;
60 format_
.mBitsPerChannel
= input_params
.bits_per_sample();
61 format_
.mChannelsPerFrame
= input_params
.channels();
62 format_
.mFramesPerPacket
= 1; // uncompressed audio
63 format_
.mBytesPerPacket
= (format_
.mBitsPerChannel
*
64 input_params
.channels()) / 8;
65 format_
.mBytesPerFrame
= format_
.mBytesPerPacket
;
66 format_
.mReserved
= 0;
68 DVLOG(1) << "Desired ouput format: " << format_
;
70 // Derive size (in bytes) of the buffers that we will render to.
71 UInt32 data_byte_size
= number_of_frames_
* format_
.mBytesPerFrame
;
72 DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size
;
74 // Allocate AudioBuffers to be used as storage for the received audio.
75 // The AudioBufferList structure works as a placeholder for the
76 // AudioBuffer structure, which holds a pointer to the actual data buffer.
77 audio_data_buffer_
.reset(new uint8
[data_byte_size
]);
78 audio_buffer_list_
.mNumberBuffers
= 1;
80 AudioBuffer
* audio_buffer
= audio_buffer_list_
.mBuffers
;
81 audio_buffer
->mNumberChannels
= input_params
.channels();
82 audio_buffer
->mDataByteSize
= data_byte_size
;
83 audio_buffer
->mData
= audio_data_buffer_
.get();
86 AUAudioInputStream::~AUAudioInputStream() {}
88 // Obtain and open the AUHAL AudioOutputUnit for recording.
89 bool AUAudioInputStream::Open() {
90 // Verify that we are not already opened.
94 // Verify that we have a valid device.
95 if (input_device_id_
== kAudioObjectUnknown
) {
96 NOTREACHED() << "Device ID is unknown";
100 // Start by obtaining an AudioOuputUnit using an AUHAL component description.
102 // Description for the Audio Unit we want to use (AUHAL in this case).
103 AudioComponentDescription desc
= {
104 kAudioUnitType_Output
,
105 kAudioUnitSubType_HALOutput
,
106 kAudioUnitManufacturer_Apple
,
111 AudioComponent comp
= AudioComponentFindNext(0, &desc
);
114 // Get access to the service provided by the specified Audio Unit.
115 OSStatus result
= AudioComponentInstanceNew(comp
, &audio_unit_
);
121 // Enable IO on the input scope of the Audio Unit.
123 // After creating the AUHAL object, we must enable IO on the input scope
124 // of the Audio Unit to obtain the device input. Input must be explicitly
125 // enabled with the kAudioOutputUnitProperty_EnableIO property on Element 1
126 // of the AUHAL. Beacause the AUHAL can be used for both input and output,
127 // we must also disable IO on the output scope.
131 // Enable input on the AUHAL.
132 result
= AudioUnitSetProperty(audio_unit_
,
133 kAudioOutputUnitProperty_EnableIO
,
134 kAudioUnitScope_Input
,
135 1, // input element 1
143 // Disable output on the AUHAL.
145 result
= AudioUnitSetProperty(audio_unit_
,
146 kAudioOutputUnitProperty_EnableIO
,
147 kAudioUnitScope_Output
,
148 0, // output element 0
149 &enableIO
, // disable
156 // Next, set the audio device to be the Audio Unit's current device.
157 // Note that, devices can only be set to the AUHAL after enabling IO.
158 result
= AudioUnitSetProperty(audio_unit_
,
159 kAudioOutputUnitProperty_CurrentDevice
,
160 kAudioUnitScope_Global
,
163 sizeof(input_device_id_
));
169 // Set up the the desired (output) format.
170 // For obtaining input from a device, the device format is always expressed
171 // on the output scope of the AUHAL's Element 1.
172 result
= AudioUnitSetProperty(audio_unit_
,
173 kAudioUnitProperty_StreamFormat
,
174 kAudioUnitScope_Output
,
183 if (!manager_
->MaybeChangeBufferSize(
184 input_device_id_
, audio_unit_
, 1, number_of_frames_
))
187 // Register the input procedure for the AUHAL.
188 // This procedure will be called when the AUHAL has received new data
189 // from the input device.
190 AURenderCallbackStruct callback
;
191 callback
.inputProc
= InputProc
;
192 callback
.inputProcRefCon
= this;
193 result
= AudioUnitSetProperty(audio_unit_
,
194 kAudioOutputUnitProperty_SetInputCallback
,
195 kAudioUnitScope_Global
,
204 // Finally, initialize the audio unit and ensure that it is ready to render.
205 // Allocates memory according to the maximum number of audio frames
206 // it can produce in response to a single render call.
207 result
= AudioUnitInitialize(audio_unit_
);
213 // The hardware latency is fixed and will not change during the call.
214 hardware_latency_frames_
= GetHardwareLatency();
216 // The master channel is 0, Left and right are channels 1 and 2.
217 // And the master channel is not counted in |number_of_channels_in_frame_|.
218 number_of_channels_in_frame_
= GetNumberOfChannelsFromStream();
223 void AUAudioInputStream::Start(AudioInputCallback
* callback
) {
225 DLOG_IF(ERROR
, !audio_unit_
) << "Open() has not been called successfully";
226 if (started_
|| !audio_unit_
)
229 // Check if we should defer Start() for http://crbug.com/160920.
230 if (manager_
->ShouldDeferStreamStart()) {
231 // Use a cancellable closure so that if Stop() is called before Start()
232 // actually runs, we can cancel the pending start.
233 deferred_start_cb_
.Reset(base::Bind(
234 &AUAudioInputStream::Start
, base::Unretained(this), callback
));
235 manager_
->GetTaskRunner()->PostDelayedTask(
237 deferred_start_cb_
.callback(),
238 base::TimeDelta::FromSeconds(
239 AudioManagerMac::kStartDelayInSecsForPowerEvents
));
245 OSStatus result
= AudioOutputUnitStart(audio_unit_
);
246 if (result
== noErr
) {
249 OSSTATUS_DLOG_IF(ERROR
, result
!= noErr
, result
)
250 << "Failed to start acquiring data";
253 void AUAudioInputStream::Stop() {
257 OSStatus result
= AudioOutputUnitStop(audio_unit_
);
258 DCHECK_EQ(result
, noErr
);
263 OSSTATUS_DLOG_IF(ERROR
, result
!= noErr
, result
)
264 << "Failed to stop acquiring data";
267 void AUAudioInputStream::Close() {
268 // It is valid to call Close() before calling open or Start().
269 // It is also valid to call Close() after Start() has been called.
274 // Deallocate the audio unit’s resources.
275 OSStatus result
= AudioUnitUninitialize(audio_unit_
);
276 OSSTATUS_DLOG_IF(ERROR
, result
!= noErr
, result
)
277 << "AudioUnitUninitialize() failed.";
279 result
= AudioComponentInstanceDispose(audio_unit_
);
280 OSSTATUS_DLOG_IF(ERROR
, result
!= noErr
, result
)
281 << "AudioComponentInstanceDispose() failed.";
286 // Inform the audio manager that we have been closed. This can cause our
288 manager_
->ReleaseInputStream(this);
291 double AUAudioInputStream::GetMaxVolume() {
292 // Verify that we have a valid device.
293 if (input_device_id_
== kAudioObjectUnknown
) {
294 NOTREACHED() << "Device ID is unknown";
298 // Query if any of the master, left or right channels has volume control.
299 for (int i
= 0; i
<= number_of_channels_in_frame_
; ++i
) {
300 // If the volume is settable, the valid volume range is [0.0, 1.0].
301 if (IsVolumeSettableOnChannel(i
))
305 // Volume control is not available for the audio stream.
309 void AUAudioInputStream::SetVolume(double volume
) {
310 DVLOG(1) << "SetVolume(volume=" << volume
<< ")";
311 DCHECK_GE(volume
, 0.0);
312 DCHECK_LE(volume
, 1.0);
314 // Verify that we have a valid device.
315 if (input_device_id_
== kAudioObjectUnknown
) {
316 NOTREACHED() << "Device ID is unknown";
320 Float32 volume_float32
= static_cast<Float32
>(volume
);
321 AudioObjectPropertyAddress property_address
= {
322 kAudioDevicePropertyVolumeScalar
,
323 kAudioDevicePropertyScopeInput
,
324 kAudioObjectPropertyElementMaster
327 // Try to set the volume for master volume channel.
328 if (IsVolumeSettableOnChannel(kAudioObjectPropertyElementMaster
)) {
329 OSStatus result
= AudioObjectSetPropertyData(input_device_id_
,
333 sizeof(volume_float32
),
335 if (result
!= noErr
) {
336 DLOG(WARNING
) << "Failed to set volume to " << volume_float32
;
341 // There is no master volume control, try to set volume for each channel.
342 int successful_channels
= 0;
343 for (int i
= 1; i
<= number_of_channels_in_frame_
; ++i
) {
344 property_address
.mElement
= static_cast<UInt32
>(i
);
345 if (IsVolumeSettableOnChannel(i
)) {
346 OSStatus result
= AudioObjectSetPropertyData(input_device_id_
,
350 sizeof(volume_float32
),
353 ++successful_channels
;
357 DLOG_IF(WARNING
, successful_channels
== 0)
358 << "Failed to set volume to " << volume_float32
;
360 // Update the AGC volume level based on the last setting above. Note that,
361 // the volume-level resolution is not infinite and it is therefore not
362 // possible to assume that the volume provided as input parameter can be
363 // used directly. Instead, a new query to the audio hardware is required.
364 // This method does nothing if AGC is disabled.
368 double AUAudioInputStream::GetVolume() {
369 // Verify that we have a valid device.
370 if (input_device_id_
== kAudioObjectUnknown
){
371 NOTREACHED() << "Device ID is unknown";
375 AudioObjectPropertyAddress property_address
= {
376 kAudioDevicePropertyVolumeScalar
,
377 kAudioDevicePropertyScopeInput
,
378 kAudioObjectPropertyElementMaster
381 if (AudioObjectHasProperty(input_device_id_
, &property_address
)) {
382 // The device supports master volume control, get the volume from the
384 Float32 volume_float32
= 0.0;
385 UInt32 size
= sizeof(volume_float32
);
386 OSStatus result
= AudioObjectGetPropertyData(input_device_id_
,
393 return static_cast<double>(volume_float32
);
395 // There is no master volume control, try to get the average volume of
397 Float32 volume_float32
= 0.0;
398 int successful_channels
= 0;
399 for (int i
= 1; i
<= number_of_channels_in_frame_
; ++i
) {
400 property_address
.mElement
= static_cast<UInt32
>(i
);
401 if (AudioObjectHasProperty(input_device_id_
, &property_address
)) {
402 Float32 channel_volume
= 0;
403 UInt32 size
= sizeof(channel_volume
);
404 OSStatus result
= AudioObjectGetPropertyData(input_device_id_
,
410 if (result
== noErr
) {
411 volume_float32
+= channel_volume
;
412 ++successful_channels
;
417 // Get the average volume of the channels.
418 if (successful_channels
!= 0)
419 return static_cast<double>(volume_float32
/ successful_channels
);
422 DLOG(WARNING
) << "Failed to get volume";
426 bool AUAudioInputStream::IsMuted() {
427 // Verify that we have a valid device.
428 DCHECK_NE(input_device_id_
, kAudioObjectUnknown
) << "Device ID is unknown";
430 AudioObjectPropertyAddress property_address
= {
431 kAudioDevicePropertyMute
,
432 kAudioDevicePropertyScopeInput
,
433 kAudioObjectPropertyElementMaster
436 if (!AudioObjectHasProperty(input_device_id_
, &property_address
)) {
437 DLOG(ERROR
) << "Device does not support checking master mute state";
442 UInt32 size
= sizeof(muted
);
443 OSStatus result
= AudioObjectGetPropertyData(
444 input_device_id_
, &property_address
, 0, NULL
, &size
, &muted
);
445 DLOG_IF(WARNING
, result
!= noErr
) << "Failed to get mute state";
446 return result
== noErr
&& muted
!= 0;
449 // AUHAL AudioDeviceOutput unit callback
450 OSStatus
AUAudioInputStream::InputProc(void* user_data
,
451 AudioUnitRenderActionFlags
* flags
,
452 const AudioTimeStamp
* time_stamp
,
454 UInt32 number_of_frames
,
455 AudioBufferList
* io_data
) {
456 // Verify that the correct bus is used (Input bus/Element 1)
457 DCHECK_EQ(bus_number
, static_cast<UInt32
>(1));
458 AUAudioInputStream
* audio_input
=
459 reinterpret_cast<AUAudioInputStream
*>(user_data
);
462 return kAudioUnitErr_InvalidElement
;
464 // Update the |mDataByteSize| value in the audio_buffer_list() since
465 // |number_of_frames| can be changed on the fly.
466 // |mDataByteSize| needs to be exactly mapping to |number_of_frames|,
467 // otherwise it will put CoreAudio into bad state and results in
468 // AudioUnitRender() returning -50 for the new created stream.
469 // See crbug/428706 for details.
470 UInt32 new_size
= number_of_frames
* audio_input
->format_
.mBytesPerFrame
;
471 AudioBuffer
* audio_buffer
= audio_input
->audio_buffer_list()->mBuffers
;
472 if (new_size
!= audio_buffer
->mDataByteSize
) {
473 if (new_size
> audio_buffer
->mDataByteSize
) {
474 // This can happen iff the device is unpluged during recording. In such
475 // case the buffer will not be used anymore since |audio_unit_| becomes
476 // invalid. We allocate enough memory here to avoid depending on
477 // how CoreAudio handles it.
478 audio_input
->audio_data_buffer_
.reset(new uint8
[new_size
]);
479 audio_buffer
->mData
= audio_input
->audio_data_buffer_
.get();
482 // Update the |mDataByteSize| to match |number_of_frames|.
483 audio_buffer
->mDataByteSize
= new_size
;
486 // Receive audio from the AUHAL from the output scope of the Audio Unit.
487 OSStatus result
= AudioUnitRender(audio_input
->audio_unit(),
492 audio_input
->audio_buffer_list());
494 UMA_HISTOGRAM_SPARSE_SLOWLY("Media.AudioInputCbErrorMac", result
);
495 OSSTATUS_DLOG(ERROR
, result
) << "AudioUnitRender() failed.";
499 // Deliver recorded data to the consumer as a callback.
500 return audio_input
->Provide(number_of_frames
,
501 audio_input
->audio_buffer_list(),
505 OSStatus
AUAudioInputStream::Provide(UInt32 number_of_frames
,
506 AudioBufferList
* io_data
,
507 const AudioTimeStamp
* time_stamp
) {
508 // Update the capture latency.
509 double capture_latency_frames
= GetCaptureLatency(time_stamp
);
511 // The AGC volume level is updated once every second on a separate thread.
512 // Note that, |volume| is also updated each time SetVolume() is called
513 // through IPC by the render-side AGC.
514 double normalized_volume
= 0.0;
515 GetAgcVolume(&normalized_volume
);
517 AudioBuffer
& buffer
= io_data
->mBuffers
[0];
518 uint8
* audio_data
= reinterpret_cast<uint8
*>(buffer
.mData
);
519 uint32 capture_delay_bytes
= static_cast<uint32
>
520 ((capture_latency_frames
+ 0.5) * format_
.mBytesPerFrame
);
523 return kAudioUnitErr_InvalidElement
;
525 // Copy captured (and interleaved) data into FIFO.
526 fifo_
.Push(audio_data
, number_of_frames
, format_
.mBitsPerChannel
/ 8);
528 // Consume and deliver the data when the FIFO has a block of available data.
529 while (fifo_
.available_blocks()) {
530 const AudioBus
* audio_bus
= fifo_
.Consume();
531 DCHECK_EQ(audio_bus
->frames(), static_cast<int>(number_of_frames_
));
533 // Compensate the audio delay caused by the FIFO.
534 capture_delay_bytes
+= fifo_
.GetAvailableFrames() * format_
.mBytesPerFrame
;
535 sink_
->OnData(this, audio_bus
, capture_delay_bytes
, normalized_volume
);
541 int AUAudioInputStream::HardwareSampleRate() {
542 // Determine the default input device's sample-rate.
543 AudioDeviceID device_id
= kAudioObjectUnknown
;
544 UInt32 info_size
= sizeof(device_id
);
546 AudioObjectPropertyAddress default_input_device_address
= {
547 kAudioHardwarePropertyDefaultInputDevice
,
548 kAudioObjectPropertyScopeGlobal
,
549 kAudioObjectPropertyElementMaster
551 OSStatus result
= AudioObjectGetPropertyData(kAudioObjectSystemObject
,
552 &default_input_device_address
,
560 Float64 nominal_sample_rate
;
561 info_size
= sizeof(nominal_sample_rate
);
563 AudioObjectPropertyAddress nominal_sample_rate_address
= {
564 kAudioDevicePropertyNominalSampleRate
,
565 kAudioObjectPropertyScopeGlobal
,
566 kAudioObjectPropertyElementMaster
568 result
= AudioObjectGetPropertyData(device_id
,
569 &nominal_sample_rate_address
,
573 &nominal_sample_rate
);
577 return static_cast<int>(nominal_sample_rate
);
580 double AUAudioInputStream::GetHardwareLatency() {
581 if (!audio_unit_
|| input_device_id_
== kAudioObjectUnknown
) {
582 DLOG(WARNING
) << "Audio unit object is NULL or device ID is unknown";
586 // Get audio unit latency.
587 Float64 audio_unit_latency_sec
= 0.0;
588 UInt32 size
= sizeof(audio_unit_latency_sec
);
589 OSStatus result
= AudioUnitGetProperty(audio_unit_
,
590 kAudioUnitProperty_Latency
,
591 kAudioUnitScope_Global
,
593 &audio_unit_latency_sec
,
595 OSSTATUS_DLOG_IF(WARNING
, result
!= noErr
, result
)
596 << "Could not get audio unit latency";
598 // Get input audio device latency.
599 AudioObjectPropertyAddress property_address
= {
600 kAudioDevicePropertyLatency
,
601 kAudioDevicePropertyScopeInput
,
602 kAudioObjectPropertyElementMaster
604 UInt32 device_latency_frames
= 0;
605 size
= sizeof(device_latency_frames
);
606 result
= AudioObjectGetPropertyData(input_device_id_
,
611 &device_latency_frames
);
612 DLOG_IF(WARNING
, result
!= noErr
) << "Could not get audio device latency.";
614 return static_cast<double>((audio_unit_latency_sec
*
615 format_
.mSampleRate
) + device_latency_frames
);
618 double AUAudioInputStream::GetCaptureLatency(
619 const AudioTimeStamp
* input_time_stamp
) {
620 // Get the delay between between the actual recording instant and the time
621 // when the data packet is provided as a callback.
622 UInt64 capture_time_ns
= AudioConvertHostTimeToNanos(
623 input_time_stamp
->mHostTime
);
624 UInt64 now_ns
= AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
625 double delay_frames
= static_cast<double>
626 (1e-9 * (now_ns
- capture_time_ns
) * format_
.mSampleRate
);
628 // Total latency is composed by the dynamic latency and the fixed
630 return (delay_frames
+ hardware_latency_frames_
);
633 int AUAudioInputStream::GetNumberOfChannelsFromStream() {
634 // Get the stream format, to be able to read the number of channels.
635 AudioObjectPropertyAddress property_address
= {
636 kAudioDevicePropertyStreamFormat
,
637 kAudioDevicePropertyScopeInput
,
638 kAudioObjectPropertyElementMaster
640 AudioStreamBasicDescription stream_format
;
641 UInt32 size
= sizeof(stream_format
);
642 OSStatus result
= AudioObjectGetPropertyData(input_device_id_
,
648 if (result
!= noErr
) {
649 DLOG(WARNING
) << "Could not get stream format";
653 return static_cast<int>(stream_format
.mChannelsPerFrame
);
656 void AUAudioInputStream::HandleError(OSStatus err
) {
657 NOTREACHED() << "error " << GetMacOSStatusErrorString(err
)
658 << " (" << err
<< ")";
660 sink_
->OnError(this);
663 bool AUAudioInputStream::IsVolumeSettableOnChannel(int channel
) {
664 Boolean is_settable
= false;
665 AudioObjectPropertyAddress property_address
= {
666 kAudioDevicePropertyVolumeScalar
,
667 kAudioDevicePropertyScopeInput
,
668 static_cast<UInt32
>(channel
)
670 OSStatus result
= AudioObjectIsPropertySettable(input_device_id_
,
673 return (result
== noErr
) ? is_settable
: false;