| 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 "media/audio/mac/audio_low_latency_input_mac.h" | 5 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 6 | 6 |
| 7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 << "channels per frame: " << format.mChannelsPerFrame << std::endl | 22 << "channels per frame: " << format.mChannelsPerFrame << std::endl |
| 23 << "bits per channel : " << format.mBitsPerChannel; | 23 << "bits per channel : " << format.mBitsPerChannel; |
| 24 return os; | 24 return os; |
| 25 } | 25 } |
| 26 | 26 |
| 27 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" | 27 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" |
| 28 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 28 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 29 // for more details and background regarding this implementation. | 29 // for more details and background regarding this implementation. |
| 30 | 30 |
| 31 AUAudioInputStream::AUAudioInputStream( | 31 AUAudioInputStream::AUAudioInputStream( |
| 32 AudioManagerMac* manager, const AudioParameters& params) | 32 AudioManagerMac* manager, const AudioParameters& params, |
| 33 AudioDeviceID audio_device_id) |
| 33 : manager_(manager), | 34 : manager_(manager), |
| 34 sink_(NULL), | 35 sink_(NULL), |
| 35 audio_unit_(0), | 36 audio_unit_(0), |
| 36 input_device_id_(kAudioObjectUnknown), | 37 input_device_id_(audio_device_id), |
| 37 started_(false), | 38 started_(false), |
| 38 hardware_latency_frames_(0) { | 39 hardware_latency_frames_(0) { |
| 39 DCHECK(manager_); | 40 DCHECK(manager_); |
| 40 | 41 |
| 41 // Set up the desired (output) format specified by the client. | 42 // Set up the desired (output) format specified by the client. |
| 42 format_.mSampleRate = params.sample_rate; | 43 format_.mSampleRate = params.sample_rate; |
| 43 format_.mFormatID = kAudioFormatLinearPCM; | 44 format_.mFormatID = kAudioFormatLinearPCM; |
| 44 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | | 45 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | |
| 45 kLinearPCMFormatFlagIsSignedInteger; | 46 kLinearPCMFormatFlagIsSignedInteger; |
| 46 format_.mBitsPerChannel = params.bits_per_sample; | 47 format_.mBitsPerChannel = params.bits_per_sample; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 74 } | 75 } |
| 75 | 76 |
| 76 AUAudioInputStream::~AUAudioInputStream() {} | 77 AUAudioInputStream::~AUAudioInputStream() {} |
| 77 | 78 |
| 78 // Obtain and open the AUHAL AudioOutputUnit for recording. | 79 // Obtain and open the AUHAL AudioOutputUnit for recording. |
| 79 bool AUAudioInputStream::Open() { | 80 bool AUAudioInputStream::Open() { |
| 80 // Verify that we are not already opened. | 81 // Verify that we are not already opened. |
| 81 if (audio_unit_) | 82 if (audio_unit_) |
| 82 return false; | 83 return false; |
| 83 | 84 |
| 85 // Verify that we have a valid device. |
| 86 if (input_device_id_ == kAudioObjectUnknown) |
| 87 return false; |
| 88 |
| 84 // Start by obtaining an AudioOuputUnit using an AUHAL component description. | 89 // Start by obtaining an AudioOuputUnit using an AUHAL component description. |
| 85 | 90 |
| 86 Component comp; | 91 Component comp; |
| 87 ComponentDescription desc; | 92 ComponentDescription desc; |
| 88 | 93 |
| 89 // Description for the Audio Unit we want to use (AUHAL in this case). | 94 // Description for the Audio Unit we want to use (AUHAL in this case). |
| 90 desc.componentType = kAudioUnitType_Output; | 95 desc.componentType = kAudioUnitType_Output; |
| 91 desc.componentSubType = kAudioUnitSubType_HALOutput; | 96 desc.componentSubType = kAudioUnitSubType_HALOutput; |
| 92 desc.componentManufacturer = kAudioUnitManufacturer_Apple; | 97 desc.componentManufacturer = kAudioUnitManufacturer_Apple; |
| 93 desc.componentFlags = 0; | 98 desc.componentFlags = 0; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 kAudioOutputUnitProperty_EnableIO, | 135 kAudioOutputUnitProperty_EnableIO, |
| 131 kAudioUnitScope_Output, | 136 kAudioUnitScope_Output, |
| 132 0, // output element 0 | 137 0, // output element 0 |
| 133 &enableIO, // disable | 138 &enableIO, // disable |
| 134 sizeof(enableIO)); | 139 sizeof(enableIO)); |
| 135 if (result) { | 140 if (result) { |
| 136 HandleError(result); | 141 HandleError(result); |
| 137 return false; | 142 return false; |
| 138 } | 143 } |
| 139 | 144 |
| 140 // Set the current device of the AudioOuputUnit to default input device. | |
| 141 | |
| 142 // First, obtain the current input device selected by the user. | |
| 143 AudioObjectPropertyAddress default_intput_device_address = { | |
| 144 kAudioHardwarePropertyDefaultInputDevice, | |
| 145 kAudioObjectPropertyScopeGlobal, | |
| 146 kAudioObjectPropertyElementMaster | |
| 147 }; | |
| 148 AudioDeviceID input_device = kAudioObjectUnknown; | |
| 149 UInt32 size = sizeof(input_device); | |
| 150 result = AudioObjectGetPropertyData(kAudioObjectSystemObject, | |
| 151 &default_intput_device_address, | |
| 152 0, | |
| 153 0, | |
| 154 &size, | |
| 155 &input_device); | |
| 156 if (result) { | |
| 157 HandleError(result); | |
| 158 return false; | |
| 159 } | |
| 160 | |
| 161 input_device_id_ = input_device; | |
| 162 | |
| 163 // Next, set the audio device to be the Audio Unit's current device. | 145 // Next, set the audio device to be the Audio Unit's current device. |
| 164 // Note that, devices can only be set to the AUHAL after enabling IO. | 146 // Note that, devices can only be set to the AUHAL after enabling IO. |
| 165 result = AudioUnitSetProperty(audio_unit_, | 147 result = AudioUnitSetProperty(audio_unit_, |
| 166 kAudioOutputUnitProperty_CurrentDevice, | 148 kAudioOutputUnitProperty_CurrentDevice, |
| 167 kAudioUnitScope_Global, | 149 kAudioUnitScope_Global, |
| 168 0, | 150 0, |
| 169 &input_device_id_, | 151 &input_device_id_, |
| 170 sizeof(input_device)); | 152 sizeof(input_device_id_)); |
| 171 if (result) { | 153 if (result) { |
| 172 HandleError(result); | 154 HandleError(result); |
| 173 return false; | 155 return false; |
| 174 } | 156 } |
| 175 | 157 |
| 176 // Register the input procedure for the AUHAL. | 158 // Register the input procedure for the AUHAL. |
| 177 // This procedure will be called when the AUHAL has received new data | 159 // This procedure will be called when the AUHAL has received new data |
| 178 // from the input device. | 160 // from the input device. |
| 179 AURenderCallbackStruct callback; | 161 AURenderCallbackStruct callback; |
| 180 callback.inputProc = InputProc; | 162 callback.inputProc = InputProc; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 // Total latency is composed by the dynamic latency and the fixed | 432 // Total latency is composed by the dynamic latency and the fixed |
| 451 // hardware latency. | 433 // hardware latency. |
| 452 return (delay_frames + hardware_latency_frames_); | 434 return (delay_frames + hardware_latency_frames_); |
| 453 } | 435 } |
| 454 | 436 |
| 455 void AUAudioInputStream::HandleError(OSStatus err) { | 437 void AUAudioInputStream::HandleError(OSStatus err) { |
| 456 NOTREACHED() << "error code: " << err; | 438 NOTREACHED() << "error code: " << err; |
| 457 if (sink_) | 439 if (sink_) |
| 458 sink_->OnError(this, static_cast<int>(err)); | 440 sink_->OnError(this, static_cast<int>(err)); |
| 459 } | 441 } |
| OLD | NEW |