Chromium Code Reviews| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/mac_logging.h" | 10 #include "base/mac/mac_logging.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | | 72 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | |
| 73 kLinearPCMFormatFlagIsSignedInteger; | 73 kLinearPCMFormatFlagIsSignedInteger; |
| 74 format_.mBitsPerChannel = input_params.bits_per_sample(); | 74 format_.mBitsPerChannel = input_params.bits_per_sample(); |
| 75 format_.mChannelsPerFrame = input_params.channels(); | 75 format_.mChannelsPerFrame = input_params.channels(); |
| 76 format_.mFramesPerPacket = 1; // uncompressed audio | 76 format_.mFramesPerPacket = 1; // uncompressed audio |
| 77 format_.mBytesPerPacket = (format_.mBitsPerChannel * | 77 format_.mBytesPerPacket = (format_.mBitsPerChannel * |
| 78 input_params.channels()) / 8; | 78 input_params.channels()) / 8; |
| 79 format_.mBytesPerFrame = format_.mBytesPerPacket; | 79 format_.mBytesPerFrame = format_.mBytesPerPacket; |
| 80 format_.mReserved = 0; | 80 format_.mReserved = 0; |
| 81 | 81 |
| 82 DVLOG(1) << "Desired ouput format: " << format_; | 82 DVLOG(1) << "Desired output (client side) format: " << format_; |
| 83 | 83 |
| 84 // Derive size (in bytes) of the buffers that we will render to. | 84 // Derive size (in bytes) of the buffers that we will render to. |
| 85 UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame; | 85 UInt32 data_byte_size = number_of_frames_ * format_.mBytesPerFrame; |
| 86 DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size; | 86 DVLOG(1) << "Size of data buffer in bytes : " << data_byte_size; |
| 87 | 87 |
| 88 // Allocate AudioBuffers to be used as storage for the received audio. | 88 // Allocate AudioBuffers to be used as storage for the received audio. |
| 89 // The AudioBufferList structure works as a placeholder for the | 89 // The AudioBufferList structure works as a placeholder for the |
| 90 // AudioBuffer structure, which holds a pointer to the actual data buffer. | 90 // AudioBuffer structure, which holds a pointer to the actual data buffer. |
| 91 audio_data_buffer_.reset(new uint8_t[data_byte_size]); | 91 audio_data_buffer_.reset(new uint8_t[data_byte_size]); |
| 92 audio_buffer_list_.mNumberBuffers = 1; | 92 audio_buffer_list_.mNumberBuffers = 1; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 result = kAudioUnitErr_FormatNotSupported; | 127 result = kAudioUnitErr_FormatNotSupported; |
| 128 HandleError(result); | 128 HandleError(result); |
| 129 return false; | 129 return false; |
| 130 } | 130 } |
| 131 DLOG_IF(WARNING, buffer_size_was_changed_) << "IO buffer size was changed to " | 131 DLOG_IF(WARNING, buffer_size_was_changed_) << "IO buffer size was changed to " |
| 132 << number_of_frames_; | 132 << number_of_frames_; |
| 133 | 133 |
| 134 // Obtain an AudioOuputUnit using an AUHAL component description. | 134 // Obtain an AudioOuputUnit using an AUHAL component description. |
| 135 | 135 |
| 136 // Description for the Audio Unit we want to use (AUHAL in this case). | 136 // Description for the Audio Unit we want to use (AUHAL in this case). |
| 137 // The kAudioUnitSubType_HALOutput audio unit interfaces to any audio device. | |
| 138 // The user specifies which audio device to track. The audio unit can do | |
|
tommi (sloooow) - chröme
2015/12/28 18:49:50
Nit:spacing
henrika (OOO until Aug 14)
2015/12/29 09:32:25
My bad; hope it is OK if I skip uploading a fix fo
| |
| 139 // input from the device as well as output to the device. Bus 0 is used for | |
| 140 // the output side, bus 1 is used to get audio input from the device. | |
| 137 AudioComponentDescription desc = { | 141 AudioComponentDescription desc = { |
| 138 kAudioUnitType_Output, | 142 kAudioUnitType_Output, |
| 139 kAudioUnitSubType_HALOutput, | 143 kAudioUnitSubType_HALOutput, |
| 140 kAudioUnitManufacturer_Apple, | 144 kAudioUnitManufacturer_Apple, |
| 141 0, | 145 0, |
| 142 0 | 146 0 |
| 143 }; | 147 }; |
| 144 | 148 |
| 145 AudioComponent comp = AudioComponentFindNext(0, &desc); | 149 AudioComponent comp = AudioComponentFindNext(NULL, &desc); |
| 146 DCHECK(comp); | 150 DCHECK(comp); |
| 147 | 151 |
| 148 // Get access to the service provided by the specified Audio Unit. | 152 // Get access to the service provided by the specified Audio Unit. |
| 149 result = AudioComponentInstanceNew(comp, &audio_unit_); | 153 result = AudioComponentInstanceNew(comp, &audio_unit_); |
| 150 if (result) { | 154 if (result) { |
| 151 HandleError(result); | 155 HandleError(result); |
| 152 return false; | 156 return false; |
| 153 } | 157 } |
| 154 | 158 |
| 159 // Initialize the AUHAL before making any changes or using it. | |
| 160 result = AudioUnitInitialize(audio_unit_); | |
| 161 if (result != noErr) { | |
| 162 HandleError(result); | |
| 163 return false; | |
| 164 } | |
| 165 | |
| 155 // Enable IO on the input scope of the Audio Unit. | 166 // Enable IO on the input scope of the Audio Unit. |
| 156 | 167 |
| 157 // After creating the AUHAL object, we must enable IO on the input scope | 168 // After creating the AUHAL object, we must enable IO on the input scope |
| 158 // of the Audio Unit to obtain the device input. Input must be explicitly | 169 // of the Audio Unit to obtain the device input. Input must be explicitly |
| 159 // enabled with the kAudioOutputUnitProperty_EnableIO property on Element 1 | 170 // enabled with the kAudioOutputUnitProperty_EnableIO property on Element 1 |
| 160 // of the AUHAL. Beacause the AUHAL can be used for both input and output, | 171 // of the AUHAL. Beacause the AUHAL can be used for both input and output, |
| 161 // we must also disable IO on the output scope. | 172 // we must also disable IO on the output scope. |
| 162 | 173 |
| 163 UInt32 enableIO = 1; | 174 UInt32 enableIO = 1; |
| 164 | 175 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 sizeof(callback)); | 239 sizeof(callback)); |
| 229 if (result != noErr) { | 240 if (result != noErr) { |
| 230 HandleError(result); | 241 HandleError(result); |
| 231 return false; | 242 return false; |
| 232 } | 243 } |
| 233 | 244 |
| 234 // Finally, initialize the audio unit and ensure that it is ready to render. | 245 // Finally, initialize the audio unit and ensure that it is ready to render. |
| 235 // Allocates memory according to the maximum number of audio frames | 246 // Allocates memory according to the maximum number of audio frames |
| 236 // it can produce in response to a single render call. | 247 // it can produce in response to a single render call. |
| 237 result = AudioUnitInitialize(audio_unit_); | 248 result = AudioUnitInitialize(audio_unit_); |
| 238 if (result != noErr) { | 249 if (result != noErr) { |
|
tommi (sloooow) - chröme
2015/12/28 18:49:50
Remove this call then? Can it fail now that initi
henrika (OOO until Aug 14)
2015/12/29 09:32:25
No, that is the trick actually, to do it twice (an
| |
| 239 HandleError(result); | 250 HandleError(result); |
| 240 return false; | 251 return false; |
| 241 } | 252 } |
| 242 | 253 |
| 243 // The hardware latency is fixed and will not change during the call. | 254 // The hardware latency is fixed and will not change during the call. |
| 244 hardware_latency_frames_ = GetHardwareLatency(); | 255 hardware_latency_frames_ = GetHardwareLatency(); |
| 245 | 256 |
| 246 // The master channel is 0, Left and right are channels 1 and 2. | 257 // The master channel is 0, Left and right are channels 1 and 2. |
| 247 // And the master channel is not counted in |number_of_channels_in_frame_|. | 258 // And the master channel is not counted in |number_of_channels_in_frame_|. |
| 248 number_of_channels_in_frame_ = GetNumberOfChannelsFromStream(); | 259 number_of_channels_in_frame_ = GetNumberOfChannelsFromStream(); |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 manager_->output_streams()); | 815 manager_->output_streams()); |
| 805 UMA_HISTOGRAM_COUNTS_1000("Media.Audio.NumberOfLowLatencyInputStreamsMac", | 816 UMA_HISTOGRAM_COUNTS_1000("Media.Audio.NumberOfLowLatencyInputStreamsMac", |
| 806 manager_->low_latency_input_streams()); | 817 manager_->low_latency_input_streams()); |
| 807 UMA_HISTOGRAM_COUNTS_1000("Media.Audio.NumberOfBasicInputStreamsMac", | 818 UMA_HISTOGRAM_COUNTS_1000("Media.Audio.NumberOfBasicInputStreamsMac", |
| 808 manager_->basic_input_streams()); | 819 manager_->basic_input_streams()); |
| 809 UMA_HISTOGRAM_BOOLEAN("Media.Audio.AutomaticGainControlMac", | 820 UMA_HISTOGRAM_BOOLEAN("Media.Audio.AutomaticGainControlMac", |
| 810 GetAutomaticGainControl()); | 821 GetAutomaticGainControl()); |
| 811 } | 822 } |
| 812 | 823 |
| 813 } // namespace media | 824 } // namespace media |
| OLD | NEW |