OSStatus AUBase::DispatchGetPropertyInfo()

in Source/AUBase.cpp [262:472]


OSStatus AUBase::DispatchGetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
	AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable)
{
	OSStatus result = noErr;
	bool validateElement = true;

	switch (inID) {
	case kAudioUnitProperty_MakeConnection:
		AUSDK_Require(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Global,
			kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(AudioUnitConnection);
		outWritable = true;
		break;

	case kAudioUnitProperty_SetRenderCallback:
		AUSDK_Require(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Global,
			kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(AURenderCallbackStruct);
		outWritable = true;
		break;

	case kAudioUnitProperty_StreamFormat:
		outDataSize = sizeof(AudioStreamBasicDescription);
		outWritable = IsStreamFormatWritable(inScope, inElement);
		break;

	case kAudioUnitProperty_SampleRate:
		outDataSize = sizeof(Float64);
		outWritable = IsStreamFormatWritable(inScope, inElement);
		break;

	case kAudioUnitProperty_ClassInfo:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(CFPropertyListRef);
		outWritable = true;
		break;

	case kAudioUnitProperty_FactoryPresets:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		AUSDK_Require_noerr(GetPresets(nullptr));
		outDataSize = sizeof(CFArrayRef);
		outWritable = false;
		break;

	case kAudioUnitProperty_PresentPreset:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(AUPreset);
		outWritable = true;
		break;

	case kAudioUnitProperty_ElementName:
		outDataSize = sizeof(CFStringRef);
		outWritable = true;
		break;

	case kAudioUnitProperty_ParameterList: {
		UInt32 nparams = 0;
		AUSDK_Require_noerr(GetParameterList(inScope, nullptr, nparams));
		outDataSize = sizeof(AudioUnitParameterID) * nparams;
		outWritable = false;
		validateElement = false;
		break;
	}

	case kAudioUnitProperty_ParameterInfo:
		outDataSize = sizeof(AudioUnitParameterInfo);
		outWritable = false;
		validateElement = false;
		break;

	case kAudioUnitProperty_ParameterHistoryInfo:
		outDataSize = sizeof(AudioUnitParameterHistoryInfo);
		outWritable = false;
		validateElement = false;
		break;

	case kAudioUnitProperty_ElementCount:
		outDataSize = sizeof(UInt32);
		outWritable = BusCountWritable(inScope);
		validateElement = false;
		break;

	case kAudioUnitProperty_Latency:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(Float64);
		outWritable = false;
		break;

	case kAudioUnitProperty_TailTime:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		AUSDK_Require(SupportsTail(), kAudioUnitErr_InvalidProperty);
		outDataSize = sizeof(Float64);
		outWritable = false;
		break;

	case kAudioUnitProperty_MaximumFramesPerSlice:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(UInt32);
		outWritable = true;
		break;

	case kAudioUnitProperty_LastRenderError:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(OSStatus);
		outWritable = false;
		break;

	case kAudioUnitProperty_SupportedNumChannels: {
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		const UInt32 num = SupportedNumChannels(nullptr);
		AUSDK_Require(num != 0u, kAudioUnitErr_InvalidProperty);
		outDataSize = sizeof(AUChannelInfo) * num;
		outWritable = false;
		break;
	}

	case kAudioUnitProperty_SupportedChannelLayoutTags: {
		const auto tags = GetChannelLayoutTags(inScope, inElement);
		AUSDK_Require(!tags.empty(), kAudioUnitErr_InvalidProperty);
		outDataSize = static_cast<UInt32>(tags.size() * sizeof(AudioChannelLayoutTag));
		outWritable = false;
		validateElement = false; // already done it
		break;
	}

	case kAudioUnitProperty_AudioChannelLayout: {
		outWritable = false;
		outDataSize = GetAudioChannelLayout(inScope, inElement, nullptr, outWritable);
		if (outDataSize != 0u) {
			result = noErr;
		} else {
			const auto tags = GetChannelLayoutTags(inScope, inElement);
			return tags.empty() ? kAudioUnitErr_InvalidProperty
								: kAudioUnitErr_InvalidPropertyValue;
		}
		validateElement = false; // already done it
		break;
	}

	case kAudioUnitProperty_ShouldAllocateBuffer:
		AUSDK_Require((inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output),
			kAudioUnitErr_InvalidScope);
		outWritable = true;
		outDataSize = sizeof(UInt32);
		break;

	case kAudioUnitProperty_ParameterValueStrings:
		AUSDK_Require_noerr(GetParameterValueStrings(inScope, inElement, nullptr));
		outDataSize = sizeof(CFArrayRef);
		outWritable = false;
		validateElement = false;
		break;

	case kAudioUnitProperty_HostCallbacks:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(mHostCallbackInfo);
		outWritable = true;
		break;

	case kAudioUnitProperty_ContextName:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(CFStringRef);
		outWritable = true;
		break;

#if !TARGET_OS_IPHONE
	case kAudioUnitProperty_IconLocation:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		AUSDK_Require(HasIcon(), kAudioUnitErr_InvalidProperty);
		outWritable = false;
		outDataSize = sizeof(CFURLRef);
		break;
#endif

	case kAudioUnitProperty_ParameterClumpName:
		outDataSize = sizeof(AudioUnitParameterNameInfo);
		outWritable = false;
		break;

	case 61: // kAudioUnitProperty_LastRenderSampleTime
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(Float64);
		outWritable = false;
		break;

	case kAudioUnitProperty_NickName:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(CFStringRef);
		outWritable = true;
		break;

#if AUSDK_MIDI2_AVAILABLE
	case kAudioUnitProperty_HostMIDIProtocol:
		AUSDK_Require(inScope == kAudioUnitScope_Global, kAudioUnitErr_InvalidScope);
		outDataSize = sizeof(MIDIProtocolID);
		outWritable = true;
		break;
#endif

	default:
		result = GetPropertyInfo(inID, inScope, inElement, outDataSize, outWritable);
		validateElement = false;
		break;
	}

	if ((result == noErr) && validateElement) {
		AUSDK_Require(GetElement(inScope, inElement) != nullptr, kAudioUnitErr_InvalidElement);
	}

	return result;
}