static OSStatus AUMethodSetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void *inData, UInt32 inDataSize) { OSStatus result = noErr; try { AUI_LOCK if (inData && inDataSize) result = AUI->DispatchSetProperty(inID, inScope, inElement, inData, inDataSize); else { if (inData == NULL && inDataSize == 0) { result = AUI->DispatchRemovePropertyValue(inID, inScope, inElement); } else { if (inData == NULL) { ca_debug_string("AudioUnitSetProperty: inData == NULL"); result = kAudio_ParamError; goto finishSetProperty; } if (inDataSize == 0) { ca_debug_string("AudioUnitSetProperty: inDataSize == 0"); result = kAudio_ParamError; goto finishSetProperty; } } } } COMPONENT_CATCH finishSetProperty: return result; }
static OSStatus AUMethodGetProperty(void *self, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void *outData, UInt32 *ioDataSize) { OSStatus result = noErr; try { UInt32 actualPropertySize, clientBufferSize; Boolean writable; char *tempBuffer; void *destBuffer; AUI_LOCK if (ioDataSize == NULL) { ca_debug_string("AudioUnitGetProperty: null size pointer"); result = kAudio_ParamError; goto finishGetProperty; } if (outData == NULL) { UInt32 dataSize; result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, dataSize, writable); *ioDataSize = dataSize; goto finishGetProperty; } clientBufferSize = *ioDataSize; if (clientBufferSize == 0) { ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry"); // $$$ or should we allow this as a shortcut for finding the size? result = kAudio_ParamError; goto finishGetProperty; } result = AUI->DispatchGetPropertyInfo(inID, inScope, inElement, actualPropertySize, writable); if (result != noErr) goto finishGetProperty; if (clientBufferSize < actualPropertySize) { tempBuffer = new char[actualPropertySize]; destBuffer = tempBuffer; } else { tempBuffer = NULL; destBuffer = outData; } result = AUI->DispatchGetProperty(inID, inScope, inElement, destBuffer); if (result == noErr) { if (clientBufferSize < actualPropertySize && tempBuffer != NULL) { memcpy(outData, tempBuffer, clientBufferSize); delete[] tempBuffer; // ioDataSize remains correct, the number of bytes we wrote } else *ioDataSize = actualPropertySize; } else *ioDataSize = 0; } COMPONENT_CATCH finishGetProperty: return result; }
OSStatus AUBase::ComponentEntryDispatch(ComponentParameters *params, AUBase *This) { if (This == NULL) return kAudio_ParamError; OSStatus result = noErr; switch (params->what) { case kComponentCanDoSelect: switch (GetSelectorForCanDo(params)) { // any selectors case kAudioUnitInitializeSelect: case kAudioUnitUninitializeSelect: case kAudioUnitGetPropertyInfoSelect: case kAudioUnitGetPropertySelect: case kAudioUnitSetPropertySelect: case kAudioUnitAddPropertyListenerSelect: #if (!__LP64__) case kAudioUnitRemovePropertyListenerSelect: #endif case kAudioUnitGetParameterSelect: case kAudioUnitSetParameterSelect: case kAudioUnitResetSelect: result = 1; break; // v1 selectors // v2 selectors case kAudioUnitRemovePropertyListenerWithUserDataSelect: case kAudioUnitAddRenderNotifySelect: case kAudioUnitRemoveRenderNotifySelect: case kAudioUnitScheduleParametersSelect: case kAudioUnitRenderSelect: result = (This->AudioUnitAPIVersion() > 1); break; default: return ComponentBase::ComponentEntryDispatch(params, This); } break; case kAudioUnitInitializeSelect: { CAMutex::Locker lock2(This->GetMutex()); result = This->DoInitialize(); } break; case kAudioUnitUninitializeSelect: { CAMutex::Locker lock2(This->GetMutex()); This->DoCleanup(); result = noErr; } break; case kAudioUnitGetPropertyInfoSelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 5); PARAM(AudioUnitScope, pinScope, 1, 5); PARAM(AudioUnitElement, pinElement, 2, 5); PARAM(UInt32 *, poutDataSize, 3, 5); PARAM(Boolean *, poutWritable, 4, 5); // pass our own copies so that we assume responsibility for testing // the caller's pointers against null and our C++ classes can // always assume they're non-null UInt32 dataSize; Boolean writable; result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable); if (poutDataSize != NULL) *poutDataSize = dataSize; if (poutWritable != NULL) *poutWritable = writable; } break; case kAudioUnitGetPropertySelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 5); PARAM(AudioUnitScope, pinScope, 1, 5); PARAM(AudioUnitElement, pinElement, 2, 5); PARAM(void *, poutData, 3, 5); PARAM(UInt32 *, pioDataSize, 4, 5); UInt32 actualPropertySize, clientBufferSize; Boolean writable; char *tempBuffer; void *destBuffer; if (pioDataSize == NULL) { ca_debug_string("AudioUnitGetProperty: null size pointer"); result = kAudio_ParamError; goto finishGetProperty; } if (poutData == NULL) { UInt32 dataSize; result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable); *pioDataSize = dataSize; goto finishGetProperty; } clientBufferSize = *pioDataSize; if (clientBufferSize == 0) { ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry"); // $$$ or should we allow this as a shortcut for finding the size? result = kAudio_ParamError; goto finishGetProperty; } result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, actualPropertySize, writable); if (result) goto finishGetProperty; if (clientBufferSize < actualPropertySize) { tempBuffer = new char[actualPropertySize]; destBuffer = tempBuffer; } else { tempBuffer = NULL; destBuffer = poutData; } result = This->DispatchGetProperty(pinID, pinScope, pinElement, destBuffer); if (result == noErr) { if (clientBufferSize < actualPropertySize && tempBuffer != NULL) { memcpy(poutData, tempBuffer, clientBufferSize); delete[] tempBuffer; // pioDataSize remains correct, the number of bytes we wrote } else *pioDataSize = actualPropertySize; } else *pioDataSize = 0; finishGetProperty: ; } break; case kAudioUnitSetPropertySelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 5); PARAM(AudioUnitScope, pinScope, 1, 5); PARAM(AudioUnitElement, pinElement, 2, 5); PARAM(const void *, pinData, 3, 5); PARAM(UInt32, pinDataSize, 4, 5); if (pinData && pinDataSize) result = This->DispatchSetProperty(pinID, pinScope, pinElement, pinData, pinDataSize); else { if (pinData == NULL && pinDataSize == 0) { result = This->DispatchRemovePropertyValue (pinID, pinScope, pinElement); } else { if (pinData == NULL) { ca_debug_string("AudioUnitSetProperty: inData == NULL"); result = kAudio_ParamError; goto finishSetProperty; } if (pinDataSize == 0) { ca_debug_string("AudioUnitSetProperty: inDataSize == 0"); result = kAudio_ParamError; goto finishSetProperty; } } } finishSetProperty: ; } break; case kAudioUnitAddPropertyListenerSelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 3); PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3); PARAM(void *, pinProcRefCon, 2, 3); result = This->AddPropertyListener(pinID, pinProc, pinProcRefCon); } break; #if (!__LP64__) case kAudioUnitRemovePropertyListenerSelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 2); PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 2); result = This->RemovePropertyListener(pinID, pinProc, NULL, false); } break; #endif case kAudioUnitRemovePropertyListenerWithUserDataSelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitPropertyID, pinID, 0, 3); PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3); PARAM(void *, pinProcRefCon, 2, 3); result = This->RemovePropertyListener(pinID, pinProc, pinProcRefCon, true); } break; case kAudioUnitAddRenderNotifySelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AURenderCallback, pinProc, 0, 2); PARAM(void *, pinProcRefCon, 1, 2); result = This->SetRenderNotification (pinProc, pinProcRefCon); } break; case kAudioUnitRemoveRenderNotifySelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AURenderCallback, pinProc, 0, 2); PARAM(void *, pinProcRefCon, 1, 2); result = This->RemoveRenderNotification (pinProc, pinProcRefCon); } break; case kAudioUnitGetParameterSelect: { CAMutex::Locker lock(This->GetMutex()); PARAM(AudioUnitParameterID, pinID, 0, 4); PARAM(AudioUnitScope, pinScope, 1, 4); PARAM(AudioUnitElement, pinElement, 2, 4); PARAM(AudioUnitParameterValue *, poutValue, 3, 4); result = (poutValue == NULL ? kAudio_ParamError : This->GetParameter(pinID, pinScope, pinElement, *poutValue)); } break; case kAudioUnitSetParameterSelect: { CAMutex::Locker lock(This->GetMutex()); // is this realtime or no??? PARAM(AudioUnitParameterID, pinID, 0, 5); PARAM(AudioUnitScope, pinScope, 1, 5); PARAM(AudioUnitElement, pinElement, 2, 5); PARAM(AudioUnitParameterValue, pinValue, 3, 5); PARAM(UInt32, pinBufferOffsetInFrames, 4, 5); result = This->SetParameter(pinID, pinScope, pinElement, pinValue, pinBufferOffsetInFrames); } break; case kAudioUnitScheduleParametersSelect: { CAMutex::Locker lock(This->GetMutex()); // is this realtime or no??? if (This->AudioUnitAPIVersion() > 1) { PARAM(AudioUnitParameterEvent *, pinParameterEvent, 0, 2); PARAM(UInt32, pinNumParamEvents, 1, 2); result = This->ScheduleParameter (pinParameterEvent, pinNumParamEvents); } else result = badComponentSelector; }