| 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 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 format.mBitsPerChannel = 32; | 461 format.mBitsPerChannel = 32; |
| 462 format.mReserved = 0; | 462 format.mReserved = 0; |
| 463 | 463 |
| 464 OSStatus result = AudioUnitSetProperty( | 464 OSStatus result = AudioUnitSetProperty( |
| 465 audio_unit_, | 465 audio_unit_, |
| 466 kAudioUnitProperty_StreamFormat, | 466 kAudioUnitProperty_StreamFormat, |
| 467 scope, | 467 scope, |
| 468 element, | 468 element, |
| 469 &format, | 469 &format, |
| 470 sizeof(format)); | 470 sizeof(format)); |
| 471 OSSTATUS_LOG_IF(ERROR, result != noErr, result) << "Set StreamFormat failed."; |
| 471 return (result == noErr); | 472 return (result == noErr); |
| 472 } | 473 } |
| 473 | 474 |
| 474 bool AUHALStream::ConfigureAUHAL() { | 475 bool AUHALStream::ConfigureAUHAL() { |
| 475 DCHECK(thread_checker_.CalledOnValidThread()); | 476 DCHECK(thread_checker_.CalledOnValidThread()); |
| 476 if (device_ == kAudioObjectUnknown || output_channels_ == 0) | 477 if (device_ == kAudioObjectUnknown || output_channels_ == 0) |
| 477 return false; | 478 return false; |
| 478 | 479 |
| 479 AudioComponentDescription desc = { | 480 AudioComponentDescription desc = { |
| 480 kAudioUnitType_Output, | 481 kAudioUnitType_Output, |
| 481 kAudioUnitSubType_HALOutput, | 482 kAudioUnitSubType_HALOutput, |
| 482 kAudioUnitManufacturer_Apple, | 483 kAudioUnitManufacturer_Apple, |
| 483 0, | 484 0, |
| 484 0 | 485 0 |
| 485 }; | 486 }; |
| 486 AudioComponent comp = AudioComponentFindNext(0, &desc); | 487 AudioComponent comp = AudioComponentFindNext(0, &desc); |
| 487 if (!comp) | 488 if (!comp) |
| 488 return false; | 489 return false; |
| 489 | 490 |
| 490 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); | 491 OSStatus result = AudioComponentInstanceNew(comp, &audio_unit_); |
| 491 if (result != noErr) { | 492 if (result != noErr) { |
| 492 OSSTATUS_DLOG(ERROR, result) << "AudioComponentInstanceNew() failed."; | 493 OSSTATUS_LOG(ERROR, result) << "AudioComponentInstanceNew() failed."; |
| 493 return false; | 494 return false; |
| 494 } | 495 } |
| 495 | 496 |
| 496 // Enable output as appropriate. | 497 // Enable output as appropriate. |
| 497 // See Apple technote for details about the EnableIO property. | 498 // See Apple technote for details about the EnableIO property. |
| 498 // Note that we use bus 1 for input and bus 0 for output: | 499 // Note that we use bus 1 for input and bus 0 for output: |
| 499 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 500 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 500 UInt32 enable_IO = 1; | 501 UInt32 enable_IO = 1; |
| 501 result = AudioUnitSetProperty( | 502 result = AudioUnitSetProperty( |
| 502 audio_unit_, | 503 audio_unit_, |
| 503 kAudioOutputUnitProperty_EnableIO, | 504 kAudioOutputUnitProperty_EnableIO, |
| 504 kAudioUnitScope_Output, | 505 kAudioUnitScope_Output, |
| 505 0, | 506 0, |
| 506 &enable_IO, | 507 &enable_IO, |
| 507 sizeof(enable_IO)); | 508 sizeof(enable_IO)); |
| 508 if (result != noErr) { | 509 if (result != noErr) { |
| 510 OSSTATUS_LOG(ERROR, result) |
| 511 << "kAudioOutputUnitProperty_EnableIO() failed."; |
| 509 CloseAudioUnit(); | 512 CloseAudioUnit(); |
| 510 return false; | 513 return false; |
| 511 } | 514 } |
| 512 | 515 |
| 513 // Set the device to be used with the AUHAL AudioUnit. | 516 // Set the device to be used with the AUHAL AudioUnit. |
| 514 result = AudioUnitSetProperty( | 517 result = AudioUnitSetProperty( |
| 515 audio_unit_, | 518 audio_unit_, |
| 516 kAudioOutputUnitProperty_CurrentDevice, | 519 kAudioOutputUnitProperty_CurrentDevice, |
| 517 kAudioUnitScope_Global, | 520 kAudioUnitScope_Global, |
| 518 0, | 521 0, |
| 519 &device_, | 522 &device_, |
| 520 sizeof(AudioDeviceID)); | 523 sizeof(AudioDeviceID)); |
| 521 if (result != noErr) { | 524 if (result != noErr) { |
| 525 OSSTATUS_LOG(ERROR, result) |
| 526 << "kAudioOutputUnitProperty_CurrentDevice() failed."; |
| 522 CloseAudioUnit(); | 527 CloseAudioUnit(); |
| 523 return false; | 528 return false; |
| 524 } | 529 } |
| 525 | 530 |
| 526 // Set stream formats. | 531 // Set stream formats. |
| 527 // See Apple's tech note for details on the peculiar way that | 532 // See Apple's tech note for details on the peculiar way that |
| 528 // inputs and outputs are handled in the AUHAL concerning scope and bus | 533 // inputs and outputs are handled in the AUHAL concerning scope and bus |
| 529 // (element) numbers: | 534 // (element) numbers: |
| 530 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 535 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 531 | 536 |
| 532 if (!SetStreamFormat(&output_format_, | 537 if (!SetStreamFormat(&output_format_, |
| 533 output_channels_, | 538 output_channels_, |
| 534 kAudioUnitScope_Input, | 539 kAudioUnitScope_Input, |
| 535 0)) { | 540 0)) { |
| 541 LOG(ERROR) << "Set Stream format failed..."; |
| 536 CloseAudioUnit(); | 542 CloseAudioUnit(); |
| 537 return false; | 543 return false; |
| 538 } | 544 } |
| 539 | 545 |
| 540 bool size_was_changed = false; | 546 bool size_was_changed = false; |
| 541 size_t io_buffer_frame_size = 0; | 547 size_t io_buffer_frame_size = 0; |
| 542 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0, | 548 if (!manager_->MaybeChangeBufferSize(device_, audio_unit_, 0, |
| 543 number_of_frames_, &size_was_changed, | 549 number_of_frames_, &size_was_changed, |
| 544 &io_buffer_frame_size)) { | 550 &io_buffer_frame_size)) { |
| 551 LOG(ERROR) << "Buffer size change failed..."; |
| 545 CloseAudioUnit(); | 552 CloseAudioUnit(); |
| 546 return false; | 553 return false; |
| 547 } | 554 } |
| 548 | 555 |
| 549 // Setup callback. | 556 // Setup callback. |
| 550 AURenderCallbackStruct callback; | 557 AURenderCallbackStruct callback; |
| 551 callback.inputProc = InputProc; | 558 callback.inputProc = InputProc; |
| 552 callback.inputProcRefCon = this; | 559 callback.inputProcRefCon = this; |
| 553 result = AudioUnitSetProperty( | 560 result = AudioUnitSetProperty( |
| 554 audio_unit_, | 561 audio_unit_, |
| 555 kAudioUnitProperty_SetRenderCallback, | 562 kAudioUnitProperty_SetRenderCallback, |
| 556 kAudioUnitScope_Input, | 563 kAudioUnitScope_Input, |
| 557 0, | 564 0, |
| 558 &callback, | 565 &callback, |
| 559 sizeof(callback)); | 566 sizeof(callback)); |
| 560 if (result != noErr) { | 567 if (result != noErr) { |
| 568 OSSTATUS_LOG(ERROR, result) |
| 569 << "kAudioUnitProperty_SetRenderCallback() failed."; |
| 561 CloseAudioUnit(); | 570 CloseAudioUnit(); |
| 562 return false; | 571 return false; |
| 563 } | 572 } |
| 564 | 573 |
| 565 SetAudioChannelLayout(); | 574 SetAudioChannelLayout(); |
| 566 | 575 |
| 567 result = AudioUnitInitialize(audio_unit_); | 576 result = AudioUnitInitialize(audio_unit_); |
| 568 if (result != noErr) { | 577 if (result != noErr) { |
| 569 OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; | 578 OSSTATUS_LOG(ERROR, result) << "AudioUnitInitialize() failed."; |
| 570 CloseAudioUnit(); | 579 CloseAudioUnit(); |
| 571 return false; | 580 return false; |
| 572 } | 581 } |
| 573 | 582 |
| 574 return true; | 583 return true; |
| 575 } | 584 } |
| 576 | 585 |
| 577 void AUHALStream::CloseAudioUnit() { | 586 void AUHALStream::CloseAudioUnit() { |
| 578 DCHECK(thread_checker_.CalledOnValidThread()); | 587 DCHECK(thread_checker_.CalledOnValidThread()); |
| 579 if (!audio_unit_) | 588 if (!audio_unit_) |
| 580 return; | 589 return; |
| 581 | 590 |
| 582 OSStatus result = AudioUnitUninitialize(audio_unit_); | 591 OSStatus result = AudioUnitUninitialize(audio_unit_); |
| 583 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) | 592 OSSTATUS_LOG_IF(ERROR, result != noErr, result) |
| 584 << "AudioUnitUninitialize() failed."; | 593 << "AudioUnitUninitialize() failed."; |
| 585 result = AudioComponentInstanceDispose(audio_unit_); | 594 result = AudioComponentInstanceDispose(audio_unit_); |
| 586 OSSTATUS_DLOG_IF(ERROR, result != noErr, result) | 595 OSSTATUS_LOG_IF(ERROR, result != noErr, result) |
| 587 << "AudioComponentInstanceDispose() failed."; | 596 << "AudioComponentInstanceDispose() failed."; |
| 588 audio_unit_ = 0; | 597 audio_unit_ = 0; |
| 589 } | 598 } |
| 590 | 599 |
| 591 void AUHALStream::SetAudioChannelLayout() { | 600 void AUHALStream::SetAudioChannelLayout() { |
| 592 DCHECK(audio_unit_); | 601 DCHECK(audio_unit_); |
| 593 | 602 |
| 594 // AudioChannelLayout is structure ending in a variable length array, so we | 603 // AudioChannelLayout is structure ending in a variable length array, so we |
| 595 // can't directly allocate one. Instead compute the size and and allocate one | 604 // can't directly allocate one. Instead compute the size and and allocate one |
| 596 // inside of a byte array. | 605 // inside of a byte array. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 continue; | 640 continue; |
| 632 descriptions[order].mChannelLabel = kCoreAudioChannelMapping[ch]; | 641 descriptions[order].mChannelLabel = kCoreAudioChannelMapping[ch]; |
| 633 descriptions[order].mChannelFlags = kAudioChannelFlags_AllOff; | 642 descriptions[order].mChannelFlags = kAudioChannelFlags_AllOff; |
| 634 } | 643 } |
| 635 } | 644 } |
| 636 | 645 |
| 637 OSStatus result = AudioUnitSetProperty( | 646 OSStatus result = AudioUnitSetProperty( |
| 638 audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, | 647 audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, |
| 639 0, channel_layout, layout_size); | 648 0, channel_layout, layout_size); |
| 640 if (result != noErr) { | 649 if (result != noErr) { |
| 641 OSSTATUS_DLOG(ERROR, result) | 650 OSSTATUS_LOG(ERROR, result) |
| 642 << "Failed to set audio channel layout. Using default layout."; | 651 << "Failed to set audio channel layout. Using default layout."; |
| 643 } | 652 } |
| 644 } | 653 } |
| 645 | 654 |
| 646 } // namespace media | 655 } // namespace media |
| OLD | NEW |