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

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

Issue 8276034: This patch will loop through the soundcard and return a list of available devices when the AudioI... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: fixed the tests and updated code based on comment from Avi Created 9 years, 1 month 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 | « media/audio/audio_input_device_unittest.cc ('k') | 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 <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
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 property_address.mScope = is_input ?
110 kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
111 property_address.mSelector = kAudioDevicePropertyStreamConfiguration;
112 result = AudioObjectGetPropertyDataSize(device_ids[i],
113 &property_address,
114 0,
115 NULL,
116 &size);
117 if (result)
118 continue;
119
120 scoped_ptr_malloc<AudioBufferList>
121 buffer(reinterpret_cast<AudioBufferList*>(malloc(size)));
122 AudioBufferList* buffer_list = buffer.get();
123 result = AudioObjectGetPropertyData(device_ids[i],
124 &property_address,
125 0,
126 NULL,
127 &size,
128 buffer_list);
129 if (result)
130 continue;
131
132 for (uint32 j = 0; j < buffer_list->mNumberBuffers; ++j)
133 channels += buffer_list->mBuffers[j].mNumberChannels;
134
135 // Exclude those devices without the type of channel we are interested in.
136 if (!channels)
137 continue;
138
139 // Get device UID.
140 CFStringRef uid = NULL;
141 size = sizeof(uid);
142 property_address.mSelector = kAudioDevicePropertyDeviceUID;
143 property_address.mScope = kAudioObjectPropertyScopeGlobal;
144 result = AudioObjectGetPropertyData(device_ids[i],
145 &property_address,
146 0,
147 NULL,
148 &size,
149 &uid);
150 if (result)
151 continue;
152
153 // Get device name.
154 CFStringRef name = NULL;
155 property_address.mSelector = kAudioObjectPropertyName;
156 property_address.mScope = kAudioObjectPropertyScopeGlobal;
157 result = AudioObjectGetPropertyData(device_ids[i],
158 &property_address,
159 0,
160 NULL,
161 &size,
162 &name);
163 if (result) {
164 if (uid)
165 CFRelease(uid);
166 continue;
167 }
168
169 // Store the device name and UID.
170 media::AudioDeviceName device_name;
171 device_name.device_name = base::SysCFStringRefToUTF8(name);
172 device_name.unique_id = base::SysCFStringRefToUTF8(uid);
173 device_names->push_back(device_name);
174
175 // We are responsible for releasing the returned CFObject. See the
176 // comment in the AudioHardware.h for constant
177 // kAudioDevicePropertyDeviceUID.
178 if (uid)
179 CFRelease(uid);
180 if (name)
181 CFRelease(name);
182 }
183 }
184
68 AudioManagerMac::AudioManagerMac() 185 AudioManagerMac::AudioManagerMac()
69 : num_output_streams_(0) { 186 : num_output_streams_(0) {
70 } 187 }
71 188
72 AudioManagerMac::~AudioManagerMac() { 189 AudioManagerMac::~AudioManagerMac() {
73 } 190 }
74 191
75 bool AudioManagerMac::HasAudioOutputDevices() { 192 bool AudioManagerMac::HasAudioOutputDevices() {
76 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); 193 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
77 } 194 }
78 195
79 bool AudioManagerMac::HasAudioInputDevices() { 196 bool AudioManagerMac::HasAudioInputDevices() {
80 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); 197 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice);
81 } 198 }
82 199
83 void AudioManagerMac::GetAudioInputDeviceNames( 200 void AudioManagerMac::GetAudioInputDeviceNames(
84 media::AudioDeviceNames* device_names) { 201 media::AudioDeviceNames* device_names) {
85 // TODO(xians): query a full list of valid devices. 202 // This is needed because AudioObjectGetPropertyDataSize has memory leak
86 if (HasAudioInputDevices()) { 203 // when there is no soundcard in the machine.
87 // Add the default device to the list. 204 if (!HasAudioInputDevices())
88 // We use index 0 to make up the unique_id to identify the 205 return;
89 // default devices. 206
207 GetAudioDeviceInfo(true, device_names);
208 if (!device_names->empty()) {
209 // Prepend the default device to the list since we always want it to be
210 // on the top of the list for all platforms. There is no duplicate
211 // counting here since the default device has been abstracted out before.
90 media::AudioDeviceName name; 212 media::AudioDeviceName name;
91 name.device_name = AudioManagerBase::kDefaultDeviceName; 213 name.device_name = AudioManagerBase::kDefaultDeviceName;
92 name.unique_id = "0"; 214 name.unique_id = "0";
93 device_names->push_back(name); 215 device_names->push_front(name);
94 } 216 }
95 } 217 }
96 218
97 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( 219 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
98 const AudioParameters& params) { 220 const AudioParameters& params) {
99 if (!params.IsValid()) 221 if (!params.IsValid())
100 return NULL; 222 return NULL;
101 223
102 // Limit the number of audio streams opened. This is to prevent using 224 // Limit the number of audio streams opened. This is to prevent using
103 // excessive resources for a large number of audio streams. More 225 // excessive resources for a large number of audio streams. More
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 273
152 // Called by the stream when it has been released by calling Close(). 274 // Called by the stream when it has been released by calling Close().
153 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { 275 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) {
154 delete stream; 276 delete stream;
155 } 277 }
156 278
157 // static 279 // static
158 AudioManager* AudioManager::CreateAudioManager() { 280 AudioManager* AudioManager::CreateAudioManager() {
159 return new AudioManagerMac(); 281 return new AudioManagerMac();
160 } 282 }
OLDNEW
« no previous file with comments | « media/audio/audio_input_device_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698