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 15:57:42 +0100
[Trying to pull this thread to some sort of conclusion!]
I'm not writing drivers, just soundfile format stuff (user-level processes). But
I think the issues are more or less the same. Of course, a driver is expected
to deliver unmodified values to the user, but if the driver has to convert to
normalised floats, what is it expected to do with the range?
Programmers everywhere complain about having to clip ~somewhere~, when
converting between 16bit and floats, because it puts conditional tests on every
sample. In my own stuff I have to clip floatsam outputs anyway (composer stuff,
experimental, over-range samples are de rigueur), so I am happy to convert 16bit
to float by scaling by 1/32767, and getting -32768 converted to -1.00003; which
I will be clipping later on anyway. Or, I can treat it as overrange, and clip it
on input.
The alternative is to scale by 1/32768, which ensures a full range of normalized
floats, but means you have to map 1.0 (which is ~within range~ for floats) to
32767 on output, clipped from 32768. And of course samples remaim identical, as
you require.
The issue is really: is -32768 the anomalous value, or is +32768 a 'missing but
legitimate' value?
My radical speculation was to scale by 32767/32768, and as noted elsewhere it
does or course amount to a very small drop in level, which indeed does become
noticeable on changes to high-level samples (which I should have checked before
commenting - I tend to avoid running signals above -6dB), but means that the
complete path from ADC to DAC could in principle be conducted without clipping.
Either way, the input driver would scale by 1/32768; the question is how does
the system convert +-1.0 back to 16bit?
Re convergent rounding - this is widely used in DSP chips such as the Motorola
56K series, in their MACR instruction. It is an operation of "round to nearest",
and on Intel involves only three ~asm instructions - it is a lot cheaper than a
C cast. Maybe it is more expensive on PPC (and is certainly expensive if coded
in C). But it is an important process, especially in the absence of dither. For
a straight i/o copy, it is transparent, but minimizes quantisation errors while
keeping them symmetrical, which will in principle be an issue as soon as the
signal is modified in any way.
The scale factor 32767/32768 is so small that it in effect falls inside the
16bit quantisation distance, except, as noted elsewhere, for signals above -6dB.
So um, well, a lot of the samples are unchanged! I need to make more tests, but
initial experiments indicate that the same method applied to 24bit samples does
give identity output, as the (32bit) scale factor is within the quantisation
range even at peak values.
So no worries, I am not about to release any pathological drivers (I have no
plans indeed to develop any!); there are several ways of doing 16bit/float
mapping, and I remain curious as to what the canonical approach is in CoreAudio.
I guess this thread has drifted rather a long way from the subject line now!
Richard Dobson
Brian Willoughby wrote:
[ I agree with all that - and my scaling by 32767 on the output end
[ is in effect that very small amount of 'backing off'. The issues
[ raised was ensuring an identity operation in converting from and
[ to 16bits, and I can do that despite using 32768 one end and 32767
[ the other.
This is not possible. You cannot preserve identity AND introduce a small
amount of "backing off"
If you're talking about specifically preserving only the 65536 distinct values
that are possible in 16 bit streams (when converted to float), while "backing
off" on all the rest, then I will complain loudly since I have 24 bit A/D and
24 bit D/A audio interfaces where I also want identity. In case you haven't
researched it: 32 bit floats only have 1 bit of precision beyond 24 bit fixed
before quantization noise is introduced, so I don't see any way you can deliver
what's promised.
You're not releasing drivers coded like this, are you?
[ I just find the notion of the purely positive clip inelegant.
Sorry, but this is an inherent limitation of fixed point binary numbers with a
finite bit width. It's not something that started with CoreAudio, so I don't
see why CoreAudio should "correct" it during the float to int conversion. It
only affects those who synthesize waveforms or process audio without clip
detection and/or prevention.
[ All other issues aside, I don't need to code for that clipping at
[ all.
Until the floating point A/D and D/A are invented, you'll have to code for
this! Unless you only want to look at your audio on the screen and not ever
hear it :-)
[ It is in any case a moot point how non-identical samples can be
[ without causing a problem. If symmetry is preserved, the
[ differences would amount to just a minuscule change of level, as
[ you say, which is neither here nor there.
Think of it this way: anything that makes it from the analog world to the
digital world will be symmetrical unless you mess with it, therefore preserving
the bits is all you need to preserve symmetry. The fact that twos complement
numbers are asymmetrical in their capacity by no means forces signals
represented by those numbers to become asymmetrical, unless you create
synthetic signals or process sampled signals without detecting and preventing
clipping.
Brian Willoughby
Sound Consulting
_______________________________________________
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.
_______________________________________________
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.