AU versions
AU versions
- Subject: AU versions
- From: Marc Poirier <email@hidden>
- Date: Wed, 30 Jul 2003 16:03:07 -0500 (CDT)
This stuff came up a little recently on the AUValidation listserv, but I
thought that it would be better brought up here...
There are currently some problems with AU versioning (and with Component
versioning in general). Damn, looking back, this message is long, so let
me summarize it quickly first:
2 ways to supply versions:
easy to forget one way
lack of documentation
90% of AUs only do the resource way correctly
2 can go out of sync
selector method for getting version is ineffecient
requires an open component instance
hosts that cache data need reliable ways to get AUs' versions
some hosts have long launch time, should cache info but can't
I wrote a function for getting version from resources
efficient - doesn't require opening a component instance
One problem is that there are two ways for a component to supply its
version: there is the version value in the component's 'thng' resource
(which is the resource that the Component Manager uses to identify
something as a component) and then there is the standard Component Manager
selector for getting version, which is kComponentVersionSelect. The
Component API provides 2 methods for getting version from a component,
both of which use the selector and require a ComponentInstance, not a
Component:
long GetComponentVersion(ComponentInstance ci);
ComponentResult CallComponentVersion(ComponentInstance ci);
The first problem with this is that it makes it really easy to create
problems by doing only one of these correctly and forgetting the other, or
allowing one to get out of sync with the other. This is also probably
exacerbated a bit by Apple's docs and example code sort of "forgetting"
about kComponentVersionSelect. It is handled by ComponentBase::Version in
the AU SDK, but there is no documentation for that method, all it says in
/Developer/Documentation/CoreAudio/AudioUnits/SDK/Classes/ComponentBase_fs.html
is:
Version
public virtual method
virtual ComponentResult Version();
and also none of the SDK's example AUs override that method.
The version resource is different, though, because basically you have to
do something for the version, otherwise your 'thng' resource won't be
valid and the Component Manager won't even recognize your AU. So it's a
lot harder to forget about that. I hypothesized that probably every AU
has a valid version in its resource, but that probably hardly any
implement a valid version for kComponentVersionSelect. I decided to test
my hypothesis and I was right (please contact me off-list for my address
where you can send me my prize):
out of 200 AUs that I have:
only 19 implement kComponentVersionSelect correctly
all except 1 implement the version in the resource correctly
So that's a big difference: 10% vs. 99.5%. Also, all of the 19 that do
kComponentVersionSelect correctly were written by me, except for Apple's
DLSMusicDevice.
In my opinion, there shouldn't even be a kComponentVersionSelect selector.
It shouldn't even be a runtime property, it should just be a cached
"Component info" value. You should be able to get it without even opening
a ComponentInstance (more on that below). But since we don't have the
Component API working like that yet, I think that at the very least
Apple's AU SDK should implement ComponentBase::Version in a way such that
it retrieves the version value from the component's resource rather than
requiring the developer to override that method with a valid return. The
chances of people going back and doing that correctly are now very slim
since it's been undocumented and undemonstrated for so long, plus doing it
from resource means that you won't ever have 2 values going out of sync.
The reason why I am concerned about this issue is because valid version
info is crucial for host app's to be able to cache info about an AU and
know when that info has become stale. Some apps, like Logic for example,
currently open every AU component during startup to query info from them.
This takes an enormous amount of time if you have 300+ AUs like I do.
These host apps should really be able to just scan an AU once, cache the
necessary info, and then only do that work again during launch time if the
version of the AU changes. But the current problems are (1) you can't get
the version using the Component API functions without opening the
component and (2) virtually every AU is returning an incorrect value for
that anyway. The solution is for the host app to get the version from the
component resources. Although there currently is no simple function in
the Component API to do this, it is pretty easy to do, and I have written
a function that does this:
http://destroyfx.org/GetComponentVersion-marc.c
I would really like to see something like this added to the Component API,
but until then, anyone is free to use this in their own code however they
wish. I think that ComponentBase::Version should do something like this,
too (it does work fine to cast a ComponentInstance to Component for the
first argument of my function).
Just to give you some idea of the performance difference, here are some
benchmarks that I did with my G4 800 SleekBook. I made a simple app that
loops through every AU effect, MusicEffect, and MusicDevice with
FindNextComponent. My collection includes 300 AUs. Here are some
figures:
simply doing FindNextComponent: 0.1 seconds
also doing my GetComponentVersionFromResource: 0.66 seconds
doing OpenAComponent and CloseAComponent for each AU: 7.8 seconds
also Initializing and Unititializing each AU: 153 seconds
And note that, for the 7.8 seconds value, that's a minimum for hosts that
do anything like that. If you're querying properties, that value will
rise. I know that for me and my 300 AUs, Logic and un-named AU host app
#2 spend over a minute opening, querying, and closing every AU during
every consarn launch.
Okay, I think this message is more than long enough now, I'll stop...
Marc
_______________________________________________
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.