Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1346)

Unified Diff: media/audio/mac/audio_auhal_mac.cc

Issue 2683033003: Tell CoreAudio how to interpret Chrome's channel layout. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698