Re: AUBufferList::CopyBufferContentsTo()
Re: AUBufferList::CopyBufferContentsTo()
- Subject: Re: AUBufferList::CopyBufferContentsTo()
- From: Marc Poirier <email@hidden>
- Date: Mon, 16 May 2005 18:55:38 -0400
On March 29, 2005, at 11:20 AM, William Stewart wrote:
On 29/03/2005, at 2:57 AM, Raphael Dinge wrote:
Hi,
This has been already discussed on this list, but I would
like to give more informations.
If I put an instance of my plugin in *mono to stereo* mode,
it will crash in DP 4.52.
This will occurs in the bypassed part of the AU SDK render code.
At that moment, AUBufferList::CopyBufferContentsTo() will
receive a list of buffers to copy, but there is only
1 src buffer and 2 dst buffers.
Doug already said on that problem : (2004/12/22)
This "shouldn't happen."
When it does happen, there's probably a discrepency between the
format of the AU's bus and the buffer the caller is asking you to
render into ...
So what should be the bus format in the mono to stereo mode
for src and dst buffers ?
1 src buffer is invalid ?
Is this a DP problem ? AU SDK problem ? Plugin problem ?
I would have said that it was a SDK problem, but given Doug
reply, this is no more clear for me.
Many thanks for any informations,
We've just been discussing this with other developers and I've now
written a test case for auval (that I'll be seeding shortly) that
catches this problem.
AUEffectBase has been written and tested primarily to do N-N channel
effects. Thus, all the logic here about:
kernel's for processing each channel
in place and bypass implementations
the render implementation in general
If you are going to use AUEffectBase to do N-M channel effects there
are a number of behaviours you need to over-ride if you are still
going to use this class. As a side note, we subclass AUBase when we do
these kinds of AU's and that has generally been our recommendation.
I was just revisiting my handling of this sort of situation, and I came
up with a proposal that I'd like to make.
Well, first let me say that my initial solution to this was to disable
the EffectBypass property when such an AU was configured with N->M
channels. But I wasn't very happy with this solution. The reason was
because all of these AUs of mine certainly could still do bypass, just
not in the standard way. In all of my cases, I had AUs that allowed
for mono input and multi-channel output. These AUs could easily handle
bypass in these situations by simply copying the single input's audio
data to all of the outputs. I mean, if the AU doesn't do that, then
it's just the host that is going to have to do that. It would be silly
to break bypass capabilities because of that situation.
So what I did is I removed my first solution to this problem and
instead went and modified AUBufferList::CopyBufferContentsTo() to
handle this. I changed this:
void CopyBufferContentsTo(AudioBufferList &abl) const {
if (mPtrState == kPtrsInvalid)
COMPONENT_THROW(-1);
const AudioBuffer *srcbuf = mPtrs->mBuffers;
AudioBuffer *destbuf = abl.mBuffers;
for (UInt32 i = abl.mNumberBuffers; i--; ++srcbuf, ++destbuf) {
if (destbuf->mData != srcbuf->mData)
memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
destbuf->mDataByteSize = srcbuf->mDataByteSize;
}
}
to this:
void CopyBufferContentsTo(AudioBufferList &abl) const {
if (mPtrState == kPtrsInvalid)
COMPONENT_THROW(-1);
const AudioBuffer *srcbuf = mPtrs->mBuffers;
AudioBuffer *destbuf = abl.mBuffers;
for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) {
if (i >= mPtrs->mNumberBuffers)
srcbuf--;
if (destbuf->mData != srcbuf->mData)
memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
destbuf->mDataByteSize = srcbuf->mDataByteSize;
}
}
I realize that others may disagree, but I really think this is a pretty
good solution. I realize that some may say that this is invisibly
handling an error situation (calling CopyBufferContentsTo with
mismatched in and out buffer counts, which you shouldn't do), but A) I
think it's way better than crashing and B) the current implementation
already "handles" the case of more inputs than outputs more or less
fine, so why not handle more outputs than inputs? And moreover, I
think that this is pretty good and useful behavior. I realize that
"expected" behavior in this situation is kinda ambiguous, but I think
that this approach does a better job than A) crashing or B) leaving the
higher output buffers unaffected. And if an AU really needs some other
esoteric kind of handling of this situation, then that AU is going to
have to handle that itself whether you implement my suggestion or not,
so why not have an implementation that handles most of those situations
well enough rather than handling none of them?
So anyway, I am hoping that maybe you Apple folks might consider this
as a modification to AUBuffer.h, cuz if not, then I will just keep on
modifying my copy with every SDK release, so I figured at least I
should give a shot at asking for it... ;-)
Marc
_______________________________________________
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