| 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 <algorithm> | 9 #include <algorithm> |
| 10 #include <cstddef> | 10 #include <cstddef> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 AudioBus* bus, | 53 AudioBus* bus, |
| 54 int frames) { | 54 int frames) { |
| 55 DCHECK(buffer_list); | 55 DCHECK(buffer_list); |
| 56 DCHECK(bus); | 56 DCHECK(bus); |
| 57 const int channels = bus->channels(); | 57 const int channels = bus->channels(); |
| 58 const int buffer_list_channels = buffer_list->mNumberBuffers; | 58 const int buffer_list_channels = buffer_list->mNumberBuffers; |
| 59 CHECK_EQ(channels, buffer_list_channels); | 59 CHECK_EQ(channels, buffer_list_channels); |
| 60 | 60 |
| 61 // Copy pointers from AudioBufferList. | 61 // Copy pointers from AudioBufferList. |
| 62 for (int i = 0; i < channels; ++i) { | 62 for (int i = 0; i < channels; ++i) { |
| 63 bus->SetChannelData( | 63 bus->SetChannelData(i, static_cast<float*>(buffer_list->mBuffers[i].mData)); |
| 64 i, static_cast<float*>(buffer_list->mBuffers[i].mData)); | |
| 65 } | 64 } |
| 66 | 65 |
| 67 // Finally set the actual length. | 66 // Finally set the actual length. |
| 68 bus->set_frames(frames); | 67 bus->set_frames(frames); |
| 69 } | 68 } |
| 70 | 69 |
| 71 AUHALStream::AUHALStream(AudioManagerMac* manager, | 70 AUHALStream::AUHALStream(AudioManagerMac* manager, |
| 72 const AudioParameters& params, | 71 const AudioParameters& params, |
| 73 AudioDeviceID device, | 72 AudioDeviceID device, |
| 74 const AudioManager::LogCallback& log_callback) | 73 const AudioManager::LogCallback& log_callback) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 return; | 150 return; |
| 152 } | 151 } |
| 153 | 152 |
| 154 // Check if we should defer Start() for http://crbug.com/160920. | 153 // Check if we should defer Start() for http://crbug.com/160920. |
| 155 if (manager_->ShouldDeferStreamStart()) { | 154 if (manager_->ShouldDeferStreamStart()) { |
| 156 // Use a cancellable closure so that if Stop() is called before Start() | 155 // Use a cancellable closure so that if Stop() is called before Start() |
| 157 // actually runs, we can cancel the pending start. | 156 // actually runs, we can cancel the pending start. |
| 158 deferred_start_cb_.Reset( | 157 deferred_start_cb_.Reset( |
| 159 base::Bind(&AUHALStream::Start, base::Unretained(this), callback)); | 158 base::Bind(&AUHALStream::Start, base::Unretained(this), callback)); |
| 160 manager_->GetTaskRunner()->PostDelayedTask( | 159 manager_->GetTaskRunner()->PostDelayedTask( |
| 161 FROM_HERE, deferred_start_cb_.callback(), base::TimeDelta::FromSeconds( | 160 FROM_HERE, deferred_start_cb_.callback(), |
| 161 base::TimeDelta::FromSeconds( |
| 162 AudioManagerMac::kStartDelayInSecsForPowerEvents)); | 162 AudioManagerMac::kStartDelayInSecsForPowerEvents)); |
| 163 return; | 163 return; |
| 164 } | 164 } |
| 165 | 165 |
| 166 stopped_ = false; | 166 stopped_ = false; |
| 167 audio_fifo_.reset(); | 167 audio_fifo_.reset(); |
| 168 { | 168 { |
| 169 base::AutoLock auto_lock(source_lock_); | 169 base::AutoLock auto_lock(source_lock_); |
| 170 source_ = callback; | 170 source_ = callback; |
| 171 } | 171 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 202 } | 202 } |
| 203 | 203 |
| 204 void AUHALStream::GetVolume(double* volume) { | 204 void AUHALStream::GetVolume(double* volume) { |
| 205 *volume = volume_; | 205 *volume = volume_; |
| 206 } | 206 } |
| 207 | 207 |
| 208 // Pulls on our provider to get rendered audio stream. | 208 // Pulls on our provider to get rendered audio stream. |
| 209 // Note to future hackers of this function: Do not add locks which can | 209 // Note to future hackers of this function: Do not add locks which can |
| 210 // be contended in the middle of stream processing here (starting and stopping | 210 // be contended in the middle of stream processing here (starting and stopping |
| 211 // the stream are ok) because this is running on a real-time thread. | 211 // the stream are ok) because this is running on a real-time thread. |
| 212 OSStatus AUHALStream::Render( | 212 OSStatus AUHALStream::Render(AudioUnitRenderActionFlags* flags, |
| 213 AudioUnitRenderActionFlags* flags, | 213 const AudioTimeStamp* output_time_stamp, |
| 214 const AudioTimeStamp* output_time_stamp, | 214 UInt32 bus_number, |
| 215 UInt32 bus_number, | 215 UInt32 number_of_frames, |
| 216 UInt32 number_of_frames, | 216 AudioBufferList* data) { |
| 217 AudioBufferList* data) { | |
| 218 TRACE_EVENT2("audio", "AUHALStream::Render", "input buffer size", | 217 TRACE_EVENT2("audio", "AUHALStream::Render", "input buffer size", |
| 219 number_of_frames_, "output buffer size", number_of_frames); | 218 number_of_frames_, "output buffer size", number_of_frames); |
| 220 | 219 |
| 221 UpdatePlayoutTimestamp(output_time_stamp); | 220 UpdatePlayoutTimestamp(output_time_stamp); |
| 222 | 221 |
| 223 // If the stream parameters change for any reason, we need to insert a FIFO | 222 // If the stream parameters change for any reason, we need to insert a FIFO |
| 224 // since the OnMoreData() pipeline can't handle frame size changes. | 223 // since the OnMoreData() pipeline can't handle frame size changes. |
| 225 if (number_of_frames != number_of_frames_) { | 224 if (number_of_frames != number_of_frames_) { |
| 226 // Create a FIFO on the fly to handle any discrepancies in callback rates. | 225 // Create a FIFO on the fly to handle any discrepancies in callback rates. |
| 227 if (!audio_fifo_) { | 226 if (!audio_fifo_) { |
| 228 // TODO(grunell): We'll only care about the first buffer size change, | 227 // TODO(grunell): We'll only care about the first buffer size change, |
| 229 // any further changes will be ignored. It would be nice to have all | 228 // any further changes will be ignored. It would be nice to have all |
| 230 // changes reflected in UMA stats. | 229 // changes reflected in UMA stats. |
| 231 number_of_frames_requested_ = number_of_frames; | 230 number_of_frames_requested_ = number_of_frames; |
| 232 DVLOG(1) << "Audio frame size changed from " << number_of_frames_ | 231 DVLOG(1) << "Audio frame size changed from " << number_of_frames_ |
| 233 << " to " << number_of_frames << " adding FIFO to compensate."; | 232 << " to " << number_of_frames << " adding FIFO to compensate."; |
| 234 audio_fifo_.reset(new AudioPullFifo( | 233 audio_fifo_.reset(new AudioPullFifo( |
| 235 output_channels_, | 234 output_channels_, number_of_frames_, |
| 236 number_of_frames_, | |
| 237 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this)))); | 235 base::Bind(&AUHALStream::ProvideInput, base::Unretained(this)))); |
| 238 } | 236 } |
| 239 } | 237 } |
| 240 | 238 |
| 241 // Make |output_bus_| wrap the output AudioBufferList. | 239 // Make |output_bus_| wrap the output AudioBufferList. |
| 242 WrapBufferList(data, output_bus_.get(), number_of_frames); | 240 WrapBufferList(data, output_bus_.get(), number_of_frames); |
| 243 | 241 |
| 244 current_playout_time_ = GetPlayoutTime(output_time_stamp); | 242 current_playout_time_ = GetPlayoutTime(output_time_stamp); |
| 245 | 243 |
| 246 if (audio_fifo_) | 244 if (audio_fifo_) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 266 const base::TimeTicks now = base::TimeTicks::Now(); | 264 const base::TimeTicks now = base::TimeTicks::Now(); |
| 267 const base::TimeDelta delay = playout_time - now; | 265 const base::TimeDelta delay = playout_time - now; |
| 268 | 266 |
| 269 // Supply the input data and render the output data. | 267 // Supply the input data and render the output data. |
| 270 source_->OnMoreData(delay, now, current_lost_frames_, dest); | 268 source_->OnMoreData(delay, now, current_lost_frames_, dest); |
| 271 dest->Scale(volume_); | 269 dest->Scale(volume_); |
| 272 current_lost_frames_ = 0; | 270 current_lost_frames_ = 0; |
| 273 } | 271 } |
| 274 | 272 |
| 275 // AUHAL callback. | 273 // AUHAL callback. |
| 276 OSStatus AUHALStream::InputProc( | 274 OSStatus AUHALStream::InputProc(void* user_data, |
| 277 void* user_data, | 275 AudioUnitRenderActionFlags* flags, |
| 278 AudioUnitRenderActionFlags* flags, | 276 const AudioTimeStamp* output_time_stamp, |
| 279 const AudioTimeStamp* output_time_stamp, | 277 UInt32 bus_number, |
| 280 UInt32 bus_number, | 278 UInt32 number_of_frames, |
| 281 UInt32 number_of_frames, | 279 AudioBufferList* io_data) { |
| 282 AudioBufferList* io_data) { | |
| 283 // Dispatch to our class method. | 280 // Dispatch to our class method. |
| 284 AUHALStream* audio_output = | 281 AUHALStream* audio_output = static_cast<AUHALStream*>(user_data); |
| 285 static_cast<AUHALStream*>(user_data); | |
| 286 if (!audio_output) | 282 if (!audio_output) |
| 287 return -1; | 283 return -1; |
| 288 | 284 |
| 289 return audio_output->Render( | 285 return audio_output->Render(flags, output_time_stamp, bus_number, |
| 290 flags, | 286 number_of_frames, io_data); |
| 291 output_time_stamp, | |
| 292 bus_number, | |
| 293 number_of_frames, | |
| 294 io_data); | |
| 295 } | 287 } |
| 296 | 288 |
| 297 base::TimeDelta AUHALStream::GetHardwareLatency() { | 289 base::TimeDelta AUHALStream::GetHardwareLatency() { |
| 298 if (!audio_unit_ || device_ == kAudioObjectUnknown) { | 290 if (!audio_unit_ || device_ == kAudioObjectUnknown) { |
| 299 DLOG(WARNING) << "AudioUnit is NULL or device ID is unknown"; | 291 DLOG(WARNING) << "AudioUnit is NULL or device ID is unknown"; |
| 300 return base::TimeDelta(); | 292 return base::TimeDelta(); |
| 301 } | 293 } |
| 302 | 294 |
| 303 // Get audio unit latency. | 295 // Get audio unit latency. |
| 304 Float64 audio_unit_latency_sec = 0.0; | 296 Float64 audio_unit_latency_sec = 0.0; |
| 305 UInt32 size = sizeof(audio_unit_latency_sec); | 297 UInt32 size = sizeof(audio_unit_latency_sec); |
| 306 OSStatus result = AudioUnitGetProperty( | 298 OSStatus result = AudioUnitGetProperty( |
| 307 audio_unit_, | 299 audio_unit_, kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, |
| 308 kAudioUnitProperty_Latency, | 300 &audio_unit_latency_sec, &size); |
| 309 kAudioUnitScope_Global, | |
| 310 0, | |
| 311 &audio_unit_latency_sec, | |
| 312 &size); | |
| 313 if (result != noErr) { | 301 if (result != noErr) { |
| 314 OSSTATUS_DLOG(WARNING, result) << "Could not get AudioUnit latency"; | 302 OSSTATUS_DLOG(WARNING, result) << "Could not get AudioUnit latency"; |
| 315 return base::TimeDelta(); | 303 return base::TimeDelta(); |
| 316 } | 304 } |
| 317 | 305 |
| 318 // Get output audio device latency. | 306 // Get output audio device latency. |
| 319 static const AudioObjectPropertyAddress property_address = { | 307 static const AudioObjectPropertyAddress property_address = { |
| 320 kAudioDevicePropertyLatency, | 308 kAudioDevicePropertyLatency, kAudioDevicePropertyScopeOutput, |
| 321 kAudioDevicePropertyScopeOutput, | 309 kAudioObjectPropertyElementMaster}; |
| 322 kAudioObjectPropertyElementMaster | |
| 323 }; | |
| 324 | 310 |
| 325 UInt32 device_latency_frames = 0; | 311 UInt32 device_latency_frames = 0; |
| 326 size = sizeof(device_latency_frames); | 312 size = sizeof(device_latency_frames); |
| 327 result = AudioObjectGetPropertyData( | 313 result = AudioObjectGetPropertyData(device_, &property_address, 0, NULL, |
| 328 device_, | 314 &size, &device_latency_frames); |
| 329 &property_address, | |
| 330 0, | |
| 331 NULL, | |
| 332 &size, | |
| 333 &device_latency_frames); | |
| 334 if (result != noErr) { | 315 if (result != noErr) { |
| 335 OSSTATUS_DLOG(WARNING, result) << "Could not get audio device latency"; | 316 OSSTATUS_DLOG(WARNING, result) << "Could not get audio device latency"; |
| 336 return base::TimeDelta(); | 317 return base::TimeDelta(); |
| 337 } | 318 } |
| 338 | 319 |
| 339 int latency_frames = audio_unit_latency_sec * output_format_.mSampleRate + | 320 int latency_frames = audio_unit_latency_sec * output_format_.mSampleRate + |
| 340 device_latency_frames; | 321 device_latency_frames; |
| 341 | 322 |
| 342 return AudioTimestampHelper::FramesToTime(latency_frames, | 323 return AudioTimestampHelper::FramesToTime(latency_frames, |
| 343 params_.sample_rate()); | 324 params_.sample_rate()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 } | 392 } |
| 412 | 393 |
| 413 number_of_frames_requested_ = 0; | 394 number_of_frames_requested_ = 0; |
| 414 glitches_detected_ = 0; | 395 glitches_detected_ = 0; |
| 415 last_sample_time_ = 0; | 396 last_sample_time_ = 0; |
| 416 last_number_of_frames_ = 0; | 397 last_number_of_frames_ = 0; |
| 417 total_lost_frames_ = 0; | 398 total_lost_frames_ = 0; |
| 418 largest_glitch_frames_ = 0; | 399 largest_glitch_frames_ = 0; |
| 419 } | 400 } |
| 420 | 401 |
| 421 bool AUHALStream::SetStreamFormat( | 402 bool AUHALStream::SetStreamFormat(AudioStreamBasicDescription* desc, |
| 422 AudioStreamBasicDescription* desc, | 403 int channels, |
| 423 int channels, | 404 UInt32 scope, |
| 424 UInt32 scope, | 405 UInt32 element) { |
| 425 UInt32 element) { | |
| 426 DCHECK(desc); | 406 DCHECK(desc); |
| 427 AudioStreamBasicDescription& format = *desc; | 407 AudioStreamBasicDescription& format = *desc; |
| 428 | 408 |
| 429 format.mSampleRate = params_.sample_rate(); | 409 format.mSampleRate = params_.sample_rate(); |
| 430 format.mFormatID = kAudioFormatLinearPCM; | 410 format.mFormatID = kAudioFormatLinearPCM; |
| 431 format.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | | 411 format.mFormatFlags = |
| 432 kLinearPCMFormatFlagIsNonInterleaved; | 412 kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; |
| 433 format.mBytesPerPacket = sizeof(Float32); | 413 format.mBytesPerPacket = sizeof(Float32); |
| 434 format.mFramesPerPacket = 1; | 414 format.mFramesPerPacket = 1; |
| 435 format.mBytesPerFrame = sizeof(Float32); | 415 format.mBytesPerFrame = sizeof(Float32); |
| 436 format.mChannelsPerFrame = channels; | 416 format.mChannelsPerFrame = channels; |
| 437 format.mBitsPerChannel = 32; | 417 format.mBitsPerChannel = 32; |
| 438 format.mReserved = 0; | 418 format.mReserved = 0; |
| 439 | 419 |
| 440 OSStatus result = AudioUnitSetProperty( | 420 OSStatus result = |
| 441 audio_unit_, | 421 AudioUnitSetProperty(audio_unit_, kAudioUnitProperty_StreamFormat, scope, |
| 442 kAudioUnitProperty_StreamFormat, | 422 element, &format, sizeof(format)); |
| 443 scope, | |
| 444 element, | |
| 445 &format, | |
| 446 sizeof(format)); | |
| 447 return (result == noErr); | 423 return (result == noErr); |
| 448 } | 424 } |
| 449 | 425 |
| 450 bool AUHALStream::ConfigureAUHAL() { | 426 bool AUHALStream::ConfigureAUHAL() { |
| 451 DCHECK(thread_checker_.CalledOnValidThread()); | 427 DCHECK(thread_checker_.CalledOnValidThread()); |
| 452 if (device_ == kAudioObjectUnknown || output_channels_ == 0) | 428 if (device_ == kAudioObjectUnknown || output_channels_ == 0) |
| 453 return false; | 429 return false; |
| 454 | 430 |
| 455 AudioComponentDescription desc = { | 431 AudioComponentDescription desc = {kAudioUnitType_Output, |
| 456 kAudioUnitType_Output, | 432 kAudioUnitSubType_HALOutput, |
| 457 kAudioUnitSubType_HALOutput, | 433 kAudioUnitManufacturer_Apple, 0, 0}; |
| 458 kAudioUnitManufacturer_Apple, | |
| 459 0, | |
| 460 0 | |
| 461 }; | |
| 462 AudioComponent comp = AudioComponentFindNext(0, &desc); | 434 AudioComponent comp = AudioComponentFindNext(0, &desc); |
| 463 if (!comp) | 435 if (!comp) |
| 464 return false; | 436 return false; |
| 465 | 437 |
| 466 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); | 438 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); |
| 467 if (result != noErr) { | 439 if (result != noErr) { |
| 468 OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; | 440 OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; |
| 469 return false; | 441 return false; |
| 470 } | 442 } |
| 471 | 443 |
| 472 // Enable output as appropriate. | 444 // Enable output as appropriate. |
| 473 // See Apple technote for details about the EnableIO property. | 445 // See Apple technote for details about the EnableIO property. |
| 474 // Note that we use bus 1 for input and bus 0 for output: | 446 // Note that we use bus 1 for input and bus 0 for output: |
| 475 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 447 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 476 UInt32 enable_IO = 1; | 448 UInt32 enable_IO = 1; |
| 477 result = AudioUnitSetProperty( | 449 result = AudioUnitSetProperty(audio_unit_, kAudioOutputUnitProperty_EnableIO, |
| 478 audio_unit_, | 450 kAudioUnitScope_Output, 0, &enable_IO, |
| 479 kAudioOutputUnitProperty_EnableIO, | 451 sizeof(enable_IO)); |
| 480 kAudioUnitScope_Output, | |
| 481 0, | |
| 482 &enable_IO, | |
| 483 sizeof(enable_IO)); | |
| 484 if (result != noErr) { | 452 if (result != noErr) { |
| 485 CloseAudioUnit(); | 453 CloseAudioUnit(); |
| 486 return false; | 454 return false; |
| 487 } | 455 } |
| 488 | 456 |
| 489 // Set the device to be used with the AUHAL AudioUnit. | 457 // Set the device to be used with the AUHAL AudioUnit. |
| 490 result = AudioUnitSetProperty( | 458 result = AudioUnitSetProperty( |
| 491 audio_unit_, | 459 audio_unit_, kAudioOutputUnitProperty_CurrentDevice, |
| 492 kAudioOutputUnitProperty_CurrentDevice, | 460 kAudioUnitScope_Global, 0, &device_, sizeof(AudioDeviceID)); |
| 493 kAudioUnitScope_Global, | |
| 494 0, | |
| 495 &device_, | |
| 496 sizeof(AudioDeviceID)); | |
| 497 if (result != noErr) { | 461 if (result != noErr) { |
| 498 CloseAudioUnit(); | 462 CloseAudioUnit(); |
| 499 return false; | 463 return false; |
| 500 } | 464 } |
| 501 | 465 |
| 502 // Set stream formats. | 466 // Set stream formats. |
| 503 // See Apple's tech note for details on the peculiar way that | 467 // See Apple's tech note for details on the peculiar way that |
| 504 // inputs and outputs are handled in the AUHAL concerning scope and bus | 468 // inputs and outputs are handled in the AUHAL concerning scope and bus |
| 505 // (element) numbers: | 469 // (element) numbers: |
| 506 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 470 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 507 | 471 |
| 508 if (!SetStreamFormat(&output_format_, | 472 if (!SetStreamFormat(&output_format_, output_channels_, kAudioUnitScope_Input, |
| 509 output_channels_, | |
| 510 kAudioUnitScope_Input, | |
| 511 0)) { | 473 0)) { |
| 512 CloseAudioUnit(); | 474 CloseAudioUnit(); |
| 513 return false; | 475 return false; |
| 514 } | 476 } |
| 515 | 477 |
| 516 bool size_was_changed = false; | 478 bool size_was_changed = false; |
| 517 size_t io_buffer_frame_size = 0; | 479 size_t io_buffer_frame_size = 0; |
| 518 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0, | 480 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0, |
| 519 number_of_frames_, &size_was_changed, | 481 number_of_frames_, &size_was_changed, |
| 520 &io_buffer_frame_size)) { | 482 &io_buffer_frame_size)) { |
| 521 CloseAudioUnit(); | 483 CloseAudioUnit(); |
| 522 return false; | 484 return false; |
| 523 } | 485 } |
| 524 | 486 |
| 525 // Setup callback. | 487 // Setup callback. |
| 526 AURenderCallbackStruct callback; | 488 AURenderCallbackStruct callback; |
| 527 callback.inputProc = InputProc; | 489 callback.inputProc = InputProc; |
| 528 callback.inputProcRefCon = this; | 490 callback.inputProcRefCon = this; |
| 529 result = AudioUnitSetProperty( | 491 result = AudioUnitSetProperty( |
| 530 audio_unit_, | 492 audio_unit_, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, |
| 531 kAudioUnitProperty_SetRenderCallback, | 493 0, &callback, sizeof(callback)); |
| 532 kAudioUnitScope_Input, | |
| 533 0, | |
| 534 &callback, | |
| 535 sizeof(callback)); | |
| 536 if (result != noErr) { | 494 if (result != noErr) { |
| 537 CloseAudioUnit(); | 495 CloseAudioUnit(); |
| 538 return false; | 496 return false; |
| 539 } | 497 } |
| 540 | 498 |
| 541 SetAudioChannelLayout(); | 499 SetAudioChannelLayout(); |
| 542 | 500 |
| 543 result = AudioUnitInitialize(audio_unit_); | 501 result = AudioUnitInitialize(audio_unit_); |
| 544 if (result != noErr) { | 502 if (result != noErr) { |
| 545 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; | 503 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 OSStatus result = AudioUnitSetProperty( | 571 OSStatus result = AudioUnitSetProperty( |
| 614 audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, | 572 audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, |
| 615 0, channel_layout, layout_size); | 573 0, channel_layout, layout_size); |
| 616 if (result != noErr) { | 574 if (result != noErr) { |
| 617 OSSTATUS_DLOG(ERROR, result) | 575 OSSTATUS_DLOG(ERROR, result) |
| 618 << "Failed to set audio channel layout. Using default layout."; | 576 << "Failed to set audio channel layout. Using default layout."; |
| 619 } | 577 } |
| 620 } | 578 } |
| 621 | 579 |
| 622 } // namespace media | 580 } // namespace media |
| OLD | NEW |