| 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/mac/scoped_cftyperef.h" |
| 8 #include "base/sys_string_conversions.h" | 9 #include "base/sys_string_conversions.h" |
| 9 #include "media/audio/fake_audio_input_stream.h" | 10 #include "media/audio/fake_audio_input_stream.h" |
| 10 #include "media/audio/fake_audio_output_stream.h" | 11 #include "media/audio/fake_audio_output_stream.h" |
| 11 #include "media/audio/mac/audio_input_mac.h" | 12 #include "media/audio/mac/audio_input_mac.h" |
| 12 #include "media/audio/mac/audio_low_latency_input_mac.h" | 13 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 13 #include "media/audio/mac/audio_low_latency_output_mac.h" | 14 #include "media/audio/mac/audio_low_latency_output_mac.h" |
| 14 #include "media/audio/mac/audio_manager_mac.h" | 15 #include "media/audio/mac/audio_manager_mac.h" |
| 15 #include "media/audio/mac/audio_output_mac.h" | 16 #include "media/audio/mac/audio_output_mac.h" |
| 16 #include "media/base/limits.h" | 17 #include "media/base/limits.h" |
| 17 | 18 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 // We are responsible for releasing the returned CFObject. See the | 176 // We are responsible for releasing the returned CFObject. See the |
| 176 // comment in the AudioHardware.h for constant | 177 // comment in the AudioHardware.h for constant |
| 177 // kAudioDevicePropertyDeviceUID. | 178 // kAudioDevicePropertyDeviceUID. |
| 178 if (uid) | 179 if (uid) |
| 179 CFRelease(uid); | 180 CFRelease(uid); |
| 180 if (name) | 181 if (name) |
| 181 CFRelease(name); | 182 CFRelease(name); |
| 182 } | 183 } |
| 183 } | 184 } |
| 184 | 185 |
| 186 static AudioDeviceID GetAudioDeviceIdByUId(bool is_input, |
| 187 const std::string& device_id) { |
| 188 AudioObjectPropertyAddress property_address = { |
| 189 kAudioHardwarePropertyDevices, |
| 190 kAudioObjectPropertyScopeGlobal, |
| 191 kAudioObjectPropertyElementMaster |
| 192 }; |
| 193 AudioDeviceID audio_device_id = kAudioObjectUnknown; |
| 194 UInt32 device_size = sizeof(audio_device_id); |
| 195 OSStatus result = -1; |
| 196 |
| 197 if (device_id == AudioManagerBase::kDefaultDeviceId) { |
| 198 // Default Device. |
| 199 property_address.mSelector = is_input ? |
| 200 kAudioHardwarePropertyDefaultInputDevice : |
| 201 kAudioHardwarePropertyDefaultOutputDevice; |
| 202 |
| 203 result = AudioObjectGetPropertyData(kAudioObjectSystemObject, |
| 204 &property_address, |
| 205 0, |
| 206 0, |
| 207 &device_size, |
| 208 &audio_device_id); |
| 209 } else { |
| 210 // Non-default device. |
| 211 base::mac::ScopedCFTypeRef<CFStringRef> |
| 212 uid(base::SysUTF8ToCFStringRef(device_id)); |
| 213 AudioValueTranslation value; |
| 214 value.mInputData = &uid; |
| 215 value.mInputDataSize = sizeof(CFStringRef); |
| 216 value.mOutputData = &audio_device_id; |
| 217 value.mOutputDataSize = device_size; |
| 218 UInt32 translation_size = sizeof(AudioValueTranslation); |
| 219 |
| 220 property_address.mSelector = kAudioHardwarePropertyDeviceForUID; |
| 221 result = AudioObjectGetPropertyData(kAudioObjectSystemObject, |
| 222 &property_address, |
| 223 0, |
| 224 0, |
| 225 &translation_size, |
| 226 &value); |
| 227 } |
| 228 |
| 229 if (result) { |
| 230 DLOG(WARNING) << "Unable to query device " << device_id |
| 231 << " for AudioDeviceID "; |
| 232 } |
| 233 |
| 234 return audio_device_id; |
| 235 } |
| 236 |
| 185 AudioManagerMac::AudioManagerMac() | 237 AudioManagerMac::AudioManagerMac() |
| 186 : num_output_streams_(0) { | 238 : num_output_streams_(0) { |
| 187 } | 239 } |
| 188 | 240 |
| 189 AudioManagerMac::~AudioManagerMac() { | 241 AudioManagerMac::~AudioManagerMac() { |
| 190 } | 242 } |
| 191 | 243 |
| 192 bool AudioManagerMac::HasAudioOutputDevices() { | 244 bool AudioManagerMac::HasAudioOutputDevices() { |
| 193 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); | 245 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); |
| 194 } | 246 } |
| 195 | 247 |
| 196 bool AudioManagerMac::HasAudioInputDevices() { | 248 bool AudioManagerMac::HasAudioInputDevices() { |
| 197 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); | 249 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); |
| 198 } | 250 } |
| 199 | 251 |
| 200 void AudioManagerMac::GetAudioInputDeviceNames( | 252 void AudioManagerMac::GetAudioInputDeviceNames( |
| 201 media::AudioDeviceNames* device_names) { | 253 media::AudioDeviceNames* device_names) { |
| 202 // This is needed because AudioObjectGetPropertyDataSize has memory leak | 254 // This is needed because AudioObjectGetPropertyDataSize has memory leak |
| 203 // when there is no soundcard in the machine. | 255 // when there is no soundcard in the machine. |
| 204 if (!HasAudioInputDevices()) | 256 if (!HasAudioInputDevices()) |
| 205 return; | 257 return; |
| 206 | 258 |
| 207 GetAudioDeviceInfo(true, device_names); | 259 GetAudioDeviceInfo(true, device_names); |
| 208 if (!device_names->empty()) { | 260 if (!device_names->empty()) { |
| 209 // Prepend the default device to the list since we always want it to be | 261 // 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 | 262 // 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. | 263 // counting here since the default device has been abstracted out before. |
| 212 media::AudioDeviceName name; | 264 media::AudioDeviceName name; |
| 213 name.device_name = AudioManagerBase::kDefaultDeviceName; | 265 name.device_name = AudioManagerBase::kDefaultDeviceName; |
| 214 name.unique_id = "0"; | 266 name.unique_id = AudioManagerBase::kDefaultDeviceId; |
| 215 device_names->push_front(name); | 267 device_names->push_front(name); |
| 216 } | 268 } |
| 217 } | 269 } |
| 218 | 270 |
| 219 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( | 271 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( |
| 220 const AudioParameters& params) { | 272 const AudioParameters& params) { |
| 221 if (!params.IsValid()) | 273 if (!params.IsValid()) |
| 222 return NULL; | 274 return NULL; |
| 223 | 275 |
| 224 // Limit the number of audio streams opened. This is to prevent using | 276 // Limit the number of audio streams opened. This is to prevent using |
| (...skipping 10 matching lines...) Expand all Loading... |
| 235 num_output_streams_++; | 287 num_output_streams_++; |
| 236 return new PCMQueueOutAudioOutputStream(this, params); | 288 return new PCMQueueOutAudioOutputStream(this, params); |
| 237 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 289 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 238 num_output_streams_++; | 290 num_output_streams_++; |
| 239 return new AUAudioOutputStream(this, params); | 291 return new AUAudioOutputStream(this, params); |
| 240 } | 292 } |
| 241 return NULL; | 293 return NULL; |
| 242 } | 294 } |
| 243 | 295 |
| 244 AudioInputStream* AudioManagerMac::MakeAudioInputStream( | 296 AudioInputStream* AudioManagerMac::MakeAudioInputStream( |
| 245 const AudioParameters& params) { | 297 const AudioParameters& params, const std::string& device_id) { |
| 246 if (!params.IsValid() || (params.channels > kMaxInputChannels)) | 298 if (!params.IsValid() || (params.channels > kMaxInputChannels) || |
| 299 device_id.empty()) |
| 247 return NULL; | 300 return NULL; |
| 248 | 301 |
| 249 if (params.format == AudioParameters::AUDIO_MOCK) { | 302 if (params.format == AudioParameters::AUDIO_MOCK) { |
| 250 return FakeAudioInputStream::MakeFakeStream(params); | 303 return FakeAudioInputStream::MakeFakeStream(params); |
| 251 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { | 304 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { |
| 252 return new PCMQueueInAudioInputStream(this, params); | 305 return new PCMQueueInAudioInputStream(this, params); |
| 253 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 306 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 254 return new AUAudioInputStream(this, params); | 307 // Gets the AudioDeviceID that refers to the AudioDevice with the device |
| 308 // unique id. This AudioDeviceID is used to set the device for Audio Unit. |
| 309 AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id); |
| 310 if (audio_device_id != kAudioObjectUnknown) |
| 311 return new AUAudioInputStream(this, params, audio_device_id); |
| 255 } | 312 } |
| 256 return NULL; | 313 return NULL; |
| 257 } | 314 } |
| 258 | 315 |
| 259 void AudioManagerMac::MuteAll() { | 316 void AudioManagerMac::MuteAll() { |
| 260 // TODO(cpu): implement. | 317 // TODO(cpu): implement. |
| 261 } | 318 } |
| 262 | 319 |
| 263 void AudioManagerMac::UnMuteAll() { | 320 void AudioManagerMac::UnMuteAll() { |
| 264 // TODO(cpu): implement. | 321 // TODO(cpu): implement. |
| 265 } | 322 } |
| 266 | 323 |
| 267 // Called by the stream when it has been released by calling Close(). | 324 // Called by the stream when it has been released by calling Close(). |
| 268 void AudioManagerMac::ReleaseOutputStream(AudioOutputStream* stream) { | 325 void AudioManagerMac::ReleaseOutputStream(AudioOutputStream* stream) { |
| 269 DCHECK(stream); | 326 DCHECK(stream); |
| 270 num_output_streams_--; | 327 num_output_streams_--; |
| 271 delete stream; | 328 delete stream; |
| 272 } | 329 } |
| 273 | 330 |
| 274 // Called by the stream when it has been released by calling Close(). | 331 // Called by the stream when it has been released by calling Close(). |
| 275 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { | 332 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { |
| 276 delete stream; | 333 delete stream; |
| 277 } | 334 } |
| 278 | 335 |
| 279 // static | 336 // static |
| 280 AudioManager* AudioManager::CreateAudioManager() { | 337 AudioManager* AudioManager::CreateAudioManager() { |
| 281 return new AudioManagerMac(); | 338 return new AudioManagerMac(); |
| 282 } | 339 } |
| OLD | NEW |