Re: AUGraph stream format problems
Re: AUGraph stream format problems
- Subject: Re: AUGraph stream format problems
- From: William Stewart <email@hidden>
- Date: Mon, 6 Oct 2003 15:19:47 -0700
AUGraph doesn't make these decisions.
The errors are being returned by the AU you are connecting too (the
connection semantics are enforced by the AU - ie. the connection needs
to have the same format from output to input - if that format is
invalid then the connection will return an error). Its left to the user
of the graph to ensure that the connection will be valid and to deal
with it when it isn't.
We modified this behaviour between Jaguar and Panther given the
discussions we'd had about AU's and format negotiation (ie. can't
generally reset formats if the AU is initialized) - so the AUGraph
code's order of operations was modified to reflect this semantic. Thus,
now, the AUGraph will *not* initialize an AU until it is involved in a
connection, and it will initialize the AU *after* the connection is
made. Obviously, as a connection can involve both input and output
sides, this is not foolproof. Also, if the graph is running, this
connection/initialization will be made on the render thread - generally
not a good idea.
So the general advise is, make sure the formats are correct and the AU
is initialized before connecting it to a playing graph. (That also
allows you to determine if the AU can become a member of the graph at
the location, etc, you want it to be).
On 06/10/2003, at 9:47 AM, Marc Poirier wrote:
I submitted this with the AppleSeed bugreporter this morning (but it's
happening with non-seed versions of AUGraph, too), but I'm posting it
here, too, just because I'd like to confirm that my description is
correct
and also see if anyone else has other ideas of solutions to the
problem:
I'm finding a lot of problems with the way that AUGraph handles the
channel layouts of AUs when connecting different AUs together. First,
I'll give you an example scenario:
I have an AU that is strictly 2-out. I load it. Next in the graph
chain,
I load an AU that is strictly 1-in/2-out (KTGranulator).
That's an illegal connection.
Here's some
console.log stuff that illustrates what's happening (a few of the
messages
are from KTGranulator, but the rest are from either the AUGraph
library or
Numerology):
KTAUGranulator::ChangeStreamFormat(kAudioUnitScope_Input), new num
channels = 2, old num channels = 1
AUEffectBase::Initialize() kAudioUnitErr_FormatNotSupported
This is being generated by the AU - it notices that the format it gets
from its connected output is not the format it currently has on its
input, tries to reformat itself to the requested connection format, and
fails as you'd expect.
NAudioMgr: .. graph update: osStatus: -10868
NAudioMgr : conn node 7 to mixer input: 0
AUEffectBase::Initialize() kAudioUnitErr_FormatNotSupported
AUBase::DoRender() -10868
ERROR STATUS: -10868 : NAudioMgr : update graph
**NAudioMgr, conn group to AU graph DONE
FGenAudModCtlr : audio Controller Update
AUBase::DoRender() -10868
AUBase::DoRender() -10868
AUBase::DoRender() -10868
etc.
So the result is that there are errors Initializing the AU, but the
graph
still tries to render the, and render fails every time, resulting in
silent audio output.
If you've started the graph then of course it is going to try to
render. The fact that you have an AU that hasn't been initialized
correctly is a problem in a running graph - this is really something
you need to resolve as a user of a graph.
The first mistake is that AUGraph is even attempting to set the number
of
input channels to 2.
No, its the AU that is doing this, not the graph. I would imagine that
the graph itself is telling you that the connection failed, either in
the call to connect the unit if the graph is initialized but not
running, or in the next call to AUGraphUpdate if it is running (or if
you make the connection, then try to initialize the graph, in the
initialize call).
AUGraph should look at the AU's response to the
kAudioUnitProperty_SupportedNumChannels property and then see that the
AU
only supports 1-in/2-out.
No - you as the user of the graph need to look at this and not do
things the AU's you have can't do.
Then, after attempting to set that bogus
format, Initialize fails, of course. AUGraph seems to note the
problem,
but continues to try to render anyway, which is the second mistake.
No - that's because you've:
(1) Left the uninitialized node connected to an AU downstream
(2) The graph is running
(3) The bogus unit is connected, is asked to render and can't.
At the very least, if Initialize failed, I think that AUGraph should
not
be including the AU in the render chain. I can't imagine that silence
is
ever the desirable outcome.
You need to be more aware of how you use the graph. What the graph does
give you is the ability to handle calls to it from different threads
(ie. the render thread, and any other thread), and allows you to update
the running state of a graph in a thread-safe manner. That's quite
useful.
However, as a user of the API there are a couple of things you need to
take care of, knowing that once a graph has an AU involved in a
connection, it will have to ensure that the AU is initialized, if it is
initialized (of course). If the graph is running and connections are
made, then the graph will call AudioUnitInitialize if the AU isn't
initialized at the time it makes the connection (thus initialization of
an AU can happen on the render thread... Why? Its the only safe place
it can do this).
Thus:
(1) Is the connection legal
(2) Where will initialization occur
(3) Does this connection require re-initialization
Knowing these things, you can use the graph to take care of safely
updating its run time state, and you can do things outside of the graph
to ensure that once you've "passed" an AU to be involved in a
connection, it will "just work"... Depending on the complexity of the
formats you are dealing with this is not too much code, and can be
easily factored.
But really AUGraph should look at the SupportedNumChannels and should
pay
attention to when its stream format changes fail.
It does - it will return an error. But that error may not be returned
from the call to Connect the Nodes, because if the graph is running, or
if it isn't initialized, then the connection is deferred.
Hope that helps to understand this.
Bill
Perhaps, in this
example scenario where the previous AU has stereo output and then next
has
mono input, AUGraph should throw up a CFUserNotification for the user
explaining that the channel formats don't match and offering either to:
A) mix the first AU's output down to mono, or B) cancel loading the
next
AU.
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.
--
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.