f1dbdf786fb2910b21c043dddad598cb98b54b30
[platform/framework/web/crosswalk.git] / src / media / audio / mac / audio_low_latency_input_mac.cc
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.
4
5 #include "media/audio/mac/audio_low_latency_input_mac.h"
6
7 #include <CoreServices/CoreServices.h>
8
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/mac/mac_logging.h"
12 #include "media/audio/mac/audio_manager_mac.h"
13 #include "media/base/audio_bus.h"
14 #include "media/base/data_buffer.h"
15
16 namespace media {
17
18 // Number of blocks of buffers used in the |fifo_|.
19 const int kNumberOfBlocksBufferInFifo = 2;
20
21 static std::ostream& operator<<(std::ostream& os,
22                                 const AudioStreamBasicDescription& format) {
23   os << "sample rate       : " << format.mSampleRate << std::endl
24      << "format ID         : " << format.mFormatID << std::endl
25      << "format flags      : " << format.mFormatFlags << std::endl
26      << "bytes per packet  : " << format.mBytesPerPacket << std::endl
27      << "frames per packet : " << format.mFramesPerPacket << std::endl
28      << "bytes per frame   : " << format.mBytesPerFrame << std::endl
29      << "channels per frame: " << format.mChannelsPerFrame << std::endl
30      << "bits per channel  : " << format.mBitsPerChannel;
31   return os;
32 }
33
34 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit"
35 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html
36 // for more details and background regarding this implementation.
37
38 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager,
39                                        const AudioParameters& input_params,
40                                        AudioDeviceID audio_device_id)
41     : manager_(manager),
42       number_of_frames_(input_params.frames_per_buffer()),
43       sink_(NULL),
44       audio_unit_(0),
45       input_device_id_(audio_device_id),
46       started_(false),
47       hardware_latency_frames_(0),
48       number_of_channels_in_frame_(0),
49       fifo_(input_params.channels(),
50             number_of_frames_,
51             kNumberOfBlocksBufferInFifo) {
52   DCHECK(manager_);
53
54   // Set up the desired (output) format specified by the client.
55   format_.mSampleRate = input_params.sample_rate();
56   format_.mFormatID = kAudioFormatLinearPCM;
57   format_.mFormatFlags = kLinearPCMFormatFlagIsPacked |
58                          kLinearPCMFormatFlagIsSignedInteger;
59   format_.mBitsPerChannel = input_params.bits_per_sample();
60   format_.mChannelsPerFrame = input_params.channels();
61   format_.mFramesPerPacket = 1;  // uncompressed audio
62   format_.mBytesPerPacket = (format_.mBitsPerChannel *
63                              input_params.channels()) / 8;
64   format_.mBytesPerFrame = format_.mBytesPerPacket;
65   format_.mReserved = 0;
66
67   DVLOG(1) << "Desired ouput format: " << format_;
68
69   // Derive size (in bytes) of the buffers that we will render to.
70   UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame;
71   DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size;
72
73   // Allocate AudioBuffers to be used as storage for the received audio.
74   // The AudioBufferList structure works as a placeholder for the
75   // AudioBuffer structure, which holds a pointer to the actual data buffer.
76   audio_data_buffer_.reset(new uint8[data_byte_size]);
77   audio_buffer_list_.mNumberBuffers = 1;
78
79   AudioBuffer* audio_buffer = audio_buffer_list_.mBuffers;
80   audio_buffer->mNumberChannels = input_params.channels();
81   audio_buffer->mDataByteSize = data_byte_size;
82   audio_buffer->mData = audio_data_buffer_.get();
83 }
84
85 AUAudioInputStream::~AUAudioInputStream() {}
86
87 // Obtain and open the AUHAL AudioOutputUnit for recording.
88 bool AUAudioInputStream::Open() {
89   // Verify that we are not already opened.
90   if (audio_unit_)
91     return false;
92
93   // Verify that we have a valid device.
94   if (input_device_id_ == kAudioObjectUnknown) {
95     NOTREACHED() << "Device ID is unknown";
96     return false;
97   }
98
99   // Start by obtaining an AudioOuputUnit using an AUHAL component description.
100
101   // Description for the Audio Unit we want to use (AUHAL in this case).
102   AudioComponentDescription desc = {
103       kAudioUnitType_Output,
104       kAudioUnitSubType_HALOutput,
105       kAudioUnitManufacturer_Apple,
106       0,
107       0
108   };
109
110   AudioComponent comp = AudioComponentFindNext(0, &desc);
111   DCHECK(comp);
112
113   // Get access to the service provided by the specified Audio Unit.
114   OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_);
115   if (result) {
116     HandleError(result);
117     return false;
118   }
119
120   // Enable IO on the input scope of the Audio Unit.
121
122   // After creating the AUHAL object, we must enable IO on the input scope
123   // of the Audio Unit to obtain the device input. Input must be explicitly
124   // enabled with the kAudioOutputUnitProperty_EnableIO property on Element 1
125   // of the AUHAL. Beacause the AUHAL can be used for both input and output,
126   // we must also disable IO on the output scope.
127
128   UInt32 enableIO = 1;
129
130   // Enable input on the AUHAL.
131   result = AudioUnitSetProperty(audio_unit_,
132                                 kAudioOutputUnitProperty_EnableIO,
133                                 kAudioUnitScope_Input,
134                                 1,          // input element 1
135                                 &enableIO,  // enable
136                                 sizeof(enableIO));
137   if (result) {
138     HandleError(result);
139     return false;
140   }
141
142   // Disable output on the AUHAL.
143   enableIO = 0;
144   result = AudioUnitSetProperty(audio_unit_,
145                                 kAudioOutputUnitProperty_EnableIO,
146                                 kAudioUnitScope_Output,
147                                 0,          // output element 0
148                                 &enableIO,  // disable
149                                 sizeof(enableIO));
150   if (result) {
151     HandleError(result);
152     return false;
153   }
154
155   // Next, set the audio device to be the Audio Unit's current device.
156   // Note that, devices can only be set to the AUHAL after enabling IO.
157   result = AudioUnitSetProperty(audio_unit_,
158                                 kAudioOutputUnitProperty_CurrentDevice,
159                                 kAudioUnitScope_Global,
160                                 0,
161                                 &input_device_id_,
162                                 sizeof(input_device_id_));
163   if (result) {
164     HandleError(result);
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;
183   }
184
185   // Set up the the desired (output) format.
186   // For obtaining input from a device, the device format is always expressed
187   // on the output scope of the AUHAL's Element 1.
188   result = AudioUnitSetProperty(audio_unit_,
189                                 kAudioUnitProperty_StreamFormat,
190                                 kAudioUnitScope_Output,
191                                 1,
192                                 &format_,
193                                 sizeof(format_));
194   if (result) {
195     HandleError(result);
196     return false;
197   }
198
199   // Set the desired number of frames in the IO buffer (output scope).
200   // WARNING: Setting this value changes the frame size for all input audio
201   // units in the current process.  As a result, the AURenderCallback must be
202   // able to handle arbitrary buffer sizes and FIFO appropriately.
203   UInt32 buffer_size = 0;
204   UInt32 property_size = sizeof(buffer_size);
205   result = AudioUnitGetProperty(audio_unit_,
206                                 kAudioDevicePropertyBufferFrameSize,
207                                 kAudioUnitScope_Output,
208                                 1,
209                                 &buffer_size,
210                                 &property_size);
211   if (result != noErr) {
212     HandleError(result);
213     return false;
214   }
215
216   // Only set the buffer size if we're the only active stream or the buffer size
217   // is lower than the current buffer size.
218   if (manager_->input_stream_count() == 1 || number_of_frames_ < buffer_size) {
219     buffer_size = number_of_frames_;
220     result = AudioUnitSetProperty(audio_unit_,
221                                   kAudioDevicePropertyBufferFrameSize,
222                                   kAudioUnitScope_Output,
223                                   1,
224                                   &buffer_size,
225                                   sizeof(buffer_size));
226     if (result != noErr) {
227       HandleError(result);
228       return false;
229     }
230   }
231
232   // Finally, initialize the audio unit and ensure that it is ready to render.
233   // Allocates memory according to the maximum number of audio frames
234   // it can produce in response to a single render call.
235   result = AudioUnitInitialize(audio_unit_);
236   if (result) {
237     HandleError(result);
238     return false;
239   }
240
241   // The hardware latency is fixed and will not change during the call.
242   hardware_latency_frames_ = GetHardwareLatency();
243
244   // The master channel is 0, Left and right are channels 1 and 2.
245   // And the master channel is not counted in |number_of_channels_in_frame_|.
246   number_of_channels_in_frame_ = GetNumberOfChannelsFromStream();
247
248   return true;
249 }
250
251 void AUAudioInputStream::Start(AudioInputCallback* callback) {
252   DCHECK(callback);
253   DLOG_IF(ERROR, !audio_unit_) << "Open() has not been called successfully";
254   if (started_ || !audio_unit_)
255     return;
256
257   // Check if we should defer Start() for http://crbug.com/160920.
258   if (manager_->ShouldDeferStreamStart()) {
259     // Use a cancellable closure so that if Stop() is called before Start()
260     // actually runs, we can cancel the pending start.
261     deferred_start_cb_.Reset(base::Bind(
262         &AUAudioInputStream::Start, base::Unretained(this), callback));
263     manager_->GetTaskRunner()->PostDelayedTask(
264         FROM_HERE,
265         deferred_start_cb_.callback(),
266         base::TimeDelta::FromSeconds(
267             AudioManagerMac::kStartDelayInSecsForPowerEvents));
268     return;
269   }
270
271   sink_ = callback;
272   StartAgc();
273   OSStatus result = AudioOutputUnitStart(audio_unit_);
274   if (result == noErr) {
275     started_ = true;
276   }
277   OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
278       << "Failed to start acquiring data";
279 }
280
281 void AUAudioInputStream::Stop() {
282   if (!started_)
283     return;
284   StopAgc();
285   OSStatus result = AudioOutputUnitStop(audio_unit_);
286   DCHECK_EQ(result, noErr);
287   started_ = false;
288   sink_ = NULL;
289
290   OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
291       << "Failed to stop acquiring data";
292 }
293
294 void AUAudioInputStream::Close() {
295   // It is valid to call Close() before calling open or Start().
296   // It is also valid to call Close() after Start() has been called.
297   if (started_) {
298     Stop();
299   }
300   if (audio_unit_) {
301     // Deallocate the audio unit’s resources.
302     AudioUnitUninitialize(audio_unit_);
303
304     // Terminates our connection to the AUHAL component.
305     CloseComponent(audio_unit_);
306     audio_unit_ = 0;
307   }
308
309   // Inform the audio manager that we have been closed. This can cause our
310   // destruction.
311   manager_->ReleaseInputStream(this);
312 }
313
314 double AUAudioInputStream::GetMaxVolume() {
315   // Verify that we have a valid device.
316   if (input_device_id_ == kAudioObjectUnknown) {
317     NOTREACHED() << "Device ID is unknown";
318     return 0.0;
319   }
320
321   // Query if any of the master, left or right channels has volume control.
322   for (int i = 0; i <= number_of_channels_in_frame_; ++i) {
323     // If the volume is settable, the  valid volume range is [0.0, 1.0].
324     if (IsVolumeSettableOnChannel(i))
325       return 1.0;
326   }
327
328   // Volume control is not available for the audio stream.
329   return 0.0;
330 }
331
332 void AUAudioInputStream::SetVolume(double volume) {
333   DVLOG(1) << "SetVolume(volume=" << volume << ")";
334   DCHECK_GE(volume, 0.0);
335   DCHECK_LE(volume, 1.0);
336
337   // Verify that we have a valid device.
338   if (input_device_id_ == kAudioObjectUnknown) {
339     NOTREACHED() << "Device ID is unknown";
340     return;
341   }
342
343   Float32 volume_float32 = static_cast<Float32>(volume);
344   AudioObjectPropertyAddress property_address = {
345     kAudioDevicePropertyVolumeScalar,
346     kAudioDevicePropertyScopeInput,
347     kAudioObjectPropertyElementMaster
348   };
349
350   // Try to set the volume for master volume channel.
351   if (IsVolumeSettableOnChannel(kAudioObjectPropertyElementMaster)) {
352     OSStatus result = AudioObjectSetPropertyData(input_device_id_,
353                                                  &property_address,
354                                                  0,
355                                                  NULL,
356                                                  sizeof(volume_float32),
357                                                  &volume_float32);
358     if (result != noErr) {
359       DLOG(WARNING) << "Failed to set volume to " << volume_float32;
360     }
361     return;
362   }
363
364   // There is no master volume control, try to set volume for each channel.
365   int successful_channels = 0;
366   for (int i = 1; i <= number_of_channels_in_frame_; ++i) {
367     property_address.mElement = static_cast<UInt32>(i);
368     if (IsVolumeSettableOnChannel(i)) {
369       OSStatus result = AudioObjectSetPropertyData(input_device_id_,
370                                                    &property_address,
371                                                    0,
372                                                    NULL,
373                                                    sizeof(volume_float32),
374                                                    &volume_float32);
375       if (result == noErr)
376         ++successful_channels;
377     }
378   }
379
380   DLOG_IF(WARNING, successful_channels == 0)
381       << "Failed to set volume to " << volume_float32;
382
383   // Update the AGC volume level based on the last setting above. Note that,
384   // the volume-level resolution is not infinite and it is therefore not
385   // possible to assume that the volume provided as input parameter can be
386   // used directly. Instead, a new query to the audio hardware is required.
387   // This method does nothing if AGC is disabled.
388   UpdateAgcVolume();
389 }
390
391 double AUAudioInputStream::GetVolume() {
392   // Verify that we have a valid device.
393   if (input_device_id_ == kAudioObjectUnknown){
394     NOTREACHED() << "Device ID is unknown";
395     return 0.0;
396   }
397
398   AudioObjectPropertyAddress property_address = {
399     kAudioDevicePropertyVolumeScalar,
400     kAudioDevicePropertyScopeInput,
401     kAudioObjectPropertyElementMaster
402   };
403
404   if (AudioObjectHasProperty(input_device_id_, &property_address)) {
405     // The device supports master volume control, get the volume from the
406     // master channel.
407     Float32 volume_float32 = 0.0;
408     UInt32 size = sizeof(volume_float32);
409     OSStatus result = AudioObjectGetPropertyData(input_device_id_,
410                                                  &property_address,
411                                                  0,
412                                                  NULL,
413                                                  &size,
414                                                  &volume_float32);
415     if (result == noErr)
416       return static_cast<double>(volume_float32);
417   } else {
418     // There is no master volume control, try to get the average volume of
419     // all the channels.
420     Float32 volume_float32 = 0.0;
421     int successful_channels = 0;
422     for (int i = 1; i <= number_of_channels_in_frame_; ++i) {
423       property_address.mElement = static_cast<UInt32>(i);
424       if (AudioObjectHasProperty(input_device_id_, &property_address)) {
425         Float32 channel_volume = 0;
426         UInt32 size = sizeof(channel_volume);
427         OSStatus result = AudioObjectGetPropertyData(input_device_id_,
428                                                      &property_address,
429                                                      0,
430                                                      NULL,
431                                                      &size,
432                                                      &channel_volume);
433         if (result == noErr) {
434           volume_float32 += channel_volume;
435           ++successful_channels;
436         }
437       }
438     }
439
440     // Get the average volume of the channels.
441     if (successful_channels != 0)
442       return static_cast<double>(volume_float32 / successful_channels);
443   }
444
445   DLOG(WARNING) << "Failed to get volume";
446   return 0.0;
447 }
448
449 // AUHAL AudioDeviceOutput unit callback
450 OSStatus AUAudioInputStream::InputProc(void* user_data,
451                                        AudioUnitRenderActionFlags* flags,
452                                        const AudioTimeStamp* time_stamp,
453                                        UInt32 bus_number,
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);
460   DCHECK(audio_input);
461   if (!audio_input)
462     return kAudioUnitErr_InvalidElement;
463
464   // Receive audio from the AUHAL from the output scope of the Audio Unit.
465   OSStatus result = AudioUnitRender(audio_input->audio_unit(),
466                                     flags,
467                                     time_stamp,
468                                     bus_number,
469                                     number_of_frames,
470                                     audio_input->audio_buffer_list());
471   if (result)
472     return result;
473
474   // Deliver recorded data to the consumer as a callback.
475   return audio_input->Provide(number_of_frames,
476                               audio_input->audio_buffer_list(),
477                               time_stamp);
478 }
479
480 OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames,
481                                      AudioBufferList* io_data,
482                                      const AudioTimeStamp* time_stamp) {
483   // Update the capture latency.
484   double capture_latency_frames = GetCaptureLatency(time_stamp);
485
486   // The AGC volume level is updated once every second on a separate thread.
487   // Note that, |volume| is also updated each time SetVolume() is called
488   // through IPC by the render-side AGC.
489   double normalized_volume = 0.0;
490   GetAgcVolume(&normalized_volume);
491
492   AudioBuffer& buffer = io_data->mBuffers[0];
493   uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData);
494   uint32 capture_delay_bytes = static_cast<uint32>
495       ((capture_latency_frames + 0.5) * format_.mBytesPerFrame);
496   DCHECK(audio_data);
497   if (!audio_data)
498     return kAudioUnitErr_InvalidElement;
499
500   // Copy captured (and interleaved) data into FIFO.
501   fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8);
502
503   // Consume and deliver the data when the FIFO has a block of available data.
504   while (fifo_.available_blocks()) {
505     const AudioBus* audio_bus = fifo_.Consume();
506     DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_));
507
508     // Compensate the audio delay caused by the FIFO.
509     capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame;
510     sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume);
511   }
512
513   return noErr;
514 }
515
516 int AUAudioInputStream::HardwareSampleRate() {
517   // Determine the default input device's sample-rate.
518   AudioDeviceID device_id = kAudioObjectUnknown;
519   UInt32 info_size = sizeof(device_id);
520
521   AudioObjectPropertyAddress default_input_device_address = {
522     kAudioHardwarePropertyDefaultInputDevice,
523     kAudioObjectPropertyScopeGlobal,
524     kAudioObjectPropertyElementMaster
525   };
526   OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
527                                                &default_input_device_address,
528                                                0,
529                                                0,
530                                                &info_size,
531                                                &device_id);
532   if (result != noErr)
533     return 0.0;
534
535   Float64 nominal_sample_rate;
536   info_size = sizeof(nominal_sample_rate);
537
538   AudioObjectPropertyAddress nominal_sample_rate_address = {
539     kAudioDevicePropertyNominalSampleRate,
540     kAudioObjectPropertyScopeGlobal,
541     kAudioObjectPropertyElementMaster
542   };
543   result = AudioObjectGetPropertyData(device_id,
544                                       &nominal_sample_rate_address,
545                                       0,
546                                       0,
547                                       &info_size,
548                                       &nominal_sample_rate);
549   if (result != noErr)
550     return 0.0;
551
552   return static_cast<int>(nominal_sample_rate);
553 }
554
555 double AUAudioInputStream::GetHardwareLatency() {
556   if (!audio_unit_ || input_device_id_ == kAudioObjectUnknown) {
557     DLOG(WARNING) << "Audio unit object is NULL or device ID is unknown";
558     return 0.0;
559   }
560
561   // Get audio unit latency.
562   Float64 audio_unit_latency_sec = 0.0;
563   UInt32 size = sizeof(audio_unit_latency_sec);
564   OSStatus result = AudioUnitGetProperty(audio_unit_,
565                                          kAudioUnitProperty_Latency,
566                                          kAudioUnitScope_Global,
567                                          0,
568                                          &audio_unit_latency_sec,
569                                          &size);
570   OSSTATUS_DLOG_IF(WARNING, result != noErr, result)
571       << "Could not get audio unit latency";
572
573   // Get input audio device latency.
574   AudioObjectPropertyAddress property_address = {
575     kAudioDevicePropertyLatency,
576     kAudioDevicePropertyScopeInput,
577     kAudioObjectPropertyElementMaster
578   };
579   UInt32 device_latency_frames = 0;
580   size = sizeof(device_latency_frames);
581   result = AudioObjectGetPropertyData(input_device_id_,
582                                       &property_address,
583                                       0,
584                                       NULL,
585                                       &size,
586                                       &device_latency_frames);
587   DLOG_IF(WARNING, result != noErr) << "Could not get audio device latency.";
588
589   return static_cast<double>((audio_unit_latency_sec *
590       format_.mSampleRate) + device_latency_frames);
591 }
592
593 double AUAudioInputStream::GetCaptureLatency(
594     const AudioTimeStamp* input_time_stamp) {
595   // Get the delay between between the actual recording instant and the time
596   // when the data packet is provided as a callback.
597   UInt64 capture_time_ns = AudioConvertHostTimeToNanos(
598       input_time_stamp->mHostTime);
599   UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
600   double delay_frames = static_cast<double>
601       (1e-9 * (now_ns - capture_time_ns) * format_.mSampleRate);
602
603   // Total latency is composed by the dynamic latency and the fixed
604   // hardware latency.
605   return (delay_frames + hardware_latency_frames_);
606 }
607
608 int AUAudioInputStream::GetNumberOfChannelsFromStream() {
609   // Get the stream format, to be able to read the number of channels.
610   AudioObjectPropertyAddress property_address = {
611     kAudioDevicePropertyStreamFormat,
612     kAudioDevicePropertyScopeInput,
613     kAudioObjectPropertyElementMaster
614   };
615   AudioStreamBasicDescription stream_format;
616   UInt32 size = sizeof(stream_format);
617   OSStatus result = AudioObjectGetPropertyData(input_device_id_,
618                                                &property_address,
619                                                0,
620                                                NULL,
621                                                &size,
622                                                &stream_format);
623   if (result != noErr) {
624     DLOG(WARNING) << "Could not get stream format";
625     return 0;
626   }
627
628   return static_cast<int>(stream_format.mChannelsPerFrame);
629 }
630
631 void AUAudioInputStream::HandleError(OSStatus err) {
632   NOTREACHED() << "error " << GetMacOSStatusErrorString(err)
633                << " (" << err << ")";
634   if (sink_)
635     sink_->OnError(this);
636 }
637
638 bool AUAudioInputStream::IsVolumeSettableOnChannel(int channel) {
639   Boolean is_settable = false;
640   AudioObjectPropertyAddress property_address = {
641     kAudioDevicePropertyVolumeScalar,
642     kAudioDevicePropertyScopeInput,
643     static_cast<UInt32>(channel)
644   };
645   OSStatus result = AudioObjectIsPropertySettable(input_device_id_,
646                                                   &property_address,
647                                                   &is_settable);
648   return (result == noErr) ? is_settable : false;
649 }
650
651 }  // namespace media