# Presets/programs in AUs

**URL:** <https://forum.juce.com/t/presets-programs-in-aus/2393>\
**Category:** Audio Plugins\
**Created:** [December 6, 2007, 9:15pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393 "2007-12-06T21:15:28Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 6, 2007, 9:15pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/1 "2007-12-06T21:15:28Z")

</div>

Hi,

I have currently 4 programs in my plug which all work fine under Windows/VST, i.e. get/setprogram() and getprogramname() are implemented correctly. However, under Garageband in 10.4 the corresponding AU component doesn’t show any programs. What else do I have to declare to make proper AU presets/programs?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [December 7, 2007, 9:45am UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/2 "2007-12-07T09:45:34Z")

</div>

ah, I don’t think that’s actually implemented yet under AU… I’ll get round to it eventually, or if you want to hurry things up, you could have a go yourself!

---

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 7, 2007, 11:14am UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/3 "2007-12-07T11:14:10Z")

</div>

Okay, I might try it… although I can’t promise success!

---

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 8, 2007, 5:14pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/4 "2007-12-08T17:14:50Z")

</div>

So that’s what I’ve come up with so far, basically following the TremoloUnit example in the Apple developer’s guide:

```auto
	ComponentResult GetPresets (CFArrayRef *outData) const
	{	
		if (outData == NULL) 
		{
			return noErr;
		}
		
		int kNumberPresets = juceFilter->getNumPrograms();
		AUPreset kPresets[kNumberPresets];
		String programName;
		
		CFMutableArrayRef presetsArray = CFArrayCreateMutable(NULL,kNumberPresets,NULL);
		for (int i=0;i<kNumberPresets;i++) 
		{
			kPresets[i].presetNumber = i;
			programName = juceFilter->getProgramName(i);
			kPresets[i].presetName = PlatformUtilities::juceStringToCFString (programName);
			CFArrayAppendValue(presetsArray,&kPresets[i]);
		}
		*outData = (CFArrayRef) presetsArray;
		return noErr;
	}
	
	OSStatus NewFactoryPresetSet( const AUPreset &inNewFactoryPreset)
	{
		int kNumberPresets = juceFilter->getNumPrograms();
		SInt32 chosenPresetNumber = (int) inNewFactoryPreset.presetNumber;
		AUPreset chosenPreset;
		String programName;
		
		if (chosenPresetNumber<kNumberPresets) 
		{
			chosenPreset.presetNumber = chosenPresetNumber;
			programName = juceFilter->getProgramName(chosenPresetNumber);
			chosenPreset.presetName = PlatformUtilities::juceStringToCFString (programName); 
			juceFilter->setCurrentProgram(chosenPresetNumber);
			SetAFactoryPresetAsCurrent(chosenPreset);
			return noErr;
		}
		else return kAudioUnitErr_InvalidProperty;
	} 
```

While in getPreset() everything seems to work fine, NewFactoryPresetSet is called with inNewFactoryPreset.presetNumber=104345483 or something like that. Consequently, the routine returns kAudioUnitErr\_InvalidProperty, and then the whole thing crashes. Anything obvious that I might have forgotten?

---

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 9, 2007, 2:34pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/5 "2007-12-09T14:34:10Z")

</div>

Alright, the kPresets array in getPreset() has to be global/static. So this seems to work:

- add the following two variables to JuceAU:

`static AUPreset *kPresets;
	static bool kPresetsNotAlloc;
`

- initiate them by writing `AUPreset* JuceAU::kPresets=NULL;
bool JuceAU::kPresetsNotAlloc=true;` somewhere into juce\_AudioUnitWrapper.cpp. Then, the two preset routines look like this:

[code]ComponentResult GetPresets (CFArrayRef \*outData) const  
{   
if (outData == NULL)  
{  
return noErr;  
}

```
	int kNumberPresets = juceFilter->getNumPrograms();
	if (kPresetsNotAlloc)
	{
		kPresets = new AUPreset[kNumberPresets];
		kPresetsNotAlloc = false;
	}
	
	String programName;
	
	CFMutableArrayRef presetsArray = CFArrayCreateMutable(NULL,kNumberPresets,NULL);
	for (int i=0;i<kNumberPresets;i++) 
	{
		kPresets[i].presetNumber = i;
		programName = juceFilter->getProgramName(i);
		kPresets[i].presetName = PlatformUtilities::juceStringToCFString (programName);
		CFArrayAppendValue(presetsArray,&kPresets[i]);
	}
	*outData = (CFArrayRef) presetsArray;
	return noErr;
}

OSStatus NewFactoryPresetSet( const AUPreset &inNewFactoryPreset)
{
	int kNumberPresets = juceFilter->getNumPrograms();
	SInt32 chosenPresetNumber = (int) inNewFactoryPreset.presetNumber;
	AUPreset chosenPreset;
	String programName;
	
	if (chosenPresetNumber<kNumberPresets) 
	{
		chosenPreset.presetNumber = chosenPresetNumber;
		programName = juceFilter->getProgramName(chosenPresetNumber);
		chosenPreset.presetName = PlatformUtilities::juceStringToCFString (programName); 
		juceFilter->setCurrentProgram(chosenPresetNumber);
		SetAFactoryPresetAsCurrent(chosenPreset);
		return noErr;
	}
	
	else return kAudioUnitErr_InvalidProperty;
} 

```

[/code]

I haven’t tested it extensively, but so far things seem fine…

Edit: Don’t forget to delete the kPresets array in the JuceAU destructor…

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [December 9, 2007, 5:47pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/6 "2007-12-09T17:47:16Z")

</div>

Ok, thanks. Obviously making the presets global is no good when you’ve got multiple instances of a plugin, but try this re-factored version using a MemoryBlock member variable to store the array (I’ve not even checked if this compiles yet…):

[code] MemoryBlock presetsArray;

```
ComponentResult GetPresets (CFArrayRef* outData) const
{
    if (outData != 0)
    {
        const int numPrograms = juceFilter->getNumPrograms();
        presetsArray.ensureSize (sizeof (AUPreset) * numPrograms, true);
        AUPreset* const presets = (AUPreset*) presetsArray.getData();

        CFMutableArrayRef presetsArray = CFArrayCreateMutable (0, numPrograms, 0);

        for (int i = 0; i < numPrograms; ++i)
        {
            presets[i].presetNumber = i;
            presets[i].presetName = PlatformUtilities::juceStringToCFString (juceFilter->getProgramName (i));
            
            CFArrayAppendValue (presetsArray, presets + i);
        }

        *outData = (CFArrayRef) presetsArray;
    }

    return noErr;
}

OSStatus NewFactoryPresetSet (const AUPreset& inNewFactoryPreset)
{
    const int numPrograms = juceFilter->getNumPrograms();
    const SInt32 chosenPresetNumber = (int) inNewFactoryPreset.presetNumber;

    if (chosenPresetNumber >= numPrograms)
        return kAudioUnitErr_InvalidProperty;

    AUPreset chosenPreset;
    chosenPreset.presetNumber = chosenPresetNumber;
    chosenPreset.presetName = PlatformUtilities::juceStringToCFString (juceFilter->getProgramName (chosenPresetNumber));

    juceFilter->setCurrentProgram (chosenPresetNumber);
    SetAFactoryPresetAsCurrent (chosenPreset);

    return noErr;
} [/code]

```

---

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 9, 2007, 7:08pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/7 "2007-12-09T19:08:35Z")

</div>

> [@jules](#):
>
> Ok, thanks. Obviously making the presets global is no good when you’ve got multiple instances of a plugin

Hmmm… works fine with multiple plugins. I don’t get it: why should this be bad? It’s the same set of presets for every instance, isn’t it?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [December 9, 2007, 7:57pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/8 "2007-12-09T19:57:18Z")

</div>

> [@](#):
>
> Hmmm… works fine with multiple plugins. I don’t get it: why should this be bad? It’s the same set of presets for every instance, isn’t it?

Maybe in your plugin it is, but there’s no reason why that should be the case for everyone. Besides, there’s an obvious bug if one plugin is deleted and deletes the statics while another is using them. In general, statics in plugins are best avoided.

---

<div class="post-metadata">

**Author:** ![siedschl](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@siedschl](https://forum.juce.com/u/siedschl)\
**Post date:** [December 9, 2007, 10:02pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/9 "2007-12-09T22:02:18Z")

</div>

I see… thanks! Everything compiles and works fine…

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [December 10, 2007, 9:10am UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/10 "2007-12-10T09:10:51Z")

</div>

Great, I’ll check it in.

---

<div class="post-metadata">

**Author:** ![chkn](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/chkn/32/3862_2.png) [@chkn](https://forum.juce.com/u/chkn)\
**Post date:** [December 10, 2007, 6:06pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/11 "2007-12-10T18:06:26Z")

</div>

does not work here:

```auto
presetsArray.ensureSize (sizeof (AUPreset) * numPrograms, true);

error: passing 'const juce::MemoryBlock' as 'this' argument of 'void juce::MemoryBlock::ensureSize(int, bool)' discards qualifiers

```

cause GetPresets is const.

i also don’t understand why presetsArray is defined a second time

```auto

            CFMutableArrayRef presetsArray = CFArrayCreateMutable (0, numPrograms, 0); 

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [December 10, 2007, 6:13pm UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/12 "2007-12-10T18:13:35Z")

</div>

ok, better make that MemoryBlock mutable…

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [May 12, 2017, 10:05am UTC](https://forum.juce.com/t/presets-programs-in-aus/2393/13 "2017-05-12T10:05:28Z")

</div>

Closed on May 12, 2017, 10:05am UTC


