Re: Audio Units - newbie questions
Re: Audio Units - newbie questions
- Subject: Re: Audio Units - newbie questions
- From: William Stewart <email@hidden>
- Date: Tue, 11 Oct 2005 14:59:52 -0700
On 11/10/2005, at 1:07 PM, Muon Software Ltd - Dave wrote:
In render you are told which output bus you are rendering for.
Could you expand on that in a little more detail? does Render get
called
multiple times for each output bus,
Multiple times, one for each bus you want data for.
or does it get called just once and I'm
supposed to check what busses I've been given and what buffers they
contain?
so far my code assumes the latter.
Nope - when the client calls an AU's render call it provides all the
information:
The buffer to put the data in
the time stamp
the number of frames
the output bus number
A typical implementation that we use in the Matrix Mixer (and an AU
Instrument that we've implemented the dynamic I/O config logic with)
is the following:
In the first call to AU Render with a new time stamp:
- Iterate through all of your inputs
- calculate all of your output data
- this can all be done essentially as an array of "output
channels"
- distribute the appropriate "output channels" to the buffer
supplied for that first render call (based on the bus number)
- consequent calls to the AU's render call with that same
time stamp just distribute the already calculated output data
The AU can determine from its input settings (an AU knows what inputs
are connected, and what aren't), and presumably from its UI (say
which effect/send buses are patched in), exactly what data it needs
to calculate for any given render call - so the above render loop can
of course know what work it needs to do.
Not really just yet - but this something we're doing a bit of work on
at the moment. In the meantime, feel free to ask questions.
OK
Are you sure you are overiding this properly? Try adding a printf to
the Init call in AUBase. What's Reset got to do with this?
My initialisation sequence does some (minimal) work in the
constructor, and
the heavyweight stuff in Initialize.
Right
My Reset function can be called at any
time after the full intialisation has taken place.
It can be called anytime from the API - if you aren't initialised
when you are called, then just don't do anything.
If it is called before
the full initialisation has taken place, it crashes - it simply wasn't
designed to work that way.
You should fix this. In fact, I think auval might even try to test
this case - if it doesn't it will be soon :-)
The code for initialising and resetting the
plugin is common with the VST version and changing it seems like a
kludge.
Why - you think its better that you crash?
My Initialize protoype looks like this:
virtual ComponentResult Initialize();
The implementation looks like this:
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
~~~~~~~~~~~~~~~~
// CMuonTachyon::Initialize
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
~~~~~~~~~~~~~~~~
ComponentResult CMuonTachyon::Initialize()
{
m_fSampleRate=(double)GetOutput(0)->GetStreamFormat().mSampleRate;
m_nBlockSize=(int)GetMaxFramesPerSlice();
if (m_bInitialised==false)
{
getLock();
initprocess();
releaseLock();
m_ptrSynth->enableNonGuiIdle(false);
}
m_bInitialised=true;
return noErr;
}
initprocess is a private function that calls my synth's init and reset
functions with the samplerate and blocksize. This enables my synth
class to
become fully initialised. Then it sets a flag m_bInitialised=true
to show
that Initialize has been correctly called and the synth class is
now ready
to use.
You could use AUBase's IsInitialised call to keep this state.
My Reset implementation looks like this:
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
~~~~~~~~~~~~~~~~
// CMuonTachyon::Reset
//
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
~~~~~~~~~~~~~~~~
ComponentResult CMuonTachyon::Reset(AudioUnitScope inScope,
AudioUnitElement
inElement)
{
//auval can call reset before it calls initalise??
if (m_bInitialised==true)
{
m_fSampleRate=(double)GetOutput(0)->GetStreamFormat
().mSampleRate;
m_nBlockSize=(int)GetMaxFramesPerSlice();
getLock();
m_ptrSynth->reset((int)m_fSampleRate,m_nBlockSize);
releaseLock();
}
else
{
????
Why are you initializing (and crashing) here.
Initialize();
}
return noErr;
}
Because auval calls this function on occasions *before* Initialize
has been
called, I need that extra check to see if m_bInitialised==true. If
I set a
breakpoint in Initialize and a breakpoint in Reset, the breakpoint
in Reset
is hit first every time I run auval.
Ah = so this would be the test I thought I'd added :-)
if (!IsInitialised) return noErr
Where do you handle the cleanup code? (this is where your
m_bInitialised would be set to false)?
void CMuonTachyon::Cleanup()
{
???
}
Bill
--
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
________________________________________________________________________
__
_______________________________________________
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