1 /*
2 Copyright (C) 2016 Apple Inc. All Rights Reserved.
3 See LICENSE.txt for this sample’s licensing information
4 
5 Abstract:
6 Part of Core Audio AUBase Classes
7 */
8 
9 #include "AUPlugInDispatch.h"
10 #include "CAXException.h"
11 #include "ComponentBase.h"
12 #include "AUBase.h"
13 
14 #define ACPI ((AudioComponentPlugInInstance *)self)
15 #define AUI	((AUBase *)&ACPI->mInstanceStorage)
16 
17 #define AUI_LOCK CAMutex::Locker auLock(AUI->GetMutex());
18 
19 // ------------------------------------------------------------------------------------------------
AUMethodInitialize(void * self)20 static OSStatus AUMethodInitialize(void *self)
21 {
22 	OSStatus result = noErr;
23 	try {
24 		AUI_LOCK
25 		result = AUI->DoInitialize();
26 	}
27 	COMPONENT_CATCH
28 	return result;
29 }
30 
AUMethodUninitialize(void * self)31 static OSStatus AUMethodUninitialize(void *self)
32 {
33 	OSStatus result = noErr;
34 	try {
35 		AUI_LOCK
36 		AUI->DoCleanup();
37 	}
38 	COMPONENT_CATCH
39 	return result;
40 }
41 
AUMethodGetPropertyInfo(void * self,AudioUnitPropertyID prop,AudioUnitScope scope,AudioUnitElement elem,UInt32 * outDataSize,Boolean * outWritable)42 static OSStatus AUMethodGetPropertyInfo(void *self, AudioUnitPropertyID prop, AudioUnitScope scope, AudioUnitElement elem, UInt32 *outDataSize, Boolean *outWritable)
43 {
44 	OSStatus result = noErr;
45 	try {
46 		UInt32 dataSize = 0;        // 13517289 GetPropetyInfo was returning an uninitialized value when there is an error. This is a problem for auval.
47 		Boolean writable = false;
48 
49 		AUI_LOCK
50 		result = AUI->DispatchGetPropertyInfo(prop, scope, elem, dataSize, writable);
51 		if (outDataSize != NULL)
52 			*outDataSize = dataSize;
53 		if (outWritable != NULL)
54 			*outWritable = writable;
55 	}
56 	COMPONENT_CATCH
57 	return result;
58 }
59 
AUMethodGetProperty(void * self,AudioUnitPropertyID inID,AudioUnitScope inScope,AudioUnitElement inElement,void * outData,UInt32 * ioDataSize)60 static OSStatus AUMethodGetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void *outData, UInt32 *ioDataSize)
61 {
62 	OSStatus result = noErr;
63 	try {
64 		UInt32 actualPropertySize, clientBufferSize;
65 		Boolean writable;
66 		char *tempBuffer;
67 		void *destBuffer;
68 
69 		AUI_LOCK
70 		if (ioDataSize == NULL) {
71 			ca_debug_string("AudioUnitGetProperty: null size pointer");
72 			result = kAudio_ParamError;
73 			goto finishGetProperty;
74 		}
75 		if (outData == NULL) {
76 			UInt32 dataSize;
77 
78 			result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, dataSize, writable);
79 			*ioDataSize = dataSize;
80 			goto finishGetProperty;
81 		}
82 
83 		clientBufferSize = *ioDataSize;
84 		if (clientBufferSize == 0)
85 		{
86 			ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry");
87 			// $$$ or should we allow this as a shortcut for finding the size?
88 			result = kAudio_ParamError;
89 			goto finishGetProperty;
90 		}
91 
92 		result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, actualPropertySize, writable);
93 		if (result != noErr)
94 			goto finishGetProperty;
95 
96 		if (clientBufferSize < actualPropertySize)
97 		{
98 			tempBuffer = new char[actualPropertySize];
99 			destBuffer = tempBuffer;
100 		} else {
101 			tempBuffer = NULL;
102 			destBuffer = outData;
103 		}
104 
105 		result = AUI->DispatchGetProperty(inID, inScope, inElement, destBuffer);
106 
107 		if (result == noErr) {
108 			if (clientBufferSize < actualPropertySize && tempBuffer != NULL)
109 			{
110 				memcpy(outData, tempBuffer, clientBufferSize);
111 				delete[] tempBuffer;
112 				// ioDataSize remains correct, the number of bytes we wrote
113 			} else
114 				*ioDataSize = actualPropertySize;
115 		} else
116 			*ioDataSize = 0;
117 	}
118 	COMPONENT_CATCH
119 finishGetProperty:
120 	return result;
121 }
122 
AUMethodSetProperty(void * self,AudioUnitPropertyID inID,AudioUnitScope inScope,AudioUnitElement inElement,const void * inData,UInt32 inDataSize)123 static OSStatus AUMethodSetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void *inData, UInt32 inDataSize)
124 {
125 	OSStatus result = noErr;
126 	try {
127 		AUI_LOCK
128 		if (inData && inDataSize)
129 			result = AUI->DispatchSetProperty(inID, inScope, inElement, inData, inDataSize);
130 		else {
131 			if (inData == NULL && inDataSize == 0) {
132 				result = AUI->DispatchRemovePropertyValue(inID, inScope, inElement);
133 			} else {
134 				if (inData == NULL) {
135 					ca_debug_string("AudioUnitSetProperty: inData == NULL");
136 					result = kAudio_ParamError;
137 					goto finishSetProperty;
138 				}
139 
140 				if (inDataSize == 0) {
141 					ca_debug_string("AudioUnitSetProperty: inDataSize == 0");
142 					result = kAudio_ParamError;
143 					goto finishSetProperty;
144 				}
145 			}
146 		}
147 	}
148 	COMPONENT_CATCH
149 finishSetProperty:
150 	return result;
151 }
152 
AUMethodAddPropertyListener(void * self,AudioUnitPropertyID prop,AudioUnitPropertyListenerProc proc,void * userData)153 static OSStatus AUMethodAddPropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData)
154 {
155 	OSStatus result = noErr;
156 	try {
157 		AUI_LOCK
158 		result = AUI->AddPropertyListener(prop, proc, userData);
159 	}
160 	COMPONENT_CATCH
161 	return result;
162 }
163 
AUMethodRemovePropertyListener(void * self,AudioUnitPropertyID prop,AudioUnitPropertyListenerProc proc)164 static OSStatus AUMethodRemovePropertyListener(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc)
165 {
166 	OSStatus result = noErr;
167 	try {
168 		AUI_LOCK
169 		result = AUI->RemovePropertyListener(prop, proc, NULL, false);
170 	}
171 	COMPONENT_CATCH
172 	return result;
173 }
174 
AUMethodRemovePropertyListenerWithUserData(void * self,AudioUnitPropertyID prop,AudioUnitPropertyListenerProc proc,void * userData)175 static OSStatus AUMethodRemovePropertyListenerWithUserData(void *self, AudioUnitPropertyID prop, AudioUnitPropertyListenerProc proc, void *userData)
176 {
177 	OSStatus result = noErr;
178 	try {
179 		AUI_LOCK
180 		result = AUI->RemovePropertyListener(prop, proc, userData, true);
181 	}
182 	COMPONENT_CATCH
183 	return result;
184 }
185 
AUMethodAddRenderNotify(void * self,AURenderCallback proc,void * userData)186 static OSStatus AUMethodAddRenderNotify(void *self, AURenderCallback proc, void *userData)
187 {
188 	OSStatus result = noErr;
189 	try {
190 		AUI_LOCK
191 		result = AUI->SetRenderNotification(proc, userData);
192 	}
193 	COMPONENT_CATCH
194 	return result;
195 }
196 
AUMethodRemoveRenderNotify(void * self,AURenderCallback proc,void * userData)197 static OSStatus AUMethodRemoveRenderNotify(void *self, AURenderCallback proc, void *userData)
198 {
199 	OSStatus result = noErr;
200 	try {
201 		AUI_LOCK
202 		result = AUI->RemoveRenderNotification(proc, userData);
203 	}
204 	COMPONENT_CATCH
205 	return result;
206 }
207 
AUMethodGetParameter(void * self,AudioUnitParameterID param,AudioUnitScope scope,AudioUnitElement elem,AudioUnitParameterValue * value)208 static OSStatus AUMethodGetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue *value)
209 {
210 	OSStatus result = noErr;
211 	try {
212 		AUI_LOCK
213 		result = (value == NULL ? kAudio_ParamError : AUI->GetParameter(param, scope, elem, *value));
214 	}
215 	COMPONENT_CATCH
216 	return result;
217 }
218 
AUMethodSetParameter(void * self,AudioUnitParameterID param,AudioUnitScope scope,AudioUnitElement elem,AudioUnitParameterValue value,UInt32 bufferOffset)219 static OSStatus AUMethodSetParameter(void *self, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement elem, AudioUnitParameterValue value, UInt32 bufferOffset)
220 {
221 	OSStatus result = noErr;
222 	try {
223 		// this is a (potentially) realtime method; no lock
224 		result = AUI->SetParameter(param, scope, elem, value, bufferOffset);
225 	}
226 	COMPONENT_CATCH
227 	return result;
228 }
229 
AUMethodScheduleParameters(void * self,const AudioUnitParameterEvent * events,UInt32 numEvents)230 static OSStatus AUMethodScheduleParameters(void *self, const AudioUnitParameterEvent *events, UInt32 numEvents)
231 {
232 	OSStatus result = noErr;
233 	try {
234 		// this is a (potentially) realtime method; no lock
235 		result = AUI->ScheduleParameter(events, numEvents);
236 	}
237 	COMPONENT_CATCH
238 	return result;
239 }
240 
AUMethodRender(void * self,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inOutputBusNumber,UInt32 inNumberFrames,AudioBufferList * ioData)241 static OSStatus AUMethodRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
242 {
243 	OSStatus result = noErr;
244 
245 #if !TARGET_OS_IPHONE
246 	try {
247 #endif
248 		// this is a processing method; no lock
249 		AudioUnitRenderActionFlags tempFlags;
250 
251 		if (inTimeStamp == NULL || ioData == NULL)
252 			result = kAudio_ParamError;
253 		else {
254 			if (ioActionFlags == NULL) {
255 				tempFlags = 0;
256 				ioActionFlags = &tempFlags;
257 			}
258 			result = AUI->DoRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberFrames, *ioData);
259 		}
260 
261 #if !TARGET_OS_IPHONE
262 	}
263 	COMPONENT_CATCH
264 #endif
265 
266 	return result;
267 }
268 
AUMethodComplexRender(void * self,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inOutputBusNumber,UInt32 inNumberOfPackets,UInt32 * outNumberOfPackets,AudioStreamPacketDescription * outPacketDescriptions,AudioBufferList * ioData,void * outMetadata,UInt32 * outMetadataByteSize)269 static OSStatus AUMethodComplexRender(void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberOfPackets, UInt32 *outNumberOfPackets, AudioStreamPacketDescription *outPacketDescriptions, AudioBufferList *ioData, void *outMetadata, UInt32 *outMetadataByteSize)
270 {
271 	OSStatus result = noErr;
272 
273 #if !TARGET_OS_IPHONE
274 	try {
275 #endif
276 		// this is a processing method; no lock
277 		AudioUnitRenderActionFlags tempFlags;
278 
279 		if (inTimeStamp == NULL || ioData == NULL)
280 			result = kAudio_ParamError;
281 		else {
282 			if (ioActionFlags == NULL) {
283 				tempFlags = 0;
284 				ioActionFlags = &tempFlags;
285 			}
286 			result = AUI->ComplexRender(*ioActionFlags, *inTimeStamp, inOutputBusNumber, inNumberOfPackets, outNumberOfPackets, outPacketDescriptions, *ioData, outMetadata, outMetadataByteSize);
287 		}
288 
289 #if !TARGET_OS_IPHONE
290 	}
291 	COMPONENT_CATCH
292 #endif
293 
294 	return result;
295 }
296 
AUMethodReset(void * self,AudioUnitScope scope,AudioUnitElement elem)297 static OSStatus AUMethodReset(void *self, AudioUnitScope scope, AudioUnitElement elem)
298 {
299 	OSStatus result = noErr;
300 	try {
301 		AUI_LOCK
302 		result = AUI->Reset(scope, elem);
303 	}
304 	COMPONENT_CATCH
305 	return result;
306 }
307 
AUMethodProcess(void * self,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inNumberFrames,AudioBufferList * ioData)308 static OSStatus AUMethodProcess (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData)
309 {
310 	OSStatus result = noErr;
311 
312 #if !TARGET_OS_IPHONE
313 	try {
314 #endif
315 		// this is a processing method; no lock
316 		bool doParamCheck = true;
317 
318 		AudioUnitRenderActionFlags tempFlags;
319 
320 		if (ioActionFlags == NULL) {
321 			tempFlags = 0;
322 			ioActionFlags = &tempFlags;
323 		} else {
324 			if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)
325 				doParamCheck = false;
326 		}
327 
328 		if (doParamCheck && (inTimeStamp == NULL || ioData == NULL))
329 			result = kAudio_ParamError;
330 		else {
331 			result = AUI->DoProcess(*ioActionFlags, *inTimeStamp, inNumberFrames, *ioData);
332 		}
333 
334 #if !TARGET_OS_IPHONE
335 	}
336 	COMPONENT_CATCH
337 #endif
338 
339 	return result;
340 }
341 
AUMethodProcessMultiple(void * self,AudioUnitRenderActionFlags * ioActionFlags,const AudioTimeStamp * inTimeStamp,UInt32 inNumberFrames,UInt32 inNumberInputBufferLists,const AudioBufferList ** inInputBufferLists,UInt32 inNumberOutputBufferLists,AudioBufferList ** ioOutputBufferLists)342 static OSStatus AUMethodProcessMultiple (void *self, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, UInt32 inNumberInputBufferLists, const AudioBufferList **inInputBufferLists, UInt32 inNumberOutputBufferLists, AudioBufferList **ioOutputBufferLists)
343 {
344 	OSStatus result = noErr;
345 
346 #if !TARGET_OS_IPHONE
347 	try {
348 #endif
349 		// this is a processing method; no lock
350 		bool doParamCheck = true;
351 
352 		AudioUnitRenderActionFlags tempFlags;
353 
354 		if (ioActionFlags == NULL) {
355 			tempFlags = 0;
356 			ioActionFlags = &tempFlags;
357 		} else {
358 			if (*ioActionFlags & (1 << 9)/*kAudioUnitRenderAction_DoNotCheckRenderArgs*/)
359 				doParamCheck = false;
360 		}
361 
362 		if (doParamCheck && (inTimeStamp == NULL || inInputBufferLists == NULL || ioOutputBufferLists == NULL))
363 			result = kAudio_ParamError;
364 		else {
365 			result = AUI->DoProcessMultiple(*ioActionFlags, *inTimeStamp, inNumberFrames, inNumberInputBufferLists, inInputBufferLists, inNumberOutputBufferLists, ioOutputBufferLists);
366 		}
367 
368 #if !TARGET_OS_IPHONE
369 	}
370 	COMPONENT_CATCH
371 #endif
372 
373 	return result;
374 }
375 // ------------------------------------------------------------------------------------------------
376 
AUMethodStart(void * self)377 static OSStatus AUMethodStart(void *self)
378 {
379 	OSStatus result = noErr;
380 	try {
381 		AUI_LOCK
382 		result = AUI->Start();
383 	}
384 	COMPONENT_CATCH
385 	return result;
386 }
387 
AUMethodStop(void * self)388 static OSStatus AUMethodStop(void *self)
389 {
390 	OSStatus result = noErr;
391 	try {
392 		AUI_LOCK
393 		result = AUI->Stop();
394 	}
395 	COMPONENT_CATCH
396 	return result;
397 }
398 
399 // ------------------------------------------------------------------------------------------------
400 
401 #if !CA_BASIC_AU_FEATURES
402 // I don't know what I'm doing here; conflicts with the multiple inheritence in MusicDeviceBase.
AUMethodMIDIEvent(void * self,UInt32 inStatus,UInt32 inData1,UInt32 inData2,UInt32 inOffsetSampleFrame)403 static OSStatus AUMethodMIDIEvent(void *self, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
404 {
405 	OSStatus result = noErr;
406 	try {
407 		// this is a potential render-time method; no lock
408 		result = AUI->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
409 	}
410 	COMPONENT_CATCH
411 	return result;
412 }
413 
AUMethodSysEx(void * self,const UInt8 * inData,UInt32 inLength)414 static OSStatus AUMethodSysEx(void *self, const UInt8 *inData, UInt32 inLength)
415 {
416 	OSStatus result = noErr;
417 	try {
418 		// this is a potential render-time method; no lock
419 		result = AUI->SysEx(inData, inLength);
420 	}
421 	COMPONENT_CATCH
422 	return result;
423 }
424 
AUMethodStartNote(void * self,MusicDeviceInstrumentID inInstrument,MusicDeviceGroupID inGroupID,NoteInstanceID * outNoteInstanceID,UInt32 inOffsetSampleFrame,const MusicDeviceNoteParams * inParams)425 static OSStatus AUMethodStartNote(void *self, MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams)
426 {
427 	OSStatus result = noErr;
428 	try {
429 		// this is a potential render-time method; no lock
430 		if (inParams == NULL || outNoteInstanceID == NULL)
431 			result = kAudio_ParamError;
432 		else
433 			result = AUI->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
434 	}
435 	COMPONENT_CATCH
436 	return result;
437 }
438 
AUMethodStopNote(void * self,MusicDeviceGroupID inGroupID,NoteInstanceID inNoteInstanceID,UInt32 inOffsetSampleFrame)439 static OSStatus AUMethodStopNote(void *self, MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame)
440 {
441 	OSStatus result = noErr;
442 	try {
443 		// this is a potential render-time method; no lock
444 		result = AUI->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame);
445 	}
446 	COMPONENT_CATCH
447 	return result;
448 }
449 
450 #if !TARGET_OS_IPHONE
AUMethodPrepareInstrument(void * self,MusicDeviceInstrumentID inInstrument)451 static OSStatus AUMethodPrepareInstrument (void *self, MusicDeviceInstrumentID inInstrument)
452 {
453 	OSStatus result = noErr;
454 	try {
455 		// this is a potential render-time method; no lock
456 		result = AUI->PrepareInstrument(inInstrument);
457 	}
458 	COMPONENT_CATCH
459 	return result;
460 }
461 
AUMethodReleaseInstrument(void * self,MusicDeviceInstrumentID inInstrument)462 static OSStatus AUMethodReleaseInstrument (void *self, MusicDeviceInstrumentID inInstrument)
463 {
464 	OSStatus result = noErr;
465 	try {
466 		// this is a potential render-time method; no lock
467 		result = AUI->ReleaseInstrument(inInstrument);
468 	}
469 	COMPONENT_CATCH
470 	return result;
471 }
472 #endif // TARGET_OS_IPHONE
473 #endif // CA_BASIC_AU_FEATURES
474 
475 
476 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
477 #pragma mark -
478 #pragma mark Lookup Methods
479 
Lookup(SInt16 selector)480 AudioComponentMethod AUBaseLookup::Lookup (SInt16 selector)
481 {
482 	switch (selector) {
483 		case kAudioUnitInitializeSelect:		return (AudioComponentMethod)AUMethodInitialize;
484 		case kAudioUnitUninitializeSelect:		return (AudioComponentMethod)AUMethodUninitialize;
485 		case kAudioUnitGetPropertyInfoSelect:	return (AudioComponentMethod)AUMethodGetPropertyInfo;
486 		case kAudioUnitGetPropertySelect:		return (AudioComponentMethod)AUMethodGetProperty;
487 		case kAudioUnitSetPropertySelect:		return (AudioComponentMethod)AUMethodSetProperty;
488 		case kAudioUnitAddPropertyListenerSelect:return (AudioComponentMethod)AUMethodAddPropertyListener;
489 		case kAudioUnitRemovePropertyListenerSelect:
490 												return (AudioComponentMethod)AUMethodRemovePropertyListener;
491 		case kAudioUnitRemovePropertyListenerWithUserDataSelect:
492 												return (AudioComponentMethod)AUMethodRemovePropertyListenerWithUserData;
493 		case kAudioUnitAddRenderNotifySelect:	return (AudioComponentMethod)AUMethodAddRenderNotify;
494 		case kAudioUnitRemoveRenderNotifySelect:return (AudioComponentMethod)AUMethodRemoveRenderNotify;
495 		case kAudioUnitGetParameterSelect:		return (AudioComponentMethod)AUMethodGetParameter;
496 		case kAudioUnitSetParameterSelect:		return (AudioComponentMethod)AUMethodSetParameter;
497 		case kAudioUnitScheduleParametersSelect:return (AudioComponentMethod)AUMethodScheduleParameters;
498 		case kAudioUnitRenderSelect:			return (AudioComponentMethod)AUMethodRender;
499 		case kAudioUnitResetSelect:				return (AudioComponentMethod)AUMethodReset;
500 		default:
501 			break;
502 	}
503 	return NULL;
504 }
505 
Lookup(SInt16 selector)506 AudioComponentMethod AUOutputLookup::Lookup (SInt16 selector)
507 {
508 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
509 	if (method) return method;
510 
511 	switch (selector) {
512 		case kAudioOutputUnitStartSelect:	return (AudioComponentMethod)AUMethodStart;
513 		case kAudioOutputUnitStopSelect:	return (AudioComponentMethod)AUMethodStop;
514 		default:
515 			break;
516 	}
517 	return NULL;
518 }
519 
Lookup(SInt16 selector)520 AudioComponentMethod AUComplexOutputLookup::Lookup (SInt16 selector)
521 {
522 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
523 	if (method) return method;
524 
525 	method = AUOutputLookup::Lookup(selector);
526 	if (method) return method;
527 
528 	if (selector == kAudioUnitComplexRenderSelect)
529 		return (AudioComponentMethod)AUMethodComplexRender;
530 	return NULL;
531 }
532 
Lookup(SInt16 selector)533 AudioComponentMethod AUBaseProcessLookup::Lookup (SInt16 selector)
534 {
535 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
536 	if (method) return method;
537 
538 	if (selector == kAudioUnitProcessSelect)
539 		return (AudioComponentMethod)AUMethodProcess;
540 
541 	return NULL;
542 }
543 
Lookup(SInt16 selector)544 AudioComponentMethod AUBaseProcessMultipleLookup::Lookup (SInt16 selector)
545 {
546 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
547 	if (method) return method;
548 
549 	if (selector == kAudioUnitProcessMultipleSelect)
550 		return (AudioComponentMethod)AUMethodProcessMultiple;
551 
552 	return NULL;
553 }
554 
Lookup(SInt16 selector)555 AudioComponentMethod AUBaseProcessAndMultipleLookup::Lookup (SInt16 selector)
556 {
557 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
558 	if (method) return method;
559 
560 	method = AUBaseProcessMultipleLookup::Lookup(selector);
561 	if (method) return method;
562 
563 	method = AUBaseProcessLookup::Lookup(selector);
564 	if (method) return method;
565 
566 	return NULL;
567 }
568 
569 #if !CA_BASIC_AU_FEATURES
MIDI_Lookup(SInt16 selector)570 inline AudioComponentMethod MIDI_Lookup (SInt16 selector)
571 {
572 	switch (selector) {
573 		case kMusicDeviceMIDIEventSelect:	return (AudioComponentMethod)AUMethodMIDIEvent;
574 		case kMusicDeviceSysExSelect:		return (AudioComponentMethod)AUMethodSysEx;
575 		default:
576 			break;
577 	}
578 	return NULL;
579 }
580 
Lookup(SInt16 selector)581 AudioComponentMethod AUMIDILookup::Lookup (SInt16 selector)
582 {
583 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
584 	if (method) return method;
585 
586 	return MIDI_Lookup(selector);
587 }
588 
Lookup(SInt16 selector)589 AudioComponentMethod AUMIDIProcessLookup::Lookup (SInt16 selector)
590 {
591 	AudioComponentMethod method = AUBaseProcessLookup::Lookup(selector);
592 	if (method) return method;
593 
594 	return MIDI_Lookup(selector);
595 }
596 
Lookup(SInt16 selector)597 AudioComponentMethod AUMusicLookup::Lookup (SInt16 selector)
598 {
599 	AudioComponentMethod method = AUBaseLookup::Lookup(selector);
600 	if (method) return method;
601 
602 	switch (selector) {
603 		case kMusicDeviceStartNoteSelect:	return (AudioComponentMethod)AUMethodStartNote;
604 		case kMusicDeviceStopNoteSelect:	return (AudioComponentMethod)AUMethodStopNote;
605 #if !TARGET_OS_IPHONE
606 		case kMusicDevicePrepareInstrumentSelect:	return (AudioComponentMethod)AUMethodPrepareInstrument;
607 		case kMusicDeviceReleaseInstrumentSelect:	return (AudioComponentMethod)AUMethodReleaseInstrument;
608 #endif
609 		default:
610 			break;
611 	}
612 	return MIDI_Lookup (selector);
613 }
614 
Lookup(SInt16 selector)615 AudioComponentMethod AUAuxBaseLookup::Lookup (SInt16 selector)
616 {
617 	switch (selector) {
618 		case kAudioUnitGetPropertyInfoSelect:	return (AudioComponentMethod)AUMethodGetPropertyInfo;
619 		case kAudioUnitGetPropertySelect:		return (AudioComponentMethod)AUMethodGetProperty;
620 		case kAudioUnitSetPropertySelect:		return (AudioComponentMethod)AUMethodSetProperty;
621 
622 		case kAudioUnitGetParameterSelect:		return (AudioComponentMethod)AUMethodGetParameter;
623 		case kAudioUnitSetParameterSelect:		return (AudioComponentMethod)AUMethodSetParameter;
624 
625 		default:
626 			break;
627 	}
628 	return NULL;
629 }
630 #endif
631 
632