summaryrefslogtreecommitdiffstats
path: root/media/audio/mac/audio_manager_mac.cc
diff options
context:
space:
mode:
authorcrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-13 20:36:51 +0000
committercrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-13 20:36:51 +0000
commit06ea4f7c2ee733bdf2e717af72cb56fb571eafac (patch)
treec1e387d65490a2bc7cf9bfc72e32d33b646e1df8 /media/audio/mac/audio_manager_mac.cc
parenta5d3767bf2ddae040dd9bdb894bbe6276e7f5a2f (diff)
downloadchromium_src-06ea4f7c2ee733bdf2e717af72cb56fb571eafac.zip
chromium_src-06ea4f7c2ee733bdf2e717af72cb56fb571eafac.tar.gz
chromium_src-06ea4f7c2ee733bdf2e717af72cb56fb571eafac.tar.bz2
Pass more detailed audio hardware configuration information to the renderer
AudioHardwareConfig currently contains an ad-hoc mix of pieces of information about the audio input and output hardware. This CL adds more complete and symmetric information about the audio hardware as tracked in AudioHardwareConfig. The ChannelMixer is also upgraded to allow for "discrete" up and down mixing. BUG=none TEST=manual - several tests updated Review URL: https://codereview.chromium.org/12387006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187936 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/mac/audio_manager_mac.cc')
-rw-r--r--media/audio/mac/audio_manager_mac.cc124
1 files changed, 116 insertions, 8 deletions
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 2184e12..ec6a79a 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -264,6 +264,97 @@ bool AudioManagerMac::HasAudioInputDevices() {
return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice);
}
+// TODO(crogers): There are several places on the OSX specific code which
+// could benefit from this helper function.
+bool AudioManagerMac::GetDefaultOutputDevice(
+ AudioDeviceID* device) {
+ CHECK(device);
+
+ // Obtain the current output device selected by the user.
+ static const AudioObjectPropertyAddress kAddress = {
+ kAudioHardwarePropertyDefaultOutputDevice,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster
+ };
+
+ UInt32 size = sizeof(*device);
+
+ OSStatus result = AudioObjectGetPropertyData(
+ kAudioObjectSystemObject,
+ &kAddress,
+ 0,
+ 0,
+ &size,
+ device);
+
+ if ((result != kAudioHardwareNoError) || (*device == kAudioDeviceUnknown)) {
+ DLOG(ERROR) << "Error getting default output AudioDevice.";
+ return false;
+ }
+
+ return true;
+}
+
+bool AudioManagerMac::GetDefaultOutputChannels(
+ int* channels, int* channels_per_frame) {
+ AudioDeviceID device;
+ if (!GetDefaultOutputDevice(&device))
+ return false;
+
+ return GetDeviceChannels(device,
+ kAudioDevicePropertyScopeOutput,
+ channels,
+ channels_per_frame);
+}
+
+bool AudioManagerMac::GetDeviceChannels(
+ AudioDeviceID device,
+ AudioObjectPropertyScope scope,
+ int* channels,
+ int* channels_per_frame) {
+ CHECK(channels);
+ CHECK(channels_per_frame);
+
+ // Get stream configuration.
+ AudioObjectPropertyAddress pa;
+ pa.mSelector = kAudioDevicePropertyStreamConfiguration;
+ pa.mScope = scope;
+ pa.mElement = kAudioObjectPropertyElementMaster;
+
+ UInt32 size;
+ OSStatus result = AudioObjectGetPropertyDataSize(device, &pa, 0, 0, &size);
+ if (result != noErr || !size)
+ return false;
+
+ // Allocate storage.
+ scoped_array<uint8> list_storage(new uint8[size]);
+ AudioBufferList& buffer_list =
+ *reinterpret_cast<AudioBufferList*>(list_storage.get());
+
+ result = AudioObjectGetPropertyData(
+ device,
+ &pa,
+ 0,
+ 0,
+ &size,
+ &buffer_list);
+ if (result != noErr)
+ return false;
+
+ // Determine number of input channels.
+ *channels_per_frame = buffer_list.mNumberBuffers > 0 ?
+ buffer_list.mBuffers[0].mNumberChannels : 0;
+ if (*channels_per_frame == 1 && buffer_list.mNumberBuffers > 1) {
+ // Non-interleaved.
+ *channels = buffer_list.mNumberBuffers;
+ } else {
+ // Interleaved.
+ *channels = *channels_per_frame;
+ }
+
+ return true;
+}
+
void AudioManagerMac::GetAudioInputDeviceNames(
media::AudioDeviceNames* device_names) {
GetAudioDeviceInfo(true, device_names);
@@ -333,11 +424,23 @@ AudioInputStream* AudioManagerMac::MakeLowLatencyInputStream(
AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
const AudioParameters& input_params) {
- ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
+ int hardware_channels = 2;
+ int hardware_channels_per_frame = 1;
+ if (!GetDefaultOutputChannels(&hardware_channels,
+ &hardware_channels_per_frame)) {
+ // Fallback to stereo.
+ hardware_channels = 2;
+ }
+
+ ChannelLayout channel_layout = GuessChannelLayout(hardware_channels);
+
int buffer_size = kDefaultLowLatencyBufferSize;
+ int user_buffer_size = GetUserBufferSize();
+ if (user_buffer_size)
+ buffer_size = user_buffer_size;
+
int input_channels = 0;
if (input_params.IsValid()) {
- channel_layout = input_params.channel_layout();
input_channels = input_params.input_channels();
if (input_channels > 0) {
@@ -349,13 +452,18 @@ AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
}
}
- int user_buffer_size = GetUserBufferSize();
- if (user_buffer_size)
- buffer_size = user_buffer_size;
+ AudioParameters params(
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ channel_layout,
+ input_channels,
+ AUAudioOutputStream::HardwareSampleRate(),
+ 16,
+ buffer_size);
- return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels,
- AUAudioOutputStream::HardwareSampleRate(), 16, buffer_size);
+ if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED)
+ params.SetDiscreteChannels(hardware_channels);
+
+ return params;
}
void AudioManagerMac::CreateDeviceListener() {