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

Side by Side Diff: webrtc/modules/audio_device/ios/voice_processing_audio_unit.mm

Issue 1822543002: Support delayed AudioUnit initialization. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase Created 4 years, 9 months 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
« no previous file with comments | « webrtc/modules/audio_device/ios/voice_processing_audio_unit.h ('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 /* 1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // with as small delay between each. This factor sets the max number of allowed 49 // with as small delay between each. This factor sets the max number of allowed
50 // initialization attempts. 50 // initialization attempts.
51 static const int kMaxNumberOfAudioUnitInitializeAttempts = 5; 51 static const int kMaxNumberOfAudioUnitInitializeAttempts = 5;
52 // A VP I/O unit's bus 1 connects to input hardware (microphone). 52 // A VP I/O unit's bus 1 connects to input hardware (microphone).
53 static const AudioUnitElement kInputBus = 1; 53 static const AudioUnitElement kInputBus = 1;
54 // A VP I/O unit's bus 0 connects to output hardware (speaker). 54 // A VP I/O unit's bus 0 connects to output hardware (speaker).
55 static const AudioUnitElement kOutputBus = 0; 55 static const AudioUnitElement kOutputBus = 0;
56 56
57 VoiceProcessingAudioUnit::VoiceProcessingAudioUnit( 57 VoiceProcessingAudioUnit::VoiceProcessingAudioUnit(
58 VoiceProcessingAudioUnitObserver* observer) 58 VoiceProcessingAudioUnitObserver* observer)
59 : observer_(observer), vpio_unit_(nullptr) { 59 : observer_(observer), vpio_unit_(nullptr), state_(kInitRequired) {
60 RTC_DCHECK(observer); 60 RTC_DCHECK(observer);
61 } 61 }
62 62
63 VoiceProcessingAudioUnit::~VoiceProcessingAudioUnit() { 63 VoiceProcessingAudioUnit::~VoiceProcessingAudioUnit() {
64 DisposeAudioUnit(); 64 DisposeAudioUnit();
65 } 65 }
66 66
67 const UInt32 VoiceProcessingAudioUnit::kBytesPerSample = 2; 67 const UInt32 VoiceProcessingAudioUnit::kBytesPerSample = 2;
68 68
69 bool VoiceProcessingAudioUnit::Init() { 69 bool VoiceProcessingAudioUnit::Init() {
70 RTC_DCHECK(!vpio_unit_) << "Already called Init()."; 70 RTC_DCHECK_EQ(state_, kInitRequired);
71 71
72 // Create an audio component description to identify the Voice Processing 72 // Create an audio component description to identify the Voice Processing
73 // I/O audio unit. 73 // I/O audio unit.
74 AudioComponentDescription vpio_unit_description; 74 AudioComponentDescription vpio_unit_description;
75 vpio_unit_description.componentType = kAudioUnitType_Output; 75 vpio_unit_description.componentType = kAudioUnitType_Output;
76 vpio_unit_description.componentSubType = kAudioUnitSubType_VoiceProcessingIO; 76 vpio_unit_description.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
77 vpio_unit_description.componentManufacturer = kAudioUnitManufacturer_Apple; 77 vpio_unit_description.componentManufacturer = kAudioUnitManufacturer_Apple;
78 vpio_unit_description.componentFlags = 0; 78 vpio_unit_description.componentFlags = 0;
79 vpio_unit_description.componentFlagsMask = 0; 79 vpio_unit_description.componentFlagsMask = 0;
80 80
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 kAudioUnitScope_Global, kInputBus, 158 kAudioUnitScope_Global, kInputBus,
159 &input_callback, sizeof(input_callback)); 159 &input_callback, sizeof(input_callback));
160 if (result != noErr) { 160 if (result != noErr) {
161 DisposeAudioUnit(); 161 DisposeAudioUnit();
162 RTCLogError(@"Failed to specify the input callback on the input bus. " 162 RTCLogError(@"Failed to specify the input callback on the input bus. "
163 "Error=%ld.", 163 "Error=%ld.",
164 (long)result); 164 (long)result);
165 return false; 165 return false;
166 } 166 }
167 167
168 state_ = kUninitialized;
168 return true; 169 return true;
169 } 170 }
170 171
172 VoiceProcessingAudioUnit::State VoiceProcessingAudioUnit::GetState() const {
173 return state_;
174 }
175
171 bool VoiceProcessingAudioUnit::Initialize(Float64 sample_rate) { 176 bool VoiceProcessingAudioUnit::Initialize(Float64 sample_rate) {
172 RTC_DCHECK(vpio_unit_) << "Init() not called."; 177 RTC_DCHECK_GE(state_, kUninitialized);
173 RTCLog(@"Initializing audio unit."); 178 RTCLog(@"Initializing audio unit.");
174 179
175 OSStatus result = noErr; 180 OSStatus result = noErr;
176 AudioStreamBasicDescription format = GetFormat(sample_rate); 181 AudioStreamBasicDescription format = GetFormat(sample_rate);
177 UInt32 size = sizeof(format); 182 UInt32 size = sizeof(format);
178 #if !defined(NDEBUG) 183 #if !defined(NDEBUG)
179 LogStreamDescription(format); 184 LogStreamDescription(format);
180 #endif 185 #endif
181 186
182 // Set the format on the output scope of the input element/bus. 187 // Set the format on the output scope of the input element/bus.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (failed_initalize_attempts == kMaxNumberOfAudioUnitInitializeAttempts) { 222 if (failed_initalize_attempts == kMaxNumberOfAudioUnitInitializeAttempts) {
218 // Max number of initialization attempts exceeded, hence abort. 223 // Max number of initialization attempts exceeded, hence abort.
219 RTCLogError(@"Too many initialization attempts."); 224 RTCLogError(@"Too many initialization attempts.");
220 return false; 225 return false;
221 } 226 }
222 RTCLog(@"Pause 100ms and try audio unit initialization again..."); 227 RTCLog(@"Pause 100ms and try audio unit initialization again...");
223 [NSThread sleepForTimeInterval:0.1f]; 228 [NSThread sleepForTimeInterval:0.1f];
224 result = AudioUnitInitialize(vpio_unit_); 229 result = AudioUnitInitialize(vpio_unit_);
225 } 230 }
226 RTCLog(@"Voice Processing I/O unit is now initialized."); 231 RTCLog(@"Voice Processing I/O unit is now initialized.");
232 state_ = kInitialized;
227 return true; 233 return true;
228 } 234 }
229 235
230 bool VoiceProcessingAudioUnit::Start() { 236 bool VoiceProcessingAudioUnit::Start() {
231 RTC_DCHECK(vpio_unit_) << "Init() not called."; 237 RTC_DCHECK_GE(state_, kUninitialized);
232 RTCLog(@"Starting audio unit."); 238 RTCLog(@"Starting audio unit.");
233 239
234 OSStatus result = AudioOutputUnitStart(vpio_unit_); 240 OSStatus result = AudioOutputUnitStart(vpio_unit_);
235 if (result != noErr) { 241 if (result != noErr) {
236 RTCLogError(@"Failed to start audio unit. Error=%ld", (long)result); 242 RTCLogError(@"Failed to start audio unit. Error=%ld", (long)result);
237 return false; 243 return false;
238 } 244 }
245 state_ = kStarted;
239 return true; 246 return true;
240 } 247 }
241 248
242 bool VoiceProcessingAudioUnit::Stop() { 249 bool VoiceProcessingAudioUnit::Stop() {
243 RTC_DCHECK(vpio_unit_) << "Init() not called."; 250 RTC_DCHECK_GE(state_, kUninitialized);
244 RTCLog(@"Stopping audio unit."); 251 RTCLog(@"Stopping audio unit.");
245 252
246 OSStatus result = AudioOutputUnitStop(vpio_unit_); 253 OSStatus result = AudioOutputUnitStop(vpio_unit_);
247 if (result != noErr) { 254 if (result != noErr) {
248 RTCLogError(@"Failed to stop audio unit. Error=%ld", (long)result); 255 RTCLogError(@"Failed to stop audio unit. Error=%ld", (long)result);
249 return false; 256 return false;
250 } 257 }
258 state_ = kInitialized;
251 return true; 259 return true;
252 } 260 }
253 261
254 bool VoiceProcessingAudioUnit::Uninitialize() { 262 bool VoiceProcessingAudioUnit::Uninitialize() {
255 RTC_DCHECK(vpio_unit_) << "Init() not called."; 263 RTC_DCHECK_GE(state_, kUninitialized);
256 RTCLog(@"Unintializing audio unit."); 264 RTCLog(@"Unintializing audio unit.");
257 265
258 OSStatus result = AudioUnitUninitialize(vpio_unit_); 266 OSStatus result = AudioUnitUninitialize(vpio_unit_);
259 if (result != noErr) { 267 if (result != noErr) {
260 RTCLogError(@"Failed to uninitialize audio unit. Error=%ld", (long)result); 268 RTCLogError(@"Failed to uninitialize audio unit. Error=%ld", (long)result);
261 return false; 269 return false;
262 } 270 }
263 return true; 271 return true;
264 } 272 }
265 273
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 format.mBytesPerPacket = kBytesPerSample; 348 format.mBytesPerPacket = kBytesPerSample;
341 format.mFramesPerPacket = 1; // uncompressed. 349 format.mFramesPerPacket = 1; // uncompressed.
342 format.mBytesPerFrame = kBytesPerSample; 350 format.mBytesPerFrame = kBytesPerSample;
343 format.mChannelsPerFrame = kRTCAudioSessionPreferredNumberOfChannels; 351 format.mChannelsPerFrame = kRTCAudioSessionPreferredNumberOfChannels;
344 format.mBitsPerChannel = 8 * kBytesPerSample; 352 format.mBitsPerChannel = 8 * kBytesPerSample;
345 return format; 353 return format;
346 } 354 }
347 355
348 void VoiceProcessingAudioUnit::DisposeAudioUnit() { 356 void VoiceProcessingAudioUnit::DisposeAudioUnit() {
349 if (vpio_unit_) { 357 if (vpio_unit_) {
358 switch (state_) {
359 case kStarted:
360 Stop();
361 // Fall through.
362 case kInitialized:
363 Uninitialize();
364 break;
365 case kUninitialized:
366 case kInitRequired:
367 break;
368 }
369
350 OSStatus result = AudioComponentInstanceDispose(vpio_unit_); 370 OSStatus result = AudioComponentInstanceDispose(vpio_unit_);
351 if (result != noErr) { 371 if (result != noErr) {
352 RTCLogError(@"AudioComponentInstanceDispose failed. Error=%ld.", 372 RTCLogError(@"AudioComponentInstanceDispose failed. Error=%ld.",
353 (long)result); 373 (long)result);
354 } 374 }
355 vpio_unit_ = nullptr; 375 vpio_unit_ = nullptr;
356 } 376 }
357 } 377 }
358 378
359 } // namespace webrtc 379 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/ios/voice_processing_audio_unit.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698