Re: PostConstructor vs Initialize (AU's built-in Parameter Implementation)
Re: PostConstructor vs Initialize (AU's built-in Parameter Implementation)
- Subject: Re: PostConstructor vs Initialize (AU's built-in Parameter Implementation)
- From: William Stewart <email@hidden>
- Date: Thu, 29 Jan 2004 11:34:28 -0800
On 28/01/2004, at 1:07 AM, yoshida wrote:
>
Thanks for the reply, bill!
>
>
At 11:19 AM -0800 04.1.27, William Stewart wrote:
>
> These are two very different methods.
>
>
>
> First, they correspond to different API calls for an AudioUnit.
>
> PostConstructor is called as part of the process of opening an AU. It
>
> is expected that opening an AU is a cheap operation, where the host
>
> can then query some of the features, capabilities of an AU (for
>
> instance, its channel handling capabilities)
>
>
>
> Initialize corresponds to AudioUnitinitialize and is called by the
>
> host when an AU is expected to be used to render audio. This is the
>
> place where resources needed for rendering should be acquired,
>
> etc... This can be as expensive as needed, after this call, you must
>
> be ready to render. Being asked to render before this call is made
>
> is an error.
>
>
>
> There are some more details on this in the docs
>
> (/Developer/Documentation/CoreAudio)
>
>
>
> As this is an API, you should not call it directly yourself,
>
> particularly in a constructor.
>
>
I have just one more question.
>
Is SetParameter() or GetParameter() called before Initalize() ?
Yes it can be.
SetParameter will establish an entry in the parameter list that is
stored in the Element object if it doesn't already exist.
One thing that is worth mentioning here as well...
There are two way that your AU can choose to store parameters using the
element objects. First (by default) is a sparse list of keys (where the
parameter ID in both of these cases is the key) using an stl map - this
is good if you have a sparse list of param ID's (say for eg. param ID's
0 to 10, 1000 to 1010, etc).
There's also a second alternative, to use paramID's as an index into an
stl vector. Thus your param ID's will start at zero and ascend
sequentially with no gaps. This is more efficient of course, but
without the flexibility offered by the map implementation. (But in
particular, the act of retrieving a parameter value whilst rendering is
far more efficient)...
Typically what we'll do (and this is also done in the sample effect
unit in the SDK) is the following:
In the constructor, or post constructor, we'll call SetParameter with
the default value for each parameter. This both establishes the
parameter's initial value and creates an entry for the parameter. The
one thing to watch here is that you should make sure that
CreateElements is called first.
This is called for you in the PostConstructor (its safe to call this
multiple times). The reason this isn't done for you in the AUBase
constructor is that the call uses virtual methods to create elements
(some AU implementations will create their own element sub-classes), so
the object must be completely constructed before this will work.
It looks like this:
ComponentOpen calls:
static Dispatch - this creates an instance of your AUBase subclass
(new Class in ComponentEntryPoint::Dispatch)
Class *This = new Class(ci);
This->PostConstructor(); // allows base class to do additional
initialization
// once the derived class is fully constructed
If PostConstructor is not over-written by the derived class, then it
will just call the CreateElements itself.
But, once your derived class's constructor has run to construct its
parent classes, you can call CreateElements yourself of course. So in
the Sample Effect's constructor you'll see the following (which is a
pattern you can follow):
// example of setting up params...
CreateElements();
Globals()->UseIndexedParameters(numParams);
for (int i = 0; i < numParams; ++i) {
SetParameter (i, 0.5); // this sets all of our parameters initial
value to 0.5 - this is calling AUEffectBase's version of SetParameter -
which defaults to scope == Global, elID == 0
}
Note the call to:
virtual void UseIndexedParameters(int inNumberOfParameters);
This is defined in AUElement (and the numParams arg is just used to set
the reserved size of the vector that will be used) - this can of course
grow in size if you add more parameters - but its good to start off
with a reserved size that is the num parameters you'll use/need.
Once that is done, GetParameter will just return the value for the
given param ID (and because its a vector, its cheap and can be called
in your render methods.
Using this technique, you will also get full support for both saving
and restoring state with no additional work by you - its all handled in
AUBase for you. It *just* works :)
An important distinction between this mechanism and implementations
I've seen from people coming from the VST world is that this separates
the state of parameters from any allocations that you would do in
Initialize. To my mind this is a far better mechanism, as it also
avoids you having to both:
(a) write a parameter mechanism yourself (even if that is something as
simple as member variables in your AU class)
(b) Having done (a), you'd also then need to over-write the
Save/Restore methods of AUBase to save and restore your parameter
variables to/from an AUPreset dictionary.
The supposed optimisation of (a) above I think can best be
characterised by the observation "Premature optimisation is the root of
all evil" :)
Hope that clarifies this...
Bill
>
>
TIA.
>
--
>
-----------------------------------------
>
English is not my native language,
>
so I'm not good at English, sorry :-(
>
M.Yoshida @ Japan
>
_______________________________________________
>
coreaudio-api mailing list | email@hidden
>
Help/Unsubscribe/Archives:
>
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
>
Do not post admin requests to the list. They will be ignored.
>
>
--
mailto:email@hidden
tel: +1 408 974 4056
________________________________________________________________________
__
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
________________________________________________________________________
__
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.