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

Side by Side Diff: media/audio/mac/audio_output_mac.cc

Issue 7134001: Fix for CoreAudio stereo problem for unknown speakers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix for CoreAudio stereo problem on unconfigured speaker layouts Created 9 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_output_mac.h" 5 #include "media/audio/mac/audio_output_mac.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "media/audio/audio_util.h" 10 #include "media/audio/audio_util.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // pointer while we operate here. Note that does not mean that the source 89 // pointer while we operate here. Note that does not mean that the source
90 // has been destroyed. 90 // has been destroyed.
91 AudioSourceCallback* source = source_; 91 AudioSourceCallback* source = source_;
92 if (source) 92 if (source)
93 source->OnError(this, static_cast<int>(err)); 93 source->OnError(this, static_cast<int>(err));
94 NOTREACHED() << "error code " << err; 94 NOTREACHED() << "error code " << err;
95 } 95 }
96 96
97 bool PCMQueueOutAudioOutputStream::Open() { 97 bool PCMQueueOutAudioOutputStream::Open() {
98 // Get the default device id. 98 // Get the default device id.
99 unsigned int device_id = 0; 99 AudioObjectID device_id = 0;
scherkus (not reviewing) 2011/06/07 22:43:22 double checking.. intended change?
annacc 2011/06/07 23:09:45 Yep, acts the same way, just looks prettier.
100 AudioObjectPropertyAddress property_address = { 100 AudioObjectPropertyAddress property_address = {
101 kAudioHardwarePropertyDefaultOutputDevice, 101 kAudioHardwarePropertyDefaultOutputDevice,
102 kAudioObjectPropertyScopeGlobal, 102 kAudioObjectPropertyScopeGlobal,
103 kAudioObjectPropertyElementMaster 103 kAudioObjectPropertyElementMaster
104 }; 104 };
105 UInt32 device_id_size = sizeof(device_id); 105 UInt32 device_id_size = sizeof(device_id);
106 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, 106 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject,
107 &property_address, 0, NULL, 107 &property_address, 0, NULL,
108 &device_id_size, &device_id); 108 &device_id_size, &device_id);
109 if (err != noErr) { 109 if (err != noErr) {
110 HandleError(err); 110 HandleError(err);
111 return false; 111 return false;
112 } 112 }
113 // Get the size of the channel layout. 113 // Get the size of the channel layout.
114 UInt32 core_layout_size; 114 UInt32 core_layout_size;
115 // TODO(annacc): AudioDeviceGetPropertyInfo() is deprecated, but its
116 // replacement, AudioObjectGetPropertyDataSize(), doesn't work yet with
117 // kAudioDevicePropertyPreferredChannelLayout.
115 err = AudioDeviceGetPropertyInfo(device_id, 0, false, 118 err = AudioDeviceGetPropertyInfo(device_id, 0, false,
116 kAudioDevicePropertyPreferredChannelLayout, 119 kAudioDevicePropertyPreferredChannelLayout,
117 &core_layout_size, NULL); 120 &core_layout_size, NULL);
118 if (err != noErr) { 121 if (err != noErr) {
119 HandleError(err); 122 HandleError(err);
120 return false; 123 return false;
121 } 124 }
122 // Get the device's channel layout. This layout may vary in sized based on 125 // Get the device's channel layout. This layout may vary in sized based on
123 // the number of channels. Use |core_layout_size| to allocate memory. 126 // the number of channels. Use |core_layout_size| to allocate memory.
124 scoped_ptr_malloc<AudioChannelLayout> core_channel_layout; 127 scoped_ptr_malloc<AudioChannelLayout> core_channel_layout;
125 core_channel_layout.reset( 128 core_channel_layout.reset(
126 reinterpret_cast<AudioChannelLayout*>(malloc(core_layout_size))); 129 reinterpret_cast<AudioChannelLayout*>(malloc(core_layout_size)));
127 memset(core_channel_layout.get(), 0, core_layout_size); 130 memset(core_channel_layout.get(), 0, core_layout_size);
131 // TODO(annacc): AudioDeviceGetProperty() is deprecated, but its
132 // replacement, AudioObjectGetPropertyData(), doesn't work yet with
133 // kAudioDevicePropertyPreferredChannelLayout.
128 err = AudioDeviceGetProperty(device_id, 0, false, 134 err = AudioDeviceGetProperty(device_id, 0, false,
129 kAudioDevicePropertyPreferredChannelLayout, 135 kAudioDevicePropertyPreferredChannelLayout,
130 &core_layout_size, core_channel_layout.get()); 136 &core_layout_size, core_channel_layout.get());
131 if (err != noErr) { 137 if (err != noErr) {
132 HandleError(err); 138 HandleError(err);
133 return false; 139 return false;
134 } 140 }
135 141
136 num_core_channels_ = 142 num_core_channels_ =
137 static_cast<int>(core_channel_layout->mNumberChannelDescriptions); 143 static_cast<int>(core_channel_layout->mNumberChannelDescriptions);
(...skipping 29 matching lines...) Expand all
167 err = AudioQueueSetParameter(audio_queue_, kAudioQueueParam_Volume, 1.0); 173 err = AudioQueueSetParameter(audio_queue_, kAudioQueueParam_Volume, 1.0);
168 if (err != noErr) { 174 if (err != noErr) {
169 HandleError(err); 175 HandleError(err);
170 return false; 176 return false;
171 } 177 }
172 178
173 // Capture channel layout in a format we can use. 179 // Capture channel layout in a format we can use.
174 for (int i = 0; i < CHANNELS_MAX; ++i) 180 for (int i = 0; i < CHANNELS_MAX; ++i)
175 core_channel_orderings_[i] = kEmptyChannel; 181 core_channel_orderings_[i] = kEmptyChannel;
176 182
183 bool allChannelsUnknown = true;
scherkus (not reviewing) 2011/06/07 22:43:22 unix_hacker style: all_channels_unknown
annacc 2011/06/07 23:09:45 Arg, I forget your crazy conventions. :) Thanks.
177 for (int i = 0; i < num_core_channels_; ++i) { 184 for (int i = 0; i < num_core_channels_; ++i) {
178 switch (core_channel_layout->mChannelDescriptions[i].mChannelLabel) { 185 AudioChannelLabel label =
179 case kAudioChannelLabel_Left: 186 core_channel_layout->mChannelDescriptions[i].mChannelLabel;
180 core_channel_orderings_[LEFT] = i; 187 if (label != kAudioChannelLabel_Unknown) {
scherkus (not reviewing) 2011/06/07 22:43:22 nit: instead check for opposite condition + contin
annacc 2011/06/07 23:09:45 Done.
181 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT]; 188 allChannelsUnknown = false;
182 break; 189 switch (label) {
183 case kAudioChannelLabel_Right: 190 case kAudioChannelLabel_Left:
184 core_channel_orderings_[RIGHT] = i; 191 core_channel_orderings_[LEFT] = i;
185 channel_remap_[i] = kChannelOrderings[source_layout_][RIGHT]; 192 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT];
186 break; 193 break;
187 case kAudioChannelLabel_Center: 194 case kAudioChannelLabel_Right:
188 core_channel_orderings_[CENTER] = i; 195 core_channel_orderings_[RIGHT] = i;
189 channel_remap_[i] = kChannelOrderings[source_layout_][CENTER]; 196 channel_remap_[i] = kChannelOrderings[source_layout_][RIGHT];
190 break; 197 break;
191 case kAudioChannelLabel_LFEScreen: 198 case kAudioChannelLabel_Center:
192 core_channel_orderings_[LFE] = i; 199 core_channel_orderings_[CENTER] = i;
193 channel_remap_[i] = kChannelOrderings[source_layout_][LFE]; 200 channel_remap_[i] = kChannelOrderings[source_layout_][CENTER];
194 break; 201 break;
195 case kAudioChannelLabel_LeftSurround: 202 case kAudioChannelLabel_LFEScreen:
196 core_channel_orderings_[SIDE_LEFT] = i; 203 core_channel_orderings_[LFE] = i;
197 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_LEFT]; 204 channel_remap_[i] = kChannelOrderings[source_layout_][LFE];
198 break; 205 break;
199 case kAudioChannelLabel_RightSurround: 206 case kAudioChannelLabel_LeftSurround:
200 core_channel_orderings_[SIDE_RIGHT] = i; 207 core_channel_orderings_[SIDE_LEFT] = i;
201 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_RIGHT]; 208 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_LEFT];
202 break; 209 break;
203 case kAudioChannelLabel_LeftCenter: 210 case kAudioChannelLabel_RightSurround:
204 core_channel_orderings_[LEFT_OF_CENTER] = i; 211 core_channel_orderings_[SIDE_RIGHT] = i;
205 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT_OF_CENTER]; 212 channel_remap_[i] = kChannelOrderings[source_layout_][SIDE_RIGHT];
206 break; 213 break;
207 case kAudioChannelLabel_RightCenter: 214 case kAudioChannelLabel_LeftCenter:
208 core_channel_orderings_[RIGHT_OF_CENTER] = i; 215 core_channel_orderings_[LEFT_OF_CENTER] = i;
209 channel_remap_[i] = kChannelOrderings[source_layout_][RIGHT_OF_CENTER]; 216 channel_remap_[i] = kChannelOrderings[source_layout_][LEFT_OF_CENTER];
210 break; 217 break;
211 case kAudioChannelLabel_CenterSurround: 218 case kAudioChannelLabel_RightCenter:
212 core_channel_orderings_[BACK_CENTER] = i; 219 core_channel_orderings_[RIGHT_OF_CENTER] = i;
213 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_CENTER]; 220 channel_remap_[i] =
214 break; 221 kChannelOrderings[source_layout_][RIGHT_OF_CENTER];
215 case kAudioChannelLabel_RearSurroundLeft: 222 break;
216 core_channel_orderings_[BACK_LEFT] = i; 223 case kAudioChannelLabel_CenterSurround:
217 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_LEFT]; 224 core_channel_orderings_[BACK_CENTER] = i;
218 break; 225 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_CENTER];
219 case kAudioChannelLabel_RearSurroundRight: 226 break;
220 core_channel_orderings_[BACK_RIGHT] = i; 227 case kAudioChannelLabel_RearSurroundLeft:
221 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_RIGHT]; 228 core_channel_orderings_[BACK_LEFT] = i;
222 break; 229 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_LEFT];
223 default: 230 break;
224 DLOG(WARNING) << "Channel label not supported"; 231 case kAudioChannelLabel_RearSurroundRight:
225 channel_remap_[i] = kEmptyChannel; 232 core_channel_orderings_[BACK_RIGHT] = i;
226 break; 233 channel_remap_[i] = kChannelOrderings[source_layout_][BACK_RIGHT];
234 break;
235 case kAudioChannelLabel_Unknown:
236 channel_remap_[i] = kEmptyChannel;
237 break;
238 default:
239 DLOG(WARNING) << "Channel label not supported";
240 channel_remap_[i] = kEmptyChannel;
241 break;
242 }
227 } 243 }
228 } 244 }
229 245
230 // Check if we need to adjust the layout. 246 // Check if we need to swizzle or adjust the layout from source to device.
231 // If the device has a BACK_LEFT and no SIDE_LEFT and the source has 247 should_swizzle_ = false;
232 // a SIDE_LEFT but no BACK_LEFT, then move (and preserve the channel).
233 // e.g. CHANNEL_LAYOUT_5POINT1 -> CHANNEL_LAYOUT_5POINT1_BACK
234 CheckForAdjustedLayout(SIDE_LEFT, BACK_LEFT);
235 // Same for SIDE_RIGHT -> BACK_RIGHT.
236 CheckForAdjustedLayout(SIDE_RIGHT, BACK_RIGHT);
237 // Move BACK_LEFT to SIDE_LEFT.
238 // e.g. CHANNEL_LAYOUT_5POINT1_BACK -> CHANNEL_LAYOUT_5POINT1
239 CheckForAdjustedLayout(BACK_LEFT, SIDE_LEFT);
240 // Same for BACK_RIGHT -> SIDE_RIGHT.
241 CheckForAdjustedLayout(BACK_RIGHT, SIDE_RIGHT);
242 // Move SIDE_LEFT to LEFT_OF_CENTER.
243 // e.g. CHANNEL_LAYOUT_7POINT1 -> CHANNEL_LAYOUT_7POINT1_WIDE
244 CheckForAdjustedLayout(SIDE_LEFT, LEFT_OF_CENTER);
245 // Same for SIDE_RIGHT -> RIGHT_OF_CENTER.
246 CheckForAdjustedLayout(SIDE_RIGHT, RIGHT_OF_CENTER);
247 // Move LEFT_OF_CENTER to SIDE_LEFT.
248 // e.g. CHANNEL_LAYOUT_7POINT1_WIDE -> CHANNEL_LAYOUT_7POINT1
249 CheckForAdjustedLayout(LEFT_OF_CENTER, SIDE_LEFT);
250 // Same for RIGHT_OF_CENTER -> SIDE_RIGHT.
251 CheckForAdjustedLayout(RIGHT_OF_CENTER, SIDE_RIGHT);
252 248
253 // Check if we will need to swizzle from source to device layout (maybe not!). 249 if (!allChannelsUnknown) {
scherkus (not reviewing) 2011/06/07 22:43:22 nit: check for opposite condition and return early
annacc 2011/06/07 23:09:45 Done.
254 should_swizzle_ = false; 250 // Check if we need to adjust the layout.
255 for (int i = 0; i < num_core_channels_; ++i) { 251 // If the device has a BACK_LEFT and no SIDE_LEFT and the source has
256 if (kChannelOrderings[source_layout_][i] != core_channel_orderings_[i]) { 252 // a SIDE_LEFT but no BACK_LEFT, then move (and preserve the channel).
257 should_swizzle_ = true; 253 // e.g. CHANNEL_LAYOUT_5POINT1 -> CHANNEL_LAYOUT_5POINT1_BACK
258 break; 254 CheckForAdjustedLayout(SIDE_LEFT, BACK_LEFT);
255 // Same for SIDE_RIGHT -> BACK_RIGHT.
256 CheckForAdjustedLayout(SIDE_RIGHT, BACK_RIGHT);
257 // Move BACK_LEFT to SIDE_LEFT.
258 // e.g. CHANNEL_LAYOUT_5POINT1_BACK -> CHANNEL_LAYOUT_5POINT1
259 CheckForAdjustedLayout(BACK_LEFT, SIDE_LEFT);
260 // Same for BACK_RIGHT -> SIDE_RIGHT.
261 CheckForAdjustedLayout(BACK_RIGHT, SIDE_RIGHT);
262 // Move SIDE_LEFT to LEFT_OF_CENTER.
263 // e.g. CHANNEL_LAYOUT_7POINT1 -> CHANNEL_LAYOUT_7POINT1_WIDE
264 CheckForAdjustedLayout(SIDE_LEFT, LEFT_OF_CENTER);
265 // Same for SIDE_RIGHT -> RIGHT_OF_CENTER.
266 CheckForAdjustedLayout(SIDE_RIGHT, RIGHT_OF_CENTER);
267 // Move LEFT_OF_CENTER to SIDE_LEFT.
268 // e.g. CHANNEL_LAYOUT_7POINT1_WIDE -> CHANNEL_LAYOUT_7POINT1
269 CheckForAdjustedLayout(LEFT_OF_CENTER, SIDE_LEFT);
270 // Same for RIGHT_OF_CENTER -> SIDE_RIGHT.
271 CheckForAdjustedLayout(RIGHT_OF_CENTER, SIDE_RIGHT);
272 // For MONO -> STEREO, move audio to LEFT and RIGHT if applicable.
273 CheckForAdjustedLayout(CENTER, LEFT);
274 CheckForAdjustedLayout(CENTER, RIGHT);
275
276 for (int i = 0; i < num_core_channels_; ++i) {
277 if (kChannelOrderings[source_layout_][i] != core_channel_orderings_[i]) {
278 should_swizzle_ = true;
279 break;
280 }
259 } 281 }
260 } 282 }
261 283
262 return true; 284 return true;
263 } 285 }
264 286
265 void PCMQueueOutAudioOutputStream::Close() { 287 void PCMQueueOutAudioOutputStream::Close() {
266 // It is valid to call Close() before calling Open(), thus audio_queue_ 288 // It is valid to call Close() before calling Open(), thus audio_queue_
267 // might be NULL. 289 // might be NULL.
268 if (audio_queue_) { 290 if (audio_queue_) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 HandleError(err); 490 HandleError(err);
469 return; 491 return;
470 } 492 }
471 } 493 }
472 err = AudioQueueStart(audio_queue_, NULL); 494 err = AudioQueueStart(audio_queue_, NULL);
473 if (err != noErr) { 495 if (err != noErr) {
474 HandleError(err); 496 HandleError(err);
475 return; 497 return;
476 } 498 }
477 } 499 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698