Index: media/audio/mac/aggregate_device_manager.cc |
diff --git a/media/audio/mac/aggregate_device_manager.cc b/media/audio/mac/aggregate_device_manager.cc |
deleted file mode 100644 |
index c7f323322e77a8b56b57339905e539730427fd61..0000000000000000000000000000000000000000 |
--- a/media/audio/mac/aggregate_device_manager.cc |
+++ /dev/null |
@@ -1,371 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "media/audio/mac/aggregate_device_manager.h" |
- |
-#include <CoreAudio/AudioHardware.h> |
-#include <string> |
- |
-#include "base/mac/mac_logging.h" |
-#include "base/mac/scoped_cftyperef.h" |
-#include "media/audio/audio_parameters.h" |
-#include "media/audio/mac/audio_manager_mac.h" |
- |
-using base::ScopedCFTypeRef; |
- |
-namespace media { |
- |
-AggregateDeviceManager::AggregateDeviceManager() |
- : plugin_id_(kAudioObjectUnknown), |
- input_device_(kAudioDeviceUnknown), |
- output_device_(kAudioDeviceUnknown), |
- aggregate_device_(kAudioObjectUnknown) { |
-} |
- |
-AggregateDeviceManager::~AggregateDeviceManager() { |
- DestroyAggregateDevice(); |
-} |
- |
-AudioDeviceID AggregateDeviceManager::GetDefaultAggregateDevice() { |
- AudioDeviceID current_input_device; |
- AudioDeviceID current_output_device; |
- AudioManagerMac::GetDefaultInputDevice(¤t_input_device); |
- AudioManagerMac::GetDefaultOutputDevice(¤t_output_device); |
- |
- if (AudioManagerMac::HardwareSampleRateForDevice(current_input_device) != |
- AudioManagerMac::HardwareSampleRateForDevice(current_output_device)) { |
- // TODO(crogers): with some extra work we can make aggregate devices work |
- // if the clock domain is the same but the sample-rate differ. |
- // For now we fallback to the synchronized path. |
- return kAudioDeviceUnknown; |
- } |
- |
- // Use a lazily created aggregate device if it's already available |
- // and still appropriate. |
- if (aggregate_device_ != kAudioObjectUnknown) { |
- // TODO(crogers): handle default device changes for synchronized I/O. |
- // For now, we check to make sure the default devices haven't changed |
- // since we lazily created the aggregate device. |
- if (current_input_device == input_device_ && |
- current_output_device == output_device_) |
- return aggregate_device_; |
- |
- // For now, once lazily created don't attempt to create another |
- // aggregate device. |
- return kAudioDeviceUnknown; |
- } |
- |
- input_device_ = current_input_device; |
- output_device_ = current_output_device; |
- |
- // Only create an aggregrate device if the clock domains match. |
- UInt32 input_clockdomain = GetClockDomain(input_device_); |
- UInt32 output_clockdomain = GetClockDomain(output_device_); |
- DVLOG(1) << "input_clockdomain: " << input_clockdomain; |
- DVLOG(1) << "output_clockdomain: " << output_clockdomain; |
- |
- if (input_clockdomain == 0 || input_clockdomain != output_clockdomain) |
- return kAudioDeviceUnknown; |
- |
- OSStatus result = CreateAggregateDevice( |
- input_device_, |
- output_device_, |
- &aggregate_device_); |
- if (result != noErr) |
- DestroyAggregateDevice(); |
- |
- return aggregate_device_; |
-} |
- |
-CFStringRef AggregateDeviceManager::GetDeviceUID(AudioDeviceID id) { |
- static const AudioObjectPropertyAddress kDeviceUIDAddress = { |
- kAudioDevicePropertyDeviceUID, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- // As stated in the CoreAudio header (AudioHardwareBase.h), |
- // the caller is responsible for releasing the device_UID. |
- CFStringRef device_UID; |
- UInt32 size = sizeof(device_UID); |
- OSStatus result = AudioObjectGetPropertyData( |
- id, |
- &kDeviceUIDAddress, |
- 0, |
- 0, |
- &size, |
- &device_UID); |
- |
- return (result == noErr) ? device_UID : NULL; |
-} |
- |
-void AggregateDeviceManager::GetDeviceName( |
- AudioDeviceID id, char* name, UInt32 size) { |
- static const AudioObjectPropertyAddress kDeviceNameAddress = { |
- kAudioDevicePropertyDeviceName, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- OSStatus result = AudioObjectGetPropertyData( |
- id, |
- &kDeviceNameAddress, |
- 0, |
- 0, |
- &size, |
- name); |
- |
- if (result != noErr && size > 0) |
- name[0] = 0; |
-} |
- |
-UInt32 AggregateDeviceManager::GetClockDomain(AudioDeviceID device_id) { |
- static const AudioObjectPropertyAddress kClockDomainAddress = { |
- kAudioDevicePropertyClockDomain, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- UInt32 clockdomain = 0; |
- UInt32 size = sizeof(UInt32); |
- OSStatus result = AudioObjectGetPropertyData( |
- device_id, |
- &kClockDomainAddress, |
- 0, |
- 0, |
- &size, |
- &clockdomain); |
- |
- return (result == noErr) ? clockdomain : 0; |
-} |
- |
-OSStatus AggregateDeviceManager::GetPluginID(AudioObjectID* id) { |
- DCHECK(id); |
- |
- // Get the audio hardware plugin. |
- CFStringRef bundle_name = CFSTR("com.apple.audio.CoreAudio"); |
- |
- AudioValueTranslation plugin_translation; |
- plugin_translation.mInputData = &bundle_name; |
- plugin_translation.mInputDataSize = sizeof(bundle_name); |
- plugin_translation.mOutputData = id; |
- plugin_translation.mOutputDataSize = sizeof(*id); |
- |
- static const AudioObjectPropertyAddress kPlugInAddress = { |
- kAudioHardwarePropertyPlugInForBundleID, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- UInt32 size = sizeof(plugin_translation); |
- OSStatus result = AudioObjectGetPropertyData( |
- kAudioObjectSystemObject, |
- &kPlugInAddress, |
- 0, |
- 0, |
- &size, |
- &plugin_translation); |
- |
- DVLOG(1) << "CoreAudio plugin ID: " << *id; |
- |
- return result; |
-} |
- |
-CFMutableDictionaryRef |
-AggregateDeviceManager::CreateAggregateDeviceDictionary( |
- AudioDeviceID input_id, |
- AudioDeviceID output_id) { |
- CFMutableDictionaryRef aggregate_device_dict = CFDictionaryCreateMutable( |
- NULL, |
- 0, |
- &kCFTypeDictionaryKeyCallBacks, |
- &kCFTypeDictionaryValueCallBacks); |
- if (!aggregate_device_dict) |
- return NULL; |
- |
- const CFStringRef kAggregateDeviceName = |
- CFSTR("ChromeAggregateAudioDevice"); |
- const CFStringRef kAggregateDeviceUID = |
- CFSTR("com.google.chrome.AggregateAudioDevice"); |
- |
- // Add name and UID of the device to the dictionary. |
- CFDictionaryAddValue( |
- aggregate_device_dict, |
- CFSTR(kAudioAggregateDeviceNameKey), |
- kAggregateDeviceName); |
- CFDictionaryAddValue( |
- aggregate_device_dict, |
- CFSTR(kAudioAggregateDeviceUIDKey), |
- kAggregateDeviceUID); |
- |
- // Add a "private aggregate key" to the dictionary. |
- // The 1 value means that the created aggregate device will |
- // only be accessible from the process that created it, and |
- // won't be visible to outside processes. |
- int value = 1; |
- ScopedCFTypeRef<CFNumberRef> aggregate_device_number(CFNumberCreate( |
- NULL, |
- kCFNumberIntType, |
- &value)); |
- CFDictionaryAddValue( |
- aggregate_device_dict, |
- CFSTR(kAudioAggregateDeviceIsPrivateKey), |
- aggregate_device_number); |
- |
- return aggregate_device_dict; |
-} |
- |
-CFMutableArrayRef |
-AggregateDeviceManager::CreateSubDeviceArray( |
- CFStringRef input_device_UID, CFStringRef output_device_UID) { |
- CFMutableArrayRef sub_devices_array = CFArrayCreateMutable( |
- NULL, |
- 0, |
- &kCFTypeArrayCallBacks); |
- |
- CFArrayAppendValue(sub_devices_array, input_device_UID); |
- CFArrayAppendValue(sub_devices_array, output_device_UID); |
- |
- return sub_devices_array; |
-} |
- |
-OSStatus AggregateDeviceManager::CreateAggregateDevice( |
- AudioDeviceID input_id, |
- AudioDeviceID output_id, |
- AudioDeviceID* aggregate_device) { |
- DCHECK(aggregate_device); |
- |
- const size_t kMaxDeviceNameLength = 256; |
- |
- scoped_ptr<char[]> input_device_name(new char[kMaxDeviceNameLength]); |
- GetDeviceName( |
- input_id, |
- input_device_name.get(), |
- sizeof(input_device_name)); |
- DVLOG(1) << "Input device: \n" << input_device_name; |
- |
- scoped_ptr<char[]> output_device_name(new char[kMaxDeviceNameLength]); |
- GetDeviceName( |
- output_id, |
- output_device_name.get(), |
- sizeof(output_device_name)); |
- DVLOG(1) << "Output device: \n" << output_device_name; |
- |
- OSStatus result = GetPluginID(&plugin_id_); |
- if (result != noErr) |
- return result; |
- |
- // Create a dictionary for the aggregate device. |
- ScopedCFTypeRef<CFMutableDictionaryRef> aggregate_device_dict( |
- CreateAggregateDeviceDictionary(input_id, output_id)); |
- if (!aggregate_device_dict) |
- return -1; |
- |
- // Create the aggregate device. |
- static const AudioObjectPropertyAddress kCreateAggregateDeviceAddress = { |
- kAudioPlugInCreateAggregateDevice, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- UInt32 size = sizeof(*aggregate_device); |
- result = AudioObjectGetPropertyData( |
- plugin_id_, |
- &kCreateAggregateDeviceAddress, |
- sizeof(aggregate_device_dict), |
- &aggregate_device_dict, |
- &size, |
- aggregate_device); |
- if (result != noErr) { |
- DLOG(ERROR) << "Error creating aggregate audio device!"; |
- return result; |
- } |
- |
- // Set the sub-devices for the aggregate device. |
- // In this case we use two: the input and output devices. |
- |
- ScopedCFTypeRef<CFStringRef> input_device_UID(GetDeviceUID(input_id)); |
- ScopedCFTypeRef<CFStringRef> output_device_UID(GetDeviceUID(output_id)); |
- if (!input_device_UID || !output_device_UID) { |
- DLOG(ERROR) << "Error getting audio device UID strings."; |
- return -1; |
- } |
- |
- ScopedCFTypeRef<CFMutableArrayRef> sub_devices_array( |
- CreateSubDeviceArray(input_device_UID, output_device_UID)); |
- if (sub_devices_array == NULL) { |
- DLOG(ERROR) << "Error creating sub-devices array."; |
- return -1; |
- } |
- |
- static const AudioObjectPropertyAddress kSetSubDevicesAddress = { |
- kAudioAggregateDevicePropertyFullSubDeviceList, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- size = sizeof(CFMutableArrayRef); |
- result = AudioObjectSetPropertyData( |
- *aggregate_device, |
- &kSetSubDevicesAddress, |
- 0, |
- NULL, |
- size, |
- &sub_devices_array); |
- if (result != noErr) { |
- DLOG(ERROR) << "Error setting aggregate audio device sub-devices!"; |
- return result; |
- } |
- |
- // Use the input device as the master device. |
- static const AudioObjectPropertyAddress kSetMasterDeviceAddress = { |
- kAudioAggregateDevicePropertyMasterSubDevice, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- size = sizeof(CFStringRef); |
- result = AudioObjectSetPropertyData( |
- *aggregate_device, |
- &kSetMasterDeviceAddress, |
- 0, |
- NULL, |
- size, |
- &input_device_UID); |
- if (result != noErr) { |
- DLOG(ERROR) << "Error setting aggregate audio device master device!"; |
- return result; |
- } |
- |
- DVLOG(1) << "New aggregate device: " << *aggregate_device; |
- return noErr; |
-} |
- |
-void AggregateDeviceManager::DestroyAggregateDevice() { |
- if (aggregate_device_ == kAudioObjectUnknown) |
- return; |
- |
- static const AudioObjectPropertyAddress kDestroyAddress = { |
- kAudioPlugInDestroyAggregateDevice, |
- kAudioObjectPropertyScopeGlobal, |
- kAudioObjectPropertyElementMaster |
- }; |
- |
- UInt32 size = sizeof(aggregate_device_); |
- OSStatus result = AudioObjectGetPropertyData( |
- plugin_id_, |
- &kDestroyAddress, |
- 0, |
- NULL, |
- &size, |
- &aggregate_device_); |
- if (result != noErr) { |
- DLOG(ERROR) << "Error destroying aggregate audio device!"; |
- return; |
- } |
- |
- aggregate_device_ = kAudioObjectUnknown; |
-} |
- |
-} // namespace media |