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_output_mac.h" | 5 #include "media/audio/mac/audio_low_latency_output_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/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 kAudioUnitProperty_StreamFormat, | 147 kAudioUnitProperty_StreamFormat, |
148 kAudioUnitScope_Input, | 148 kAudioUnitScope_Input, |
149 0, | 149 0, |
150 &format_, | 150 &format_, |
151 sizeof(format_)); | 151 sizeof(format_)); |
152 OSSTATUS_DCHECK(result == noErr, result); | 152 OSSTATUS_DCHECK(result == noErr, result); |
153 if (result) | 153 if (result) |
154 return false; | 154 return false; |
155 | 155 |
156 // Set the buffer frame size. | 156 // Set the buffer frame size. |
157 // WARNING: Setting this value changes the frame size for all audio units in | |
158 // the current process. It's imperative that the input and output frame sizes | |
159 // be the same as audio_util::GetAudioHardwareBufferSize(). | |
160 // TODO(henrika): Due to http://crrev.com/159666 this is currently not true | |
161 // and should be fixed, a CHECK() should be added at that time. | |
157 UInt32 buffer_size = number_of_frames_; | 162 UInt32 buffer_size = number_of_frames_; |
158 result = AudioUnitSetProperty( | 163 result = AudioUnitSetProperty( |
159 output_unit_, | 164 output_unit_, |
160 kAudioDevicePropertyBufferFrameSize, | 165 kAudioDevicePropertyBufferFrameSize, |
161 kAudioUnitScope_Output, | 166 kAudioUnitScope_Output, |
162 0, | 167 0, |
163 &buffer_size, | 168 &buffer_size, |
164 sizeof(buffer_size)); | 169 sizeof(buffer_size)); |
165 OSSTATUS_DCHECK(result == noErr, result); | 170 OSSTATUS_DCHECK(result == noErr, result); |
166 if (result) | 171 if (result) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 switches::kDisableAudioOutputResampler); | 232 switches::kDisableAudioOutputResampler); |
228 | 233 |
229 // Update the playout latency. | 234 // Update the playout latency. |
230 double playout_latency_frames = GetPlayoutLatency(output_time_stamp); | 235 double playout_latency_frames = GetPlayoutLatency(output_time_stamp); |
231 | 236 |
232 AudioBuffer& buffer = io_data->mBuffers[0]; | 237 AudioBuffer& buffer = io_data->mBuffers[0]; |
233 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); | 238 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); |
234 uint32 hardware_pending_bytes = static_cast<uint32> | 239 uint32 hardware_pending_bytes = static_cast<uint32> |
235 ((playout_latency_frames + 0.5) * format_.mBytesPerFrame); | 240 ((playout_latency_frames + 0.5) * format_.mBytesPerFrame); |
236 | 241 |
237 // If we specify a buffer size which is too low, the OS will ask for more data | 242 // Unfortunately AUAudioInputStream and AUAudioOutputStream share the frame |
Chris Rogers
2012/10/08 21:08:26
nit: "frame frame"
DaleCurtis
2012/10/08 21:17:34
Done.
| |
238 // to fulfill the hardware request, so resize the AudioBus as appropriate. | 243 // frame size set by kAudioDevicePropertyBufferFrameSize above on a per |
239 // This change requires AudioOutputResampler to prevent buffer size mismatches | 244 // process basis. What this means is that the |number_of_frames| value may |
240 // downstream, so glitch if it's not enabled. | 245 // be larger or smaller than the value set during Configure(). The downstream |
241 if (!kDisableAudioOutputResampler && | 246 // audio pipeline does not support dynamic frame size changes, as such we must |
242 static_cast<UInt32>(audio_bus_->frames()) != number_of_frames) { | 247 // clip |frames_filled| as necessary, this will result in bad audio, but the |
243 audio_bus_ = AudioBus::Create(audio_bus_->channels(), number_of_frames); | 248 // alternative is a browser crash. |
244 } | 249 // TODO(henrika): This should never happen so long as we're always using the |
245 | 250 // hardware sample rate and the input/output streams configure the same frame |
251 // size. This is currently not true. See http://crbug.com/154352. Once | |
252 // fixed, a CHECK() should be added and the clipping + wall of text removed. | |
Chris Rogers
2012/10/08 21:08:26
Don't we still want to check for (audio_bus_->fram
DaleCurtis
2012/10/08 21:17:34
Things are already broken so it doesn't really mat
| |
246 int frames_filled = std::min(source_->OnMoreData( | 253 int frames_filled = std::min(source_->OnMoreData( |
247 audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)), | 254 audio_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)), |
248 static_cast<int>(number_of_frames)); | 255 static_cast<int>(number_of_frames)); |
256 | |
249 // Note: If this ever changes to output raw float the data must be clipped and | 257 // Note: If this ever changes to output raw float the data must be clipped and |
250 // sanitized since it may come from an untrusted source such as NaCl. | 258 // sanitized since it may come from an untrusted source such as NaCl. |
251 audio_bus_->ToInterleaved( | 259 audio_bus_->ToInterleaved( |
252 frames_filled, format_.mBitsPerChannel / 8, audio_data); | 260 frames_filled, format_.mBitsPerChannel / 8, audio_data); |
253 uint32 filled = frames_filled * format_.mBytesPerFrame; | 261 uint32 filled = frames_filled * format_.mBytesPerFrame; |
254 | 262 |
255 // Handle channel order for 5.1 audio. | 263 // Handle channel order for 5.1 audio. |
256 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; | 264 // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; |
257 // volume adjust should use SSE optimized vector_fmul() prior to interleave. | 265 // volume adjust should use SSE optimized vector_fmul() prior to interleave. |
258 if (format_.mChannelsPerFrame == 6) { | 266 if (format_.mChannelsPerFrame == 6) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 UInt64 output_time_ns = AudioConvertHostTimeToNanos( | 379 UInt64 output_time_ns = AudioConvertHostTimeToNanos( |
372 output_time_stamp->mHostTime); | 380 output_time_stamp->mHostTime); |
373 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); | 381 UInt64 now_ns = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); |
374 double delay_frames = static_cast<double> | 382 double delay_frames = static_cast<double> |
375 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate); | 383 (1e-9 * (output_time_ns - now_ns) * format_.mSampleRate); |
376 | 384 |
377 return (delay_frames + hardware_latency_frames_); | 385 return (delay_frames + hardware_latency_frames_); |
378 } | 386 } |
379 | 387 |
380 } // namespace media | 388 } // namespace media |
OLD | NEW |