void AUElement::SaveState()

in Source/AUScopeElement.cpp [120:177]


void AUElement::SaveState(AudioUnitScope scope, CFMutableDataRef data)
{
	AudioUnitParameterInfo paramInfo{};
	const CFIndex countOffset = CFDataGetLength(data);
	uint32_t paramsWritten = 0;

	const auto appendBytes = [data](const void* bytes, CFIndex length) {
		CFDataAppendBytes(data, static_cast<const UInt8*>(bytes), length);
	};

	const auto appendParameter = [&](AudioUnitParameterID paramID, AudioUnitParameterValue value) {
		struct {
			UInt32 paramID;
			UInt32 value; // really a big-endian float
		} entry{};
		static_assert(sizeof(entry) == (sizeof(entry.paramID) + sizeof(entry.value)));

		if (mAudioUnit.GetParameterInfo(scope, paramID, paramInfo) == noErr) {
			if ((paramInfo.flags & kAudioUnitParameterFlag_CFNameRelease) != 0u) {
				if (paramInfo.cfNameString != nullptr) {
					CFRelease(paramInfo.cfNameString);
				}
				if (paramInfo.unit == kAudioUnitParameterUnit_CustomUnit &&
					paramInfo.unitName != nullptr) {
					CFRelease(paramInfo.unitName);
				}
			}
			if (((paramInfo.flags & kAudioUnitParameterFlag_OmitFromPresets) != 0u) ||
				((paramInfo.flags & kAudioUnitParameterFlag_MeterReadOnly) != 0u)) {
				return;
			}
		}

		entry.paramID = CFSwapInt32HostToBig(paramID);
		entry.value = CFSwapInt32HostToBig(*reinterpret_cast<UInt32*>(&value)); // NOLINT

		appendBytes(&entry, sizeof(entry));
		++paramsWritten;
	};

	constexpr UInt32 placeholderCount = 0;
	appendBytes(&placeholderCount, sizeof(placeholderCount));

	if (mUseIndexedParameters) {
		const auto nparams = static_cast<UInt32>(mIndexedParameters.size());
		for (UInt32 i = 0; i < nparams; i++) {
			appendParameter(i, mIndexedParameters[i]);
		}
	} else {
		for (const auto& item : mParameters) {
			appendParameter(item.first, item.second);
		}
	}

	const auto count_BE = CFSwapInt32HostToBig(paramsWritten);
	memcpy(CFDataGetMutableBytePtr(data) + countOffset, // NOLINT ptr math
		&count_BE, sizeof(count_BE));
}