OSStatus AUBase::SaveState()

in Source/AUBase.cpp [1760:1840]


OSStatus AUBase::SaveState(CFPropertyListRef* outData)
{
	const AudioComponentDescription desc = GetComponentDescription();

	auto dict = Owned<CFMutableDictionaryRef>::from_create(CFDictionaryCreateMutable(
		nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));

	// first step -> save the version to the data ref
	SInt32 value = kCurrentSavedStateVersion;
	AddNumToDictionary(*dict, kVersionString, value);

	// second step -> save the component type, subtype, manu to the data ref
	value = static_cast<SInt32>(desc.componentType);
	AddNumToDictionary(*dict, kTypeString, value);

	value = static_cast<SInt32>(desc.componentSubType);
	AddNumToDictionary(*dict, kSubtypeString, value);

	value = static_cast<SInt32>(desc.componentManufacturer);
	AddNumToDictionary(*dict, kManufacturerString, value);

	// fourth step -> save the state of all parameters on all scopes and elements
	auto data = Owned<CFMutableDataRef>::from_create(CFDataCreateMutable(nullptr, 0));
	for (AudioUnitScope iscope = 0; iscope < 3; ++iscope) {
		const auto& scope = GetScope(iscope);
		scope.SaveState(*data);
	}

	SaveExtendedScopes(*data);

	// save all this in the data section of the dictionary
	CFDictionarySetValue(*dict, kDataString, *data);
	data = nullptr; // data can be large-ish, so destroy it now.

	// OK - now we're going to do some properties
	// save the preset name...
	CFDictionarySetValue(*dict, kNameString, mCurrentPreset.presetName);

	// Does the unit support the RenderQuality property - if so, save it...
	OSStatus result =
		DispatchGetProperty(kAudioUnitProperty_RenderQuality, kAudioUnitScope_Global, 0, &value);

	if (result == noErr) {
		AddNumToDictionary(*dict, kRenderQualityString, value);
	}

	// Does the unit support the CPULoad Quality property - if so, save it...
	Float32 cpuLoad = 0.0f;
	result = DispatchGetProperty(kAudioUnitProperty_CPULoad, kAudioUnitScope_Global, 0, &cpuLoad);

	if (result == noErr) {
		CFNumberRef num = CFNumberCreate(nullptr, kCFNumberFloatType, &cpuLoad);
		CFDictionarySetValue(*dict, kCPULoadString, num);
		CFRelease(num);
	}

	// Do we have any element names for any of our scopes?
	// first check to see if we have any names...
	bool foundName = false;
	for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
		foundName = GetScope(i).HasElementWithName();
		if (foundName) {
			break;
		}
	}
	// OK - we found a name away we go...
	if (foundName) {
		auto nameDict = Owned<CFMutableDictionaryRef>::from_create(CFDictionaryCreateMutable(
			nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
		for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
			GetScope(i).AddElementNamesToDict(*nameDict);
		}

		CFDictionarySetValue(*dict, kElementNameString, *nameDict);
	}

	// we're done!!!
	*outData = static_cast<CFPropertyListRef>(dict.release()); // transfer ownership

	return noErr;
}