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

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

Issue 2683033003: Tell CoreAudio how to interpret Chrome's channel layout. (Closed)
Patch Set: Fix 8ch+ discrete layouts. 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
« no previous file with comments | « media/audio/mac/audio_auhal_mac.h ('k') | media/base/channel_layout.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..e11885fa3d0a5e599a0462a698bc9c3063cb89b2 100644
--- a/media/audio/mac/audio_auhal_mac.cc
+++ b/media/audio/mac/audio_auhal_mac.cc
@@ -7,6 +7,7 @@
#include <CoreServices/CoreServices.h>
#include <algorithm>
+#include <cstddef>
#include <string>
#include "base/bind.h"
@@ -22,6 +23,32 @@
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 &&
+ 10 == CHANNELS_MAX,
+ "Channel positions must match CoreAudio channel order.");
+
static void WrapBufferList(AudioBufferList* buffer_list,
AudioBus* bus,
int frames) {
@@ -535,6 +562,8 @@ bool AUHALStream::ConfigureAUHAL() {
return false;
}
+ SetAudioChannelLayout();
+
result = AudioUnitInitialize(audio_unit_);
if (result != noErr) {
OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed.";
@@ -559,4 +588,59 @@ void AUHALStream::CloseAudioUnit() {
audio_unit_ = 0;
}
+void AUHALStream::SetAudioChannelLayout() {
+ DCHECK(audio_unit_);
+
+ // AudioChannelLayout is structure ending in a variable length array, so we
+ // can't directly allocate one. Instead compute the size and and allocate one
+ // inside of a byte array.
+ //
+ // Code modeled after example from Apple documentation here:
+ // https://developer.apple.com/library/content/qa/qa1627/_index.html
+ const size_t layout_size =
+ offsetof(AudioChannelLayout, mChannelDescriptions[params_.channels()]);
+ 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; once we run out
+ // of known channels mark them as unknown.
+ for (int ch = 0; ch < params_.channels(); ++ch) {
+ descriptions[ch].mChannelLabel = ch > CHANNELS_MAX
+ ? kAudioChannelLabel_Unknown
+ : 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
« no previous file with comments | « media/audio/mac/audio_auhal_mac.h ('k') | media/base/channel_layout.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698