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 |