Re: Preroll semantics & clarification of kAudioUnitProperty_OfflineRender
Re: Preroll semantics & clarification of kAudioUnitProperty_OfflineRender
- Subject: Re: Preroll semantics & clarification of kAudioUnitProperty_OfflineRender
- From: Brian Willoughby <email@hidden>
- Date: Tue, 22 Nov 2011 01:59:57 -0800
On Nov 22, 2011, at 01:04, Heinrich Fink wrote:
So the correct behavior as a host implementor would be to first
check if kAudioUnitProperty_OfflineRender is supported. If this is
the case and if you are about to switch to an offline context (as a
host), you should set this to 'true'. If an audio unit does NOT
support this property, i.e. it returns
kAudioUnitErr_InvalidProperty, I could assume (at least for effect
units) that rendering in offline mode - possibly rendering faster
than real time - should just work. Of course this is not the case
with AUFilePlayer. According to previous discussions AUFilePlayer
does not play well with offline rendering behavior. Just to be
sure: Is this still the case?
So I will further assume that our "preroll" scenario is a valid use
case. To be on the safe side, I will further expect that using
AUFilePlayer as the primary file playback generator unit is
probably not an option, and that we will probably have to roll our
own (e.g. use ExtAudioFileRead directly).
I can now see that kAudioUnitProperty_OfflineRender does not
provide the means to determine whether an audio unit supports a non-
realtime rendering context. So I ask myself: What would be the
correct way to ask an audio unit if it supports offline rendering?
For example, a property for which AUFilePlayer would return false.
Heinrich,
I think that you first have to start by asking what sorts of
conditions might possibly cause an AU to fail when called faster than
real time. I do not believe that there is any reason for a valid AU
to not support offline rendering, i.e., faster-than-real-time rendering.
Thinking about the OfflineRender property is a sidetrack that is
probably doing more to confuse your question than help, not to
mention that it cannot answer your question. My understanding of
OfflineRender is that it is intended as a communication from the host
to the unit, not from the unit to the host. What you need is a way
for the unit to tell the host that it cannot go faster than real
time, and that's simply not part of the API, at least not to my
knowledge.
Basically, an AU gets an optional Reset() call, followed by pull
requests for a given buffer size at a specific offset in time. In
other words, the parameters to Render() provide all the information
that the AU needs, and thus there should be no dependency upon real
time. Hosts are free to call an AU ahead of time to latency-
compensate certain tracks or even all tracks, thus, any AU which
accesses a real time clock outside of the Render() parameters is
subject to performing the wrong calculations. Also, keep in mind
that the time slice for each Render() call can be completely
different, and thus a valid AU can make no assumptions that might
predict when it will be called again.
In reality, an AU uses as much CPU as it is designed to use, and thus
the real constraint to be dealt with is whether the AU might take
longer than real time to produce results in situations that demand
real time. Because the AU API is not reentrant, the host is forced
to wait until the AU returns with the requested data.
In the situation you seem to be describing, the host can really only
call the AU as fast as the AU returns from each call. Thus, it's
really only possible to render faster than real time if the AU can
perform all of its calculations and return to the host quickly enough
for the average Render() call to occur faster than real time.
The purpose of the OfflineRender property is for the host to inform
the AU that it can use as much CPU time as it needs, regardless of
whether this time is greater than the time slice. Otherwise, the AU
should use as little CPU as needed to get the job done, and even
still there is no guarantee that an AU will execute in real time on
every possible system (think: really old Macs). Thus, the
OfflineRender property seems to allow the host to request one of two
situations: A) telling the AU to use all the CPU that it wants to in
order to produce the best results, assuming quality is more important
than calculation time, or B) telling the AU to assume that time is of
the essence and to use the CPU sparingly in order to maximize the
chances of keeping up with real time, assuming that promptness (i.e.
real time performance) is more important than quality.
As for validity, I'm not sure whether it is valid to use a
combination of OfflineRender to pre-roll and Online Render for
playback. It seems like it should be valid, but I do not know
whether it is safe to assume that all audio will be valid if part of
it is rendered in one mode and another part is rendered in another
mode. Depending upon the internal implementation of OfflineRender, a
given AU may not be able to use certain state variables when that
property changes value. Then again, I may have missed a AU
specification that requires specific behavior in this respect.
The only safe assumption would seem to be that you can either use
OfflineRender exclusively, or Online Render. In either case, your
safest bet would be to issue a Reset() call to clear any possible
invalid state in the AU, and then use a single mode only.
I'm sure that most AUs have state that is not formatted any different
in each mode (if the AU even has an offline mode), in which case my
caveat is moot. But this sort of thing is completely opaque to the
AU host.
I have a hunch that, rather than needing some means to determine
whether an AU support non-real-time rendering, what you really need
is some means to determine whether it is safe to assume that you can
mix offline and online rendering from one call to the next without
producing an invalid state.
Brian Willoughby
Sound Consulting
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden