Re: Canonical format max amp limits?
Re: Canonical format max amp limits?
- Subject: Re: Canonical format max amp limits?
- From: Steve Checkoway <email@hidden>
- Date: Wed, 14 Jul 2004 09:44:13 -0700
On Jul 14, 2004, at 3:27 AM, Brian Willoughby wrote:
That wouldn't do any good. In C, all operations involving floating
point
types are executed in double precision. Might as well store the full
double
scalar in Mul16Bit since it's going to be promoted to double before the
multiply is executed no matter what you do.
Not true. The c standard is usually very loose about these sorts of
things. I'd be very surprised if that were the case. Still, I checked
to see what gcc did with a floating point multiply.
[DualG5:~/temp] steve$ cat size.c
#include <stdio.h>
int main()
{
float x = 5.0f;
float y = 3.5f;
float z = x * y;
printf("%e\n", z);
return 0;
}
[DualG5:~/temp] steve$ gcc -S -Wall size.c
[DualG5:~/temp] steve$ cat size.s
<snip>
lis r0,0x40a0
stw r0,64(r30)
lis r0,0x4060
stw r0,68(r30)
lfs f13,64(r30)
lfs f0,68(r30)
fmuls f0,f13,f0
stfs f0,72(r30)
lfs f0,72(r30)
<snip>
Now I don't claim to be an expert at PPC assembler, but it's storing 32
bit values to memory and then loading 32 bit values into floating point
registers and then multiplying them and storing them back to memory. I
don't see any double precision here. (You'll note that the addresses
differ by 4 bytes.)
We've covered this exact topic already on the CoreAudio-API Mailing
List.
Check the archives. Some early sample code from Apple, the Daisy
example, had
this same mistaken code, and was corrected after I pointed out the
error. You
can find the thread by searching for "Willoughby 32767 32768" with the
Exact
match algorithm.
Your code is introducing non-linear distortion into the waveform by
scaling
the positive half of the wave differently than the negative half.
That was most likely the code that I was modeling mine after. If so, it
hasn't been changed since you pointed out the error.
You've just proven that you cannot convert to fixed-point by clipping
to +1.0f
because that exceeds the range of twos-complement numbers (when
normalized as
defined). One solution is to convert to a larger fixed-point number,
such as a
32-bit integer register, and then clip to the lower bit depth e.g. to
32767 if
your result is 16-bit. This is easier to handle in fixed-point,
because the
actual maximum possible float value is very close to, but less than
+1.0f, and
it is different for 16-bit vs. 24-bit (or 20-bit, if your interface is
working
with 20-bit D/A).
Clipping requires the use of an if statement does it not? Two if I'm
not mistaken. One to check if it's over and one to check if it's under.
One really good reason for using the AudioConverter is that you won't
make
these kinds of mistakes.
Perhaps not, but then you pay the price of the function call overhead
for the callbacks.
That would add really nasty quantization noise which isn't very
musical at
all. Probably wouldn't hear it on your MP3 player, but professionals
would run
screaming from Mac OS X and CoreAudio if it were implemented this way.
Really nasty? You're talking about the difference between one sample
being -32767 and one being -32768. Can you really hear that one sample
out of the 44100 others that are being played that second?
For example, if all you were doing is digital passthrough, i.e. simple
16-bit
S/P-DIF input -> CoreAudio Float32 -> 16-bit S/P-DIF output, then your
code
would not be bit-accurate. Audiophiles would not accept this
alteration of a
pure digital bitstream. Also, it would completely ruin Dolby Digital
and DTS
bitstreams (or any other non-PCM bitstream). It's rare that a coded
bitstream
would be processed this way, but there are some examples.
I agree here, but like you say, it's rare that such a thing would
happen. I'd be going from one to the other.
The DIY method requires that you learn a lot about optimization, and
there's
no reason to believe that you'll do a better job than Apple. For
example, your
code uses the C language ?: operator, which is equivalent to an if-else
construct, which really messes up the instruction cache. Your code is
already
slower than the AudioConverter for that reason alone, not to mention
that some
manual unrolling, or use of non-standard compiler options, is needed
for top
speed. Add to all the above the fact that AltiVec optimization is not
fully
automatic, and that takes performance to an entirely higher level if
you know
how to write AltiVec code.
The clipping requires more if statements than the one presented in my
sample code. How does that make mine slower? Does CoreAudio use
AltiVec?
- Steve
_______________________________________________
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.