Chromium Code Reviews| Index: media/audio/mac/audio_auhal_mac.cc |
| diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc |
| index d4d6075bd84a2bac8a586b1cb7337beee28a9b7c..6d352349f79f35baf8539cba6c24c87c6a7ac617 100644 |
| --- a/media/audio/mac/audio_auhal_mac.cc |
| +++ b/media/audio/mac/audio_auhal_mac.cc |
| @@ -22,6 +22,31 @@ |
| namespace media { |
| +// Mapping from Chrome's channel layout to CoreAudio layout. This must match the |
| +// layout of the Channels enum in |channel_layout.h| |
| +static const AudioChannelLabel kCoreAudioChannelMapping[] = { |
| + kAudioChannelLabel_Left, |
| + kAudioChannelLabel_Right, |
| + kAudioChannelLabel_Center, |
| + kAudioChannelLabel_LFEScreen, |
| + kAudioChannelLabel_LeftSurround, |
| + kAudioChannelLabel_RightSurround, |
| + kAudioChannelLabel_LeftCenter, |
| + kAudioChannelLabel_RightCenter, |
| + kAudioChannelLabel_CenterSurround, |
| + kAudioChannelLabel_LeftSurroundDirect, |
| + kAudioChannelLabel_RightSurroundDirect, |
| +}; |
| +static_assert(0 == LEFT && 1 == RIGHT && 2 == CENTER && 3 == LFE && |
| + 4 == BACK_LEFT && |
| + 5 == BACK_RIGHT && |
| + 6 == LEFT_OF_CENTER && |
| + 7 == RIGHT_OF_CENTER && |
| + 8 == BACK_CENTER && |
| + 9 == SIDE_LEFT && |
| + 10 == SIDE_RIGHT, |
| + "Channel positions must max OSX channel order."); |
|
Avi (use Gerrit)
2017/02/09 02:44:38
"must match"? (And it's "macOS" nowadays.)
DaleCurtis
2017/02/09 03:18:38
Done, switched to CoreAudio like we use elsewhere
|
| + |
| static void WrapBufferList(AudioBufferList* buffer_list, |
| AudioBus* bus, |
| int frames) { |
| @@ -535,6 +560,8 @@ bool AUHALStream::ConfigureAUHAL() { |
| return false; |
| } |
| + SetAudioChannelLayout(); |
| + |
| result = AudioUnitInitialize(audio_unit_); |
| if (result != noErr) { |
| OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed."; |
| @@ -559,4 +586,55 @@ void AUHALStream::CloseAudioUnit() { |
| audio_unit_ = 0; |
| } |
| +void AUHALStream::SetAudioChannelLayout() { |
| + DCHECK(audio_unit_); |
| + |
| +// Code modeled after example from Apple documentation here: |
| +// https://developer.apple.com/library/content/qa/qa1627/_index.html |
|
Avi (use Gerrit)
2017/02/09 02:44:38
Can you clarify in the comments why it appears you
DaleCurtis
2017/02/09 03:18:38
I thought (1) would prevent this, but offsetof() w
|
| +#define FIELD_OFFSET(type, field) ((size_t) & ((type*)0)->field) |
| + const size_t layout_size = FIELD_OFFSET( |
| + AudioChannelLayout, mChannelDescriptions[params_.channels()]); |
| +#undef FIELD_OFFSET |
| + |
| + std::unique_ptr<uint8_t[]> layout_storage(new uint8_t[layout_size]); |
| + memset(layout_storage.get(), 0, layout_size); |
| + AudioChannelLayout* channel_layout = |
| + reinterpret_cast<AudioChannelLayout*>(layout_storage.get()); |
| + |
| + channel_layout->mNumberChannelDescriptions = params_.channels(); |
| + channel_layout->mChannelLayoutTag = |
| + kAudioChannelLayoutTag_UseChannelDescriptions; |
| + AudioChannelDescription* descriptions = channel_layout->mChannelDescriptions; |
| + |
| + if (params_.channel_layout() == CHANNEL_LAYOUT_DISCRETE) { |
| + // For the discrete case just assume common input mappings. |
| + for (int ch = 0; ch <= CHANNELS_MAX; ++ch) { |
| + descriptions[ch].mChannelLabel = kCoreAudioChannelMapping[ch]; |
| + descriptions[ch].mChannelFlags = kAudioChannelFlags_AllOff; |
| + } |
| + } else if (params_.channel_layout() == CHANNEL_LAYOUT_MONO) { |
| + // CoreAudio has a special label for mono. |
| + DCHECK_EQ(params_.channels(), 1); |
| + descriptions[0].mChannelLabel = kAudioChannelLabel_Mono; |
| + descriptions[0].mChannelFlags = kAudioChannelFlags_AllOff; |
| + } else { |
| + for (int ch = 0; ch <= CHANNELS_MAX; ++ch) { |
| + const int order = |
| + ChannelOrder(params_.channel_layout(), static_cast<Channels>(ch)); |
| + if (order == -1) |
| + continue; |
| + descriptions[order].mChannelLabel = kCoreAudioChannelMapping[ch]; |
| + descriptions[order].mChannelFlags = kAudioChannelFlags_AllOff; |
| + } |
| + } |
| + |
| + OSStatus result = AudioUnitSetProperty( |
| + audio_unit_, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, |
| + 0, channel_layout, layout_size); |
| + if (result != noErr) { |
| + OSSTATUS_DLOG(ERROR, result) |
| + << "Failed to set audio channel layout. Using default layout."; |
| + } |
| +} |
| + |
| } // namespace media |