• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Canonical format max amp limits?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.


  • Follow-Ups:
    • Re: Canonical format max amp limits?
      • From: "James Chandler Jr" <email@hidden>
    • Re: Canonical format max amp limits?
      • From: Stephen Davis <email@hidden>
References: 
 >Re: Canonical format max amp limits? (From: James Chandler Jr <email@hidden>)
 >Re: Canonical format max amp limits? (From: Steve Checkoway <email@hidden>)
 >Re: Canonical format max amp limits? (From: Brian Willoughby <email@hidden>)

  • Prev by Date: Re: Canonical format max amp limits?
  • Next by Date: Re: Canonical format max amp limits?
  • Previous by thread: Re: Canonical format max amp limits?
  • Next by thread: Re: Canonical format max amp limits?
  • Index(es):
    • Date
    • Thread