OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_auhal_mac.h" | 5 #include "media/audio/mac/audio_auhal_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/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/mac/mac_logging.h" | 14 #include "base/mac/mac_logging.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
16 #include "media/audio/mac/audio_manager_mac.h" | 16 #include "media/audio/mac/audio_manager_mac.h" |
17 #include "media/base/audio_pull_fifo.h" | 17 #include "media/base/audio_pull_fifo.h" |
18 | 18 |
19 namespace media { | 19 namespace media { |
20 | 20 |
21 static void ZeroBufferList(AudioBufferList* buffer_list) { | |
22 for (size_t i = 0; i < buffer_list->mNumberBuffers; ++i) { | |
23 memset(buffer_list->mBuffers[i].mData, | |
24 0, | |
25 buffer_list->mBuffers[i].mDataByteSize); | |
26 } | |
27 } | |
28 | |
29 static void WrapBufferList(AudioBufferList* buffer_list, | 21 static void WrapBufferList(AudioBufferList* buffer_list, |
30 AudioBus* bus, | 22 AudioBus* bus, |
31 int frames) { | 23 int frames) { |
32 DCHECK(buffer_list); | 24 DCHECK(buffer_list); |
33 DCHECK(bus); | 25 DCHECK(bus); |
34 const int channels = bus->channels(); | 26 const int channels = bus->channels(); |
35 const int buffer_list_channels = buffer_list->mNumberBuffers; | 27 const int buffer_list_channels = buffer_list->mNumberBuffers; |
36 CHECK_EQ(channels, buffer_list_channels); | 28 CHECK_EQ(channels, buffer_list_channels); |
37 | 29 |
38 // Copy pointers from AudioBufferList. | 30 // Copy pointers from AudioBufferList. |
39 for (int i = 0; i < channels; ++i) { | 31 for (int i = 0; i < channels; ++i) { |
40 bus->SetChannelData( | 32 bus->SetChannelData( |
41 i, static_cast<float*>(buffer_list->mBuffers[i].mData)); | 33 i, static_cast<float*>(buffer_list->mBuffers[i].mData)); |
42 } | 34 } |
43 | 35 |
44 // Finally set the actual length. | 36 // Finally set the actual length. |
45 bus->set_frames(frames); | 37 bus->set_frames(frames); |
46 } | 38 } |
47 | 39 |
48 AUHALStream::AUHALStream( | 40 AUHALStream::AUHALStream( |
49 AudioManagerMac* manager, | 41 AudioManagerMac* manager, |
50 const AudioParameters& params, | 42 const AudioParameters& params, |
51 AudioDeviceID device) | 43 AudioDeviceID device) |
52 : manager_(manager), | 44 : manager_(manager), |
53 params_(params), | 45 params_(params), |
54 input_channels_(params_.input_channels()), | |
55 output_channels_(params_.channels()), | 46 output_channels_(params_.channels()), |
56 number_of_frames_(params_.frames_per_buffer()), | 47 number_of_frames_(params_.frames_per_buffer()), |
57 source_(NULL), | 48 source_(NULL), |
58 device_(device), | 49 device_(device), |
59 audio_unit_(0), | 50 audio_unit_(0), |
60 volume_(1), | 51 volume_(1), |
61 hardware_latency_frames_(0), | 52 hardware_latency_frames_(0), |
62 stopped_(false), | 53 stopped_(false), |
63 input_buffer_list_(NULL), | |
64 current_hardware_pending_bytes_(0) { | 54 current_hardware_pending_bytes_(0) { |
65 // We must have a manager. | 55 // We must have a manager. |
66 DCHECK(manager_); | 56 DCHECK(manager_); |
67 | 57 |
68 VLOG(1) << "AUHALStream::AUHALStream()"; | 58 VLOG(1) << "AUHALStream::AUHALStream()"; |
69 VLOG(1) << "Device: " << device; | 59 VLOG(1) << "Device: " << device; |
70 VLOG(1) << "Input channels: " << input_channels_; | |
71 VLOG(1) << "Output channels: " << output_channels_; | 60 VLOG(1) << "Output channels: " << output_channels_; |
72 VLOG(1) << "Sample rate: " << params_.sample_rate(); | 61 VLOG(1) << "Sample rate: " << params_.sample_rate(); |
73 VLOG(1) << "Buffer size: " << number_of_frames_; | 62 VLOG(1) << "Buffer size: " << number_of_frames_; |
74 } | 63 } |
75 | 64 |
76 AUHALStream::~AUHALStream() { | 65 AUHALStream::~AUHALStream() { |
77 } | 66 } |
78 | 67 |
79 bool AUHALStream::Open() { | 68 bool AUHALStream::Open() { |
80 // Get the total number of input and output channels that the | 69 // Get the total number of output channels that the |
81 // hardware supports. | 70 // hardware supports. |
82 int device_input_channels; | |
83 bool got_input_channels = AudioManagerMac::GetDeviceChannels( | |
84 device_, | |
85 kAudioDevicePropertyScopeInput, | |
86 &device_input_channels); | |
87 | |
88 int device_output_channels; | 71 int device_output_channels; |
89 bool got_output_channels = AudioManagerMac::GetDeviceChannels( | 72 bool got_output_channels = AudioManagerMac::GetDeviceChannels( |
90 device_, | 73 device_, |
91 kAudioDevicePropertyScopeOutput, | 74 kAudioDevicePropertyScopeOutput, |
92 &device_output_channels); | 75 &device_output_channels); |
93 | 76 |
94 // Sanity check the requested I/O channels. | 77 // Sanity check the requested output channels. |
95 if (!got_input_channels || | |
96 input_channels_ < 0 || input_channels_ > device_input_channels) { | |
97 LOG(ERROR) << "AudioDevice does not support requested input channels."; | |
98 return false; | |
99 } | |
100 | |
101 if (!got_output_channels || | 78 if (!got_output_channels || |
102 output_channels_ <= 0 || output_channels_ > device_output_channels) { | 79 output_channels_ <= 0 || output_channels_ > device_output_channels) { |
103 LOG(ERROR) << "AudioDevice does not support requested output channels."; | 80 LOG(ERROR) << "AudioDevice does not support requested output channels."; |
104 return false; | 81 return false; |
105 } | 82 } |
106 | 83 |
107 // The requested sample-rate must match the hardware sample-rate. | 84 // The requested sample-rate must match the hardware sample-rate. |
108 int sample_rate = AudioManagerMac::HardwareSampleRateForDevice(device_); | 85 int sample_rate = AudioManagerMac::HardwareSampleRateForDevice(device_); |
109 | 86 |
110 if (sample_rate != params_.sample_rate()) { | 87 if (sample_rate != params_.sample_rate()) { |
111 LOG(ERROR) << "Requested sample-rate: " << params_.sample_rate() | 88 LOG(ERROR) << "Requested sample-rate: " << params_.sample_rate() |
112 << " must match the hardware sample-rate: " << sample_rate; | 89 << " must match the hardware sample-rate: " << sample_rate; |
113 return false; | 90 return false; |
114 } | 91 } |
115 | 92 |
116 CreateIOBusses(); | 93 // The output bus will wrap the AudioBufferList given to us in |
| 94 // the Render() callback. |
| 95 DCHECK_GT(output_channels_, 0); |
| 96 output_bus_ = AudioBus::CreateWrapper(output_channels_); |
117 | 97 |
118 bool configured = ConfigureAUHAL(); | 98 bool configured = ConfigureAUHAL(); |
119 if (configured) | 99 if (configured) |
120 hardware_latency_frames_ = GetHardwareLatency(); | 100 hardware_latency_frames_ = GetHardwareLatency(); |
121 | 101 |
122 return configured; | 102 return configured; |
123 } | 103 } |
124 | 104 |
125 void AUHALStream::Close() { | 105 void AUHALStream::Close() { |
126 if (input_buffer_list_) { | |
127 input_buffer_list_storage_.reset(); | |
128 input_buffer_list_ = NULL; | |
129 input_bus_.reset(NULL); | |
130 output_bus_.reset(NULL); | |
131 } | |
132 | |
133 if (audio_unit_) { | 106 if (audio_unit_) { |
134 OSStatus result = AudioUnitUninitialize(audio_unit_); | 107 OSStatus result = AudioUnitUninitialize(audio_unit_); |
135 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) | 108 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) |
136 << "AudioUnitUninitialize() failed."; | 109 << "AudioUnitUninitialize() failed."; |
137 result = AudioComponentInstanceDispose(audio_unit_); | 110 result = AudioComponentInstanceDispose(audio_unit_); |
138 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) | 111 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) |
139 << "AudioComponentInstanceDispose() failed."; | 112 << "AudioComponentInstanceDispose() failed."; |
140 } | 113 } |
141 | 114 |
142 // Inform the audio manager that we have been closed. This will cause our | 115 // Inform the audio manager that we have been closed. This will cause our |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 178 |
206 // Pulls on our provider to get rendered audio stream. | 179 // Pulls on our provider to get rendered audio stream. |
207 // Note to future hackers of this function: Do not add locks which can | 180 // Note to future hackers of this function: Do not add locks which can |
208 // be contended in the middle of stream processing here (starting and stopping | 181 // be contended in the middle of stream processing here (starting and stopping |
209 // the stream are ok) because this is running on a real-time thread. | 182 // the stream are ok) because this is running on a real-time thread. |
210 OSStatus AUHALStream::Render( | 183 OSStatus AUHALStream::Render( |
211 AudioUnitRenderActionFlags* flags, | 184 AudioUnitRenderActionFlags* flags, |
212 const AudioTimeStamp* output_time_stamp, | 185 const AudioTimeStamp* output_time_stamp, |
213 UInt32 bus_number, | 186 UInt32 bus_number, |
214 UInt32 number_of_frames, | 187 UInt32 number_of_frames, |
215 AudioBufferList* io_data) { | 188 AudioBufferList* data) { |
216 TRACE_EVENT0("audio", "AUHALStream::Render"); | 189 TRACE_EVENT0("audio", "AUHALStream::Render"); |
217 | 190 |
218 // If the stream parameters change for any reason, we need to insert a FIFO | 191 // If the stream parameters change for any reason, we need to insert a FIFO |
219 // since the OnMoreData() pipeline can't handle frame size changes. | 192 // since the OnMoreData() pipeline can't handle frame size changes. |
220 if (number_of_frames != number_of_frames_) { | 193 if (number_of_frames != number_of_frames_) { |
221 // Create a FIFO on the fly to handle any discrepancies in callback rates. | 194 // Create a FIFO on the fly to handle any discrepancies in callback rates. |
222 if (!audio_fifo_) { | 195 if (!audio_fifo_) { |
223 VLOG(1) << "Audio frame size changed from " << number_of_frames_ << " to " | 196 VLOG(1) << "Audio frame size changed from " << number_of_frames_ << " to " |
224 << number_of_frames << "; adding FIFO to compensate."; | 197 << number_of_frames << "; adding FIFO to compensate."; |
225 audio_fifo_.reset(new AudioPullFifo( | 198 audio_fifo_.reset(new AudioPullFifo( |
226 output_channels_, | 199 output_channels_, |
227 number_of_frames_, | 200 number_of_frames_, |
228 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this)))); | 201 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this)))); |
229 } | 202 } |
230 | |
231 // Synchronous IO is not supported in this state. | |
232 if (input_channels_ > 0) | |
233 input_bus_->Zero(); | |
234 } else { | |
235 if (input_channels_ > 0 && input_buffer_list_) { | |
236 // Get the input data. |input_buffer_list_| is wrapped | |
237 // to point to the data allocated in |input_bus_|. | |
238 OSStatus result = AudioUnitRender(audio_unit_, | |
239 flags, | |
240 output_time_stamp, | |
241 1, | |
242 number_of_frames, | |
243 input_buffer_list_); | |
244 if (result != noErr) | |
245 ZeroBufferList(input_buffer_list_); | |
246 } | |
247 } | 203 } |
248 | 204 |
249 // Make |output_bus_| wrap the output AudioBufferList. | 205 // Make |output_bus_| wrap the output AudioBufferList. |
250 WrapBufferList(io_data, output_bus_.get(), number_of_frames); | 206 WrapBufferList(data, output_bus_.get(), number_of_frames); |
251 | 207 |
252 // Update the playout latency. | 208 // Update the playout latency. |
253 const double playout_latency_frames = GetPlayoutLatency(output_time_stamp); | 209 const double playout_latency_frames = GetPlayoutLatency(output_time_stamp); |
254 current_hardware_pending_bytes_ = static_cast<uint32>( | 210 current_hardware_pending_bytes_ = static_cast<uint32>( |
255 (playout_latency_frames + 0.5) * params_.GetBytesPerFrame()); | 211 (playout_latency_frames + 0.5) * params_.GetBytesPerFrame()); |
256 | 212 |
257 if (audio_fifo_) | 213 if (audio_fifo_) |
258 audio_fifo_->Consume(output_bus_.get(), output_bus_->frames()); | 214 audio_fifo_->Consume(output_bus_.get(), output_bus_->frames()); |
259 else | 215 else |
260 ProvideInput(0, output_bus_.get()); | 216 ProvideInput(0, output_bus_.get()); |
261 | 217 |
262 return noErr; | 218 return noErr; |
263 } | 219 } |
264 | 220 |
265 void AUHALStream::ProvideInput(int frame_delay, AudioBus* dest) { | 221 void AUHALStream::ProvideInput(int frame_delay, AudioBus* dest) { |
266 base::AutoLock auto_lock(source_lock_); | 222 base::AutoLock auto_lock(source_lock_); |
267 if (!source_) { | 223 if (!source_) { |
268 dest->Zero(); | 224 dest->Zero(); |
269 return; | 225 return; |
270 } | 226 } |
271 | 227 |
272 // Supply the input data and render the output data. | 228 // Supply the input data and render the output data. |
273 source_->OnMoreIOData( | 229 source_->OnMoreData( |
274 input_bus_.get(), | |
275 dest, | 230 dest, |
276 AudioBuffersState(0, | 231 AudioBuffersState(0, |
277 current_hardware_pending_bytes_ + | 232 current_hardware_pending_bytes_ + |
278 frame_delay * params_.GetBytesPerFrame())); | 233 frame_delay * params_.GetBytesPerFrame())); |
279 dest->Scale(volume_); | 234 dest->Scale(volume_); |
280 } | 235 } |
281 | 236 |
282 // AUHAL callback. | 237 // AUHAL callback. |
283 OSStatus AUHALStream::InputProc( | 238 OSStatus AUHALStream::InputProc( |
284 void* user_data, | 239 void* user_data, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 // the bots, probably less so in the wild. | 318 // the bots, probably less so in the wild. |
364 if (now_ns > output_time_ns) | 319 if (now_ns > output_time_ns) |
365 return 0; | 320 return 0; |
366 | 321 |
367 double delay_frames = static_cast<double> | 322 double delay_frames = static_cast<double> |
368 (1e-9 * (output_time_ns - now_ns) * output_format_.mSampleRate); | 323 (1e-9 * (output_time_ns - now_ns) * output_format_.mSampleRate); |
369 | 324 |
370 return (delay_frames + hardware_latency_frames_); | 325 return (delay_frames + hardware_latency_frames_); |
371 } | 326 } |
372 | 327 |
373 void AUHALStream::CreateIOBusses() { | |
374 if (input_channels_ > 0) { | |
375 // Allocate storage for the AudioBufferList used for the | |
376 // input data from the input AudioUnit. | |
377 // We allocate enough space for with one AudioBuffer per channel. | |
378 size_t buffer_list_size = offsetof(AudioBufferList, mBuffers[0]) + | |
379 (sizeof(AudioBuffer) * input_channels_); | |
380 input_buffer_list_storage_.reset(new uint8[buffer_list_size]); | |
381 | |
382 input_buffer_list_ = | |
383 reinterpret_cast<AudioBufferList*>(input_buffer_list_storage_.get()); | |
384 input_buffer_list_->mNumberBuffers = input_channels_; | |
385 | |
386 // |input_bus_| allocates the storage for the PCM input data. | |
387 input_bus_ = AudioBus::Create(input_channels_, number_of_frames_); | |
388 | |
389 // Make the AudioBufferList point to the memory in |input_bus_|. | |
390 UInt32 buffer_size_bytes = input_bus_->frames() * sizeof(Float32); | |
391 for (size_t i = 0; i < input_buffer_list_->mNumberBuffers; ++i) { | |
392 input_buffer_list_->mBuffers[i].mNumberChannels = 1; | |
393 input_buffer_list_->mBuffers[i].mDataByteSize = buffer_size_bytes; | |
394 input_buffer_list_->mBuffers[i].mData = input_bus_->channel(i); | |
395 } | |
396 } | |
397 | |
398 // The output bus will wrap the AudioBufferList given to us in | |
399 // the Render() callback. | |
400 DCHECK_GT(output_channels_, 0); | |
401 output_bus_ = AudioBus::CreateWrapper(output_channels_); | |
402 } | |
403 | |
404 bool AUHALStream::EnableIO(bool enable, UInt32 scope) { | |
405 // See Apple technote for details about the EnableIO property. | |
406 // Note that we use bus 1 for input and bus 0 for output: | |
407 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | |
408 UInt32 enable_IO = enable ? 1 : 0; | |
409 OSStatus result = AudioUnitSetProperty( | |
410 audio_unit_, | |
411 kAudioOutputUnitProperty_EnableIO, | |
412 scope, | |
413 (scope == kAudioUnitScope_Input) ? 1 : 0, | |
414 &enable_IO, | |
415 sizeof(enable_IO)); | |
416 return (result == noErr); | |
417 } | |
418 | |
419 bool AUHALStream::SetStreamFormat( | 328 bool AUHALStream::SetStreamFormat( |
420 AudioStreamBasicDescription* desc, | 329 AudioStreamBasicDescription* desc, |
421 int channels, | 330 int channels, |
422 UInt32 scope, | 331 UInt32 scope, |
423 UInt32 element) { | 332 UInt32 element) { |
424 DCHECK(desc); | 333 DCHECK(desc); |
425 AudioStreamBasicDescription& format = *desc; | 334 AudioStreamBasicDescription& format = *desc; |
426 | 335 |
427 format.mSampleRate = params_.sample_rate(); | 336 format.mSampleRate = params_.sample_rate(); |
428 format.mFormatID = kAudioFormatLinearPCM; | 337 format.mFormatID = kAudioFormatLinearPCM; |
(...skipping 10 matching lines...) Expand all Loading... |
439 audio_unit_, | 348 audio_unit_, |
440 kAudioUnitProperty_StreamFormat, | 349 kAudioUnitProperty_StreamFormat, |
441 scope, | 350 scope, |
442 element, | 351 element, |
443 &format, | 352 &format, |
444 sizeof(format)); | 353 sizeof(format)); |
445 return (result == noErr); | 354 return (result == noErr); |
446 } | 355 } |
447 | 356 |
448 bool AUHALStream::ConfigureAUHAL() { | 357 bool AUHALStream::ConfigureAUHAL() { |
449 if (device_ == kAudioObjectUnknown || | 358 if (device_ == kAudioObjectUnknown || output_channels_ == 0) |
450 (input_channels_ == 0 && output_channels_ == 0)) | |
451 return false; | 359 return false; |
452 | 360 |
453 AudioComponentDescription desc = { | 361 AudioComponentDescription desc = { |
454 kAudioUnitType_Output, | 362 kAudioUnitType_Output, |
455 kAudioUnitSubType_HALOutput, | 363 kAudioUnitSubType_HALOutput, |
456 kAudioUnitManufacturer_Apple, | 364 kAudioUnitManufacturer_Apple, |
457 0, | 365 0, |
458 0 | 366 0 |
459 }; | 367 }; |
460 AudioComponent comp = AudioComponentFindNext(0, &desc); | 368 AudioComponent comp = AudioComponentFindNext(0, &desc); |
461 if (!comp) | 369 if (!comp) |
462 return false; | 370 return false; |
463 | 371 |
464 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); | 372 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); |
465 if (result != noErr) { | 373 if (result != noErr) { |
466 OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; | 374 OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; |
467 return false; | 375 return false; |
468 } | 376 } |
469 | 377 |
470 // Enable input and output as appropriate. | 378 // Enable output as appropriate. |
471 if (!EnableIO(input_channels_ > 0, kAudioUnitScope_Input)) | 379 // See Apple technote for details about the EnableIO property. |
472 return false; | 380 // Note that we use bus 1 for input and bus 0 for output: |
473 if (!EnableIO(output_channels_ > 0, kAudioUnitScope_Output)) | 381 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 382 UInt32 enable_IO = 1; |
| 383 result = AudioUnitSetProperty( |
| 384 audio_unit_, |
| 385 kAudioOutputUnitProperty_EnableIO, |
| 386 kAudioUnitScope_Output, |
| 387 0, |
| 388 &enable_IO, |
| 389 sizeof(enable_IO)); |
| 390 if (result != noErr) |
474 return false; | 391 return false; |
475 | 392 |
476 // Set the device to be used with the AUHAL AudioUnit. | 393 // Set the device to be used with the AUHAL AudioUnit. |
477 result = AudioUnitSetProperty( | 394 result = AudioUnitSetProperty( |
478 audio_unit_, | 395 audio_unit_, |
479 kAudioOutputUnitProperty_CurrentDevice, | 396 kAudioOutputUnitProperty_CurrentDevice, |
480 kAudioUnitScope_Global, | 397 kAudioUnitScope_Global, |
481 0, | 398 0, |
482 &device_, | 399 &device_, |
483 sizeof(AudioDeviceID)); | 400 sizeof(AudioDeviceID)); |
484 if (result != noErr) | 401 if (result != noErr) |
485 return false; | 402 return false; |
486 | 403 |
487 // Set stream formats. | 404 // Set stream formats. |
488 // See Apple's tech note for details on the peculiar way that | 405 // See Apple's tech note for details on the peculiar way that |
489 // inputs and outputs are handled in the AUHAL concerning scope and bus | 406 // inputs and outputs are handled in the AUHAL concerning scope and bus |
490 // (element) numbers: | 407 // (element) numbers: |
491 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 408 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
492 | 409 |
493 if (input_channels_ > 0) { | 410 if (!SetStreamFormat(&output_format_, |
494 if (!SetStreamFormat(&input_format_, | 411 output_channels_, |
495 input_channels_, | 412 kAudioUnitScope_Input, |
496 kAudioUnitScope_Output, | 413 0)) { |
497 1)) | 414 return false; |
498 return false; | |
499 } | |
500 | |
501 if (output_channels_ > 0) { | |
502 if (!SetStreamFormat(&output_format_, | |
503 output_channels_, | |
504 kAudioUnitScope_Input, | |
505 0)) | |
506 return false; | |
507 } | 415 } |
508 | 416 |
509 // Set the buffer frame size. | 417 // Set the buffer frame size. |
510 // WARNING: Setting this value changes the frame size for all output audio | 418 // WARNING: Setting this value changes the frame size for all output audio |
511 // units in the current process. As a result, the AURenderCallback must be | 419 // units in the current process. As a result, the AURenderCallback must be |
512 // able to handle arbitrary buffer sizes and FIFO appropriately. | 420 // able to handle arbitrary buffer sizes and FIFO appropriately. |
513 UInt32 buffer_size = 0; | 421 UInt32 buffer_size = 0; |
514 UInt32 property_size = sizeof(buffer_size); | 422 UInt32 property_size = sizeof(buffer_size); |
515 result = AudioUnitGetProperty(audio_unit_, | 423 result = AudioUnitGetProperty(audio_unit_, |
516 kAudioDevicePropertyBufferFrameSize, | 424 kAudioDevicePropertyBufferFrameSize, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 result = AudioUnitInitialize(audio_unit_); | 467 result = AudioUnitInitialize(audio_unit_); |
560 if (result != noErr) { | 468 if (result != noErr) { |
561 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; | 469 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; |
562 return false; | 470 return false; |
563 } | 471 } |
564 | 472 |
565 return true; | 473 return true; |
566 } | 474 } |
567 | 475 |
568 } // namespace media | 476 } // namespace media |
OLD | NEW |