The leaks are tiny, but I want to get rid of them! It appears that certain CFStrings are not getting released in IPlug's AU code, particularly when it comes to preset names. I am trying to find out how to release them properly but so far no joy. From everything I've read it seems that the host should release them - but i've tried releasing them myself in various places, and mostly it just crashed auval. If anyone has any idea what's wrong with the methods below it would be great to know. I had a look at the DFX au utilities which include AUPreset CF datatypes and actually I made some progress and got rid of the preset leaks (by using the DFX CFAUPreset), but the leaks for the other items remained… i'd prefer to work out the problem and fix it without including the DFX code.
case kAudioUnitProperty_FactoryPresets: { // 24, // listenable
*pDataSize = sizeof(CFArrayRef);
if (pData) {
int i, n = NPresets();
CFMutableArrayRef presetArray = CFArrayCreateMutable(0, n, 0);
for (i = 0; i < n; ++i) {
AUPreset* pAUPreset = new AUPreset;
pAUPreset->presetNumber = i;
pAUPreset->presetName = MakeCFString(GetPresetName(i)); // this needs to get released somewhere?
CFArrayAppendValue(presetArray, pAUPreset);
}
*((CFMutableArrayRef*) pData) = presetArray;
}
return noErr;
}
case kAudioUnitProperty_ParameterInfo: { // 4, listenable
ASSERT_SCOPE(kAudioUnitScope_Global);
*pDataSize = sizeof(AudioUnitParameterInfo);
if (pData) {
AudioUnitParameterInfo* pInfo = (AudioUnitParameterInfo*) pData;
memset(pInfo, 0, sizeof(AudioUnitParameterInfo));
pInfo->flags = kAudioUnitParameterFlag_CFNameRelease |
kAudioUnitParameterFlag_HasCFNameString |
kAudioUnitParameterFlag_IsReadable |
kAudioUnitParameterFlag_IsWritable;
IParam* pParam = GetParam(element);
const char* paramName = pParam->GetNameForHost();
pInfo->cfNameString = MakeCFString(pParam->GetNameForHost());
strcpy(pInfo->name, paramName); // Max 52.
switch (pParam->Type()) {
case IParam::kTypeBool:
pInfo->unit = kAudioUnitParameterUnit_Boolean;
break;
case IParam::kTypeEnum:
//fall through
case IParam::kTypeInt:
pInfo->unit = kAudioUnitParameterUnit_Indexed;
break;
default: {
const char* label = pParam->GetLabelForHost();
if (CSTR_NOT_EMPTY(label)) {
pInfo->unit = kAudioUnitParameterUnit_CustomUnit;
pInfo->unitName = MakeCFString(label);
}
else {
pInfo->unit = kAudioUnitParameterUnit_Generic;
}
}
}
double vMin, vMax;
pParam->GetBounds(&vMin, &vMax);
pInfo->minValue = vMin;
pInfo->maxValue = vMax;
pInfo->defaultValue = pParam->Value();
}