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

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

Issue 23533045: Implement GetDefaultOutputDeviceID, GetAssociatedOutputDeviceID and ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix apparent sdk build problem Created 7 years, 3 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_manager_mac.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/mac/audio_manager_mac.cc
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 21b931809a5333e89595deae95be058455791d6f..bb2292beac712d31332148e4ea688b81012f9ecb 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -186,7 +186,7 @@ static AudioDeviceID GetAudioDeviceIdByUId(bool is_input,
UInt32 device_size = sizeof(audio_device_id);
OSStatus result = -1;
- if (device_id == AudioManagerBase::kDefaultDeviceId) {
+ if (device_id == AudioManagerBase::kDefaultDeviceId || device_id.empty()) {
// Default Device.
property_address.mSelector = is_input ?
kAudioHardwarePropertyDefaultInputDevice :
@@ -260,7 +260,7 @@ bool AudioManagerMac::HasAudioInputDevices() {
return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice);
}
-// TODO(crogers): There are several places on the OSX specific code which
+// TODO(xians): There are several places on the OSX specific code which
// could benefit from these helper functions.
bool AudioManagerMac::GetDefaultInputDevice(
AudioDeviceID* device) {
@@ -441,6 +441,64 @@ AudioParameters AudioManagerMac::GetInputStreamParameters(
sample_rate, 16, buffer_size);
}
+std::string AudioManagerMac::GetAssociatedOutputDeviceID(
+ const std::string& input_device_id) {
+ AudioDeviceID device = GetAudioDeviceIdByUId(true, input_device_id);
+ if (device == kAudioObjectUnknown)
+ return std::string();
+
+ UInt32 size = 0;
+ AudioObjectPropertyAddress pa = {
+ kAudioDevicePropertyRelatedDevices,
+ kAudioDevicePropertyScopeOutput,
+ kAudioObjectPropertyElementMaster
+ };
+ OSStatus result = AudioObjectGetPropertyDataSize(device, &pa, 0, 0, &size);
+ if (result || !size)
+ return std::string();
+
+ int device_count = size / sizeof(AudioDeviceID);
+ scoped_ptr_malloc<AudioDeviceID>
+ devices(reinterpret_cast<AudioDeviceID*>(malloc(size)));
+ result = AudioObjectGetPropertyData(
+ device, &pa, 0, NULL, &size, devices.get());
+ if (result)
+ return std::string();
+
+ for (int i = 0; i < device_count; ++i) {
+ // Get the number of output channels of the device.
+ pa.mSelector = kAudioDevicePropertyStreams;
+ size = 0;
+ result = AudioObjectGetPropertyDataSize(devices.get()[i],
+ &pa,
+ 0,
+ NULL,
+ &size);
+ if (result || !size)
+ continue; // Skip if there aren't any output channels.
+
+ // Get device UID.
+ CFStringRef uid = NULL;
+ size = sizeof(uid);
+ pa.mSelector = kAudioDevicePropertyDeviceUID;
+ result = AudioObjectGetPropertyData(devices.get()[i],
+ &pa,
+ 0,
+ NULL,
+ &size,
+ &uid);
+ if (result || !uid)
+ continue;
+
+ std::string ret(base::SysCFStringRefToUTF8(uid));
+ CFRelease(uid);
+ return ret;
+ }
+
+ // No matching device found.
+ return std::string();
+}
+
AudioOutputStream* AudioManagerMac::MakeLinearOutputStream(
const AudioParameters& params) {
return MakeLowLatencyOutputStream(params, std::string(), std::string());
@@ -450,15 +508,19 @@ AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
const AudioParameters& params,
const std::string& device_id,
const std::string& input_device_id) {
- DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
// Handle basic output with no input channels.
if (params.input_channels() == 0) {
- AudioDeviceID device = kAudioObjectUnknown;
- GetDefaultOutputDevice(&device);
+ AudioDeviceID device = GetAudioDeviceIdByUId(false, device_id);
+ if (device == kAudioObjectUnknown) {
+ DLOG(ERROR) << "Failed to open output device: " << device_id;
+ return NULL;
+ }
return new AUHALStream(this, params, device);
}
- // TODO(crogers): support more than stereo input.
+ DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
+
+ // TODO(xians): support more than stereo input.
if (params.input_channels() != 2) {
// WebAudio is currently hard-coded to 2 channels so we should not
// see this case.
@@ -495,7 +557,7 @@ AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
// different and arbitrary combinations of input and output devices
// even running at different sample-rates.
// kAudioDeviceUnknown translates to "use default" here.
- // TODO(crogers): consider tracking UMA stats on AUHALStream
+ // TODO(xians): consider tracking UMA stats on AUHALStream
// versus AudioSynchronizedStream.
AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, input_device_id);
if (audio_device_id == kAudioObjectUnknown)
@@ -507,6 +569,33 @@ AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
kAudioDeviceUnknown);
}
+std::string AudioManagerMac::GetDefaultOutputDeviceID() {
+ AudioDeviceID device_id = kAudioObjectUnknown;
+ if (!GetDefaultOutputDevice(&device_id))
+ return std::string();
+
+ const AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyDeviceUID,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster
+ };
+ CFStringRef device_uid = NULL;
+ UInt32 size = sizeof(device_uid);
+ OSStatus status = AudioObjectGetPropertyData(device_id,
+ &property_address,
+ 0,
+ NULL,
+ &size,
+ &device_uid);
+ if (status != kAudioHardwareNoError || !device_uid)
+ return std::string();
+
+ std::string ret(base::SysCFStringRefToUTF8(device_uid));
+ CFRelease(device_uid);
+
+ return ret;
+}
+
AudioInputStream* AudioManagerMac::MakeLinearInputStream(
const AudioParameters& params, const std::string& device_id) {
DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format());
@@ -516,12 +605,24 @@ AudioInputStream* AudioManagerMac::MakeLinearInputStream(
AudioInputStream* AudioManagerMac::MakeLowLatencyInputStream(
const AudioParameters& params, const std::string& device_id) {
DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
- // Gets the AudioDeviceID that refers to the AudioOutputDevice with the device
+ // Gets the AudioDeviceID that refers to the AudioInputDevice with the device
// unique id. This AudioDeviceID is used to set the device for Audio Unit.
AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
AudioInputStream* stream = NULL;
- if (audio_device_id != kAudioObjectUnknown)
- stream = new AUAudioInputStream(this, params, audio_device_id);
+ if (audio_device_id != kAudioObjectUnknown) {
+ // AUAudioInputStream needs to be fed the preferred audio output parameters
+ // of the matching device so that the buffer size of both input and output
+ // can be matched. See constructor of AUAudioInputStream for more.
+ const std::string associated_output_device(
+ GetAssociatedOutputDeviceID(device_id));
+ const AudioParameters output_params =
+ GetPreferredOutputStreamParameters(
+ associated_output_device.empty() ?
+ AudioManagerBase::kDefaultDeviceId : associated_output_device,
+ params);
+ stream = new AUAudioInputStream(this, params, output_params,
+ audio_device_id);
+ }
return stream;
}
@@ -529,17 +630,22 @@ AudioInputStream* AudioManagerMac::MakeLowLatencyInputStream(
AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
const std::string& output_device_id,
const AudioParameters& input_params) {
- // TODO(tommi): Support |output_device_id|.
- DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
+ AudioDeviceID device = GetAudioDeviceIdByUId(false, output_device_id);
+ if (device == kAudioObjectUnknown) {
+ DLOG(ERROR) << "Invalid output device " << output_device_id;
+ return AudioParameters();
+ }
+
int hardware_channels = 2;
- if (!GetDefaultOutputChannels(&hardware_channels)) {
+ if (!GetDeviceChannels(device, kAudioDevicePropertyScopeOutput,
+ &hardware_channels)) {
// Fallback to stereo.
hardware_channels = 2;
}
ChannelLayout channel_layout = GuessChannelLayout(hardware_channels);
- const int hardware_sample_rate = AUAudioOutputStream::HardwareSampleRate();
+ const int hardware_sample_rate = HardwareSampleRateForDevice(device);
const int buffer_size = ChooseBufferSize(hardware_sample_rate);
int input_channels = 0;
@@ -547,7 +653,7 @@ AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
input_channels = input_params.input_channels();
if (input_channels > 0) {
- // TODO(crogers): given the limitations of the AudioOutputStream
+ // TODO(xians): given the limitations of the AudioOutputStream
// back-ends used with synchronized I/O, we hard-code to stereo.
// Specifically, this is a limitation of AudioSynchronizedStream which
// can be removed as part of the work to consolidate these back-ends.
« no previous file with comments | « media/audio/mac/audio_manager_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698