Re: Calculating peak level in db
Re: Calculating peak level in db
- Subject: Re: Calculating peak level in db
- From: Richard Dobson <email@hidden>
- Date: Tue, 15 Oct 2002 00:17:51 +0100
Well, the trick I use is to use convergent rounding when converting from floats
to shorts, and my underlying concern is with preserving exact symmetry of the
waveform - that is the case if I map floats to +- 32767 (so that 16bit zero =
true DC). A sampled sinusoid that touched both -32768 and +32767 would have a
true DC point 0.5 below 16bit zero, on rendering to analogue. So an ADC that
returned such values from an ideal input sinusoid would be doing something
wrong, in my view. A sinusoid that somehow spanned +- 32768 (which would of
course need something larger than 16bits to hold it), would likewise have true
DC at zero.
To cut a long story short (now there's a pun!), and excluding the matter of
dithering, I can read 16bit samples into floats, scaling by 1/32768 (sadly, I
don't know how to apply shift to a float yet, in ANSI C), and convert said
floats back to shorts using convergent rounding (~not~ a 'simple' C cast - and
on Intel it requires but three _asm instructions) after scaling by 32767, and
amazingly enough, the output samples are bit for bit identical to the input ones.
For example - 16bit input = 16384.
floatsam = 16384 / 32768 = 0.5;
0.5 * 32767 = 16383.5;
After convergent rounding, final sample = 16384.
Only if you use a truncating C cast will you end up with a different value. If
CoreAudio is not preserving exact symmetry of the waveform through such
conversions, I guess we have a small but perfectly formed DC offset somewhere!
Of course, few DACs will be so silent as not to swamp digital DC with noise, so
this may be 'academic' to a degree!
Brian Willoughby wrote:
[ The slightly uncertain area is in the final conversion to hardware
[ in, or for, the DAC, where typically the normalised (dithered and
[ possibly clipped ) floating-point value will be multiplied by
[ 32767, to fit the 16bit range - in this way no integer clipping
[ has to be used, but you would never gets a value of -32768.
This is incorrect. The multiplier is not 32767, but 32768. Further along in
your own message, you mention using 32768 to process incoming 16 bit samples.
You must realize that a simple 16 bit to float to 16 bit stream would not
preserve the original samples if you used 32768 on input and 32767 on output.
So, to return to your example above, you will see both -32768 and 32767, with
clipping applied if any processing on the stream has created values of 1.0 or
greater. I imagine that a simple sign invert of a full-range 16 bit stream
would result in minimal clipping as -32768 (-1.0) is changed to 32768 (1.0) and
clipped to 32767 on put to a physical 16 bit device.
...
_______________________________________________
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.