Re: CoreAudio Level Of Death
Re: CoreAudio Level Of Death
- Subject: Re: CoreAudio Level Of Death
- From: Urs Heckmann <email@hidden>
- Date: Fri, 12 Nov 2004 16:16:05 +0100
Hiya Doug,
Am 11.11.2004 um 17:52 schrieb Doug Wyatt:
No one is actually examining the buffers and deciding that your AU
must be muted (unless it's whatever AU host you're testing with ...
not our sample code).
NaNs are the antimatter of audio, however -- once you've put one out,
it turns every other floating point number it touches into a NaN. So
if there are any filters or regenerating delays in the signal path,
one NaN will silence the chain until that DSP code is reset (unless
it's smart enough to periodically check for NaNs). It could be that
the Apple built-in drivers have some filters, I don't know offhand and
if they do, it probably depends on the sound hardware and whether
you're using the internal speakers vs. line out.
Hmmm...
I was pretty sure I could locate that silence outside of my plugin...
(the silence doesn't go away even if I bypass all filters or any
otherwise recursive structures after it happens)
I've just successfully reanimated an AU that outputted NaNs to the left
and Infinities to the right for a couple of seconds.
So, I'm not sure anymore...
You can check for NaNs with isnan() (just be aware that it can be
pretty expensive; you probably don't want this check in shipping
code).
According to IEEE specs, all NaNs and Infinities have all bits set in
the exponent, while all denormals have an all zero exponent. Treating
the floats as unsigned integers would allow for extraction of the
exponent and creating comparison results that can be used to find toxic
floats and make them zero. Without branching, of course:
void erase_All_NaNs_Infinities_And_Denormals( float* inSamples, int&
inNumberOfSamples )
{
UInt32* inArrayOfFloats = (UInt32*) inSamples;
for ( int i = 0; i < inNumberOfSamples; i++ )
{
UInt32 sample = *inArrayOfFloats;
UInt32 exponent = sample & 0x7F800000;
// exponent != 0x7F800000 is 0 if NaN or Infinity, otherwise 1
// !exponent is 0 if denormalized, otherwise 1
*inArrayOfFloats++ = sample * ((exponent != 0x7F800000) & !exponent);
}
}
Does that look reasonable? - It could also easily prallelized for
AltiVec...
I havn't found any information about latencies when moving comparison
results from the Condition Register into an Integer Register. I guess
it's a normal 1-cycle latency move? (Or better, I hope so ;-)
Cheers,
;) Urs
_______________________________________________
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