Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <CoreAudio/AudioHardware.h> | 5 #include <CoreAudio/AudioHardware.h> |
| 6 | 6 |
| 7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
| 8 #include "base/sys_string_conversions.h" | |
| 8 #include "media/audio/fake_audio_input_stream.h" | 9 #include "media/audio/fake_audio_input_stream.h" |
| 9 #include "media/audio/fake_audio_output_stream.h" | 10 #include "media/audio/fake_audio_output_stream.h" |
| 10 #include "media/audio/mac/audio_input_mac.h" | 11 #include "media/audio/mac/audio_input_mac.h" |
| 11 #include "media/audio/mac/audio_low_latency_input_mac.h" | 12 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 12 #include "media/audio/mac/audio_low_latency_output_mac.h" | 13 #include "media/audio/mac/audio_low_latency_output_mac.h" |
| 13 #include "media/audio/mac/audio_manager_mac.h" | 14 #include "media/audio/mac/audio_manager_mac.h" |
| 14 #include "media/audio/mac/audio_output_mac.h" | 15 #include "media/audio/mac/audio_output_mac.h" |
| 15 #include "media/base/limits.h" | 16 #include "media/base/limits.h" |
| 16 | 17 |
| 17 static const int kMaxInputChannels = 2; | 18 static const int kMaxInputChannels = 2; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, | 59 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, |
| 59 &property_address, | 60 &property_address, |
| 60 0, // inQualifierDataSize | 61 0, // inQualifierDataSize |
| 61 NULL, // inQualifierData | 62 NULL, // inQualifierData |
| 62 &output_device_id_size, | 63 &output_device_id_size, |
| 63 &output_device_id); | 64 &output_device_id); |
| 64 return err == kAudioHardwareNoError && | 65 return err == kAudioHardwareNoError && |
| 65 output_device_id != kAudioObjectUnknown; | 66 output_device_id != kAudioObjectUnknown; |
| 66 } | 67 } |
| 67 | 68 |
| 69 static void GetAudioDeviceInfo(bool is_input, | |
| 70 media::AudioDeviceNames* device_names) { | |
| 71 DCHECK(device_names); | |
| 72 device_names->clear(); | |
| 73 | |
| 74 // Query the number of total devices. | |
| 75 AudioObjectPropertyAddress property_address = { | |
| 76 kAudioHardwarePropertyDevices, | |
| 77 kAudioObjectPropertyScopeGlobal, | |
| 78 kAudioObjectPropertyElementMaster | |
| 79 }; | |
| 80 UInt32 size = 0; | |
| 81 OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, | |
| 82 &property_address, | |
| 83 0, | |
| 84 NULL, | |
| 85 &size); | |
| 86 if (result || !size) | |
| 87 return; | |
| 88 | |
| 89 int device_count = size / sizeof(AudioDeviceID); | |
| 90 | |
| 91 // Get the array of device ids for all the devices, which includes both | |
| 92 // input devices and output devices. | |
| 93 scoped_ptr_malloc<AudioDeviceID> | |
| 94 devices(reinterpret_cast<AudioDeviceID*>(malloc(size))); | |
| 95 AudioDeviceID* device_ids = devices.get(); | |
| 96 result = AudioObjectGetPropertyData(kAudioObjectSystemObject, | |
| 97 &property_address, | |
| 98 0, | |
| 99 NULL, | |
| 100 &size, | |
| 101 device_ids); | |
| 102 if (result) | |
| 103 return; | |
| 104 | |
| 105 // Iterate over all available devices to gather information. | |
| 106 for (int i = 0; i < device_count; ++i) { | |
| 107 int channels = 0; | |
| 108 // Get the number of input or output channels of the device. | |
| 109 AudioDeviceGetPropertyInfo(device_ids[i], | |
|
Avi (use Gerrit)
2011/10/26 21:44:25
obsolete
| |
| 110 0, | |
| 111 is_input, | |
| 112 kAudioDevicePropertyStreamConfiguration, | |
| 113 &size, | |
| 114 NULL); | |
| 115 scoped_ptr_malloc<AudioBufferList> | |
| 116 buffer(reinterpret_cast<AudioBufferList*>(malloc(size))); | |
| 117 AudioBufferList* buffer_list = buffer.get(); | |
| 118 AudioDeviceGetProperty(device_ids[i], | |
|
Avi (use Gerrit)
2011/10/26 21:44:25
obsolete
| |
| 119 0, | |
| 120 is_input, | |
| 121 kAudioDevicePropertyStreamConfiguration, | |
| 122 &size, | |
| 123 buffer_list); | |
| 124 | |
| 125 for (uint32 j = 0; j < buffer_list->mNumberBuffers; ++j) | |
| 126 channels += buffer_list->mBuffers[j].mNumberChannels; | |
| 127 | |
| 128 // Exclude those devices without the type of channel we are interested in. | |
| 129 if (!channels) | |
| 130 continue; | |
| 131 | |
| 132 // Get device UID. | |
| 133 CFStringRef uid = NULL; | |
| 134 size = sizeof(uid); | |
| 135 result = AudioDeviceGetProperty(device_ids[i], | |
|
Avi (use Gerrit)
2011/10/26 21:44:25
AudioDeviceGetProperty is deprecated (see TN2223),
| |
| 136 0, | |
| 137 is_input, | |
| 138 kAudioDevicePropertyDeviceUID, | |
| 139 &size, | |
| 140 &uid); | |
| 141 if (result) | |
| 142 continue; | |
| 143 | |
| 144 // Get device name. | |
| 145 CFStringRef name = NULL; | |
| 146 result = AudioDeviceGetProperty(device_ids[i], | |
|
Avi (use Gerrit)
2011/10/26 21:44:25
obsolete
| |
| 147 0, | |
| 148 is_input, | |
| 149 kAudioObjectPropertyName, | |
| 150 &size, | |
| 151 &name); | |
| 152 if (result) | |
| 153 continue; | |
| 154 | |
| 155 // Store the device name and UID. | |
| 156 media::AudioDeviceName device_name; | |
| 157 device_name.device_name = base::SysCFStringRefToUTF8(name); | |
| 158 device_name.unique_id = base::SysCFStringRefToUTF8(uid); | |
| 159 device_names->push_back(device_name); | |
| 160 } | |
|
Chris Rogers
2011/10/26 18:52:44
I believe you have a memory leak here, since you n
no longer working on chromium
2011/10/26 21:33:09
Thanks, you are right, there is a leak there. It f
Avi (use Gerrit)
2011/10/26 21:44:25
I'm a little confused on why. Does AudioDeviceGetP
Chris Rogers
2011/10/26 21:49:44
It's documented in AudioHardware.h in the discussi
| |
| 161 } | |
| 162 | |
| 68 AudioManagerMac::AudioManagerMac() | 163 AudioManagerMac::AudioManagerMac() |
| 69 : num_output_streams_(0) { | 164 : num_output_streams_(0) { |
| 70 } | 165 } |
| 71 | 166 |
| 72 AudioManagerMac::~AudioManagerMac() { | 167 AudioManagerMac::~AudioManagerMac() { |
| 73 } | 168 } |
| 74 | 169 |
| 75 bool AudioManagerMac::HasAudioOutputDevices() { | 170 bool AudioManagerMac::HasAudioOutputDevices() { |
| 76 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); | 171 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); |
| 77 } | 172 } |
| 78 | 173 |
| 79 bool AudioManagerMac::HasAudioInputDevices() { | 174 bool AudioManagerMac::HasAudioInputDevices() { |
| 80 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); | 175 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); |
| 81 } | 176 } |
| 82 | 177 |
| 83 void AudioManagerMac::GetAudioInputDeviceNames( | 178 void AudioManagerMac::GetAudioInputDeviceNames( |
| 84 media::AudioDeviceNames* device_names) { | 179 media::AudioDeviceNames* device_names) { |
| 85 // TODO(xians): query a full list of valid devices. | 180 GetAudioDeviceInfo(true, device_names); |
| 86 if (HasAudioInputDevices()) { | 181 if (!device_names->empty()) { |
| 87 // Add the default device to the list. | 182 // Prepend the default device to the list since we always want it to be |
| 88 // We use index 0 to make up the unique_id to identify the | 183 // on the top of the list for all platforms. There is no duplicate |
| 89 // default devices. | 184 // counting here since the default device has been abstracted out before. |
| 90 media::AudioDeviceName name; | 185 media::AudioDeviceName name; |
| 91 name.device_name = AudioManagerBase::kDefaultDeviceName; | 186 name.device_name = AudioManagerBase::kDefaultDeviceName; |
| 92 name.unique_id = "0"; | 187 name.unique_id = "0"; |
| 93 device_names->push_back(name); | 188 device_names->push_front(name); |
| 94 } | 189 } |
| 95 } | 190 } |
| 96 | 191 |
| 97 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( | 192 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( |
| 98 const AudioParameters& params) { | 193 const AudioParameters& params) { |
| 99 if (!params.IsValid()) | 194 if (!params.IsValid()) |
| 100 return NULL; | 195 return NULL; |
| 101 | 196 |
| 102 // Limit the number of audio streams opened. This is to prevent using | 197 // Limit the number of audio streams opened. This is to prevent using |
| 103 // excessive resources for a large number of audio streams. More | 198 // excessive resources for a large number of audio streams. More |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 | 246 |
| 152 // Called by the stream when it has been released by calling Close(). | 247 // Called by the stream when it has been released by calling Close(). |
| 153 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { | 248 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { |
| 154 delete stream; | 249 delete stream; |
| 155 } | 250 } |
| 156 | 251 |
| 157 // static | 252 // static |
| 158 AudioManager* AudioManager::CreateAudioManager() { | 253 AudioManager* AudioManager::CreateAudioManager() { |
| 159 return new AudioManagerMac(); | 254 return new AudioManagerMac(); |
| 160 } | 255 } |
| OLD | NEW |