Re: sample data types (iOS)
Re: sample data types (iOS)
- Subject: Re: sample data types (iOS)
- From: Brian Willoughby <email@hidden>
- Date: Tue, 8 Feb 2011 00:17:53 -0800
On Feb 7, 2011, at 23:26, Schell Scivally wrote:
I just did a little experiment and got +/-2147483648 (INT32_MAX) as
the max and min of SInt32. I'm sorry if this is considered noise for
the list, I have lots of programming experience but not much in the
way of introductory computer science.
There is a distinction between the valid range of a particular type
and the range that is used for audio signals. There is also a
distinction between the basic C language types and the larger set of
types used for audio. So, this topic goes beyond introductory
computer and enters the realm of audio-specific.
All signed integers utilize the full range. Whether you're talking 8-
bit, 16-bit, or 24-bit. A minor exception is 8-bit, where many
systems use unsigned values rather than signed, but it's still
possible to use signed 8-bit for audio. A bigger exception is
SInt32, because you're never going to find a DAC or A/D converter
that runs 32-bit samples (well, there are some very new converters
that are 32-bit, but they're not really any more accurate than a 24-
bit converter, and that's no disappointment because nobody has built
an analog system that realizes the full potential of 24-bit audio).
Disregarding the exceptions above, 8-bit audio would range from -128
to +127, 16-bit audio (iOS) from -32768 to +32767, and 24-bit audio
from -8388608 to +8388607. But when carried around in a true 32-bit
value, the convention is usually to left-justify the value so that
the lowest bits remain unused. In this convention, 32-bit signed
integers range from -2147483648 to +2147483647, where 24-bit samples
jump by 256 steps, 16-bit samples jump by 65536 steps, and 8-bit
samples jump by 16777216 steps. The convenience here is that you can
put 8-bit samples or 16-bit samples into your 32-bit memory and pull
out 24-bit samples without worrying about what is what. Sorry for
the distraction, but you probably won't find 32-bit signed integers
in CoreAudio. You will find them in the FLAC library as the
canonical format.
In contrast, floating point numbers, which are all signed by
definition, have basically an unlimited range. This is not very
useful for audio, which always has a finite range (or a speaker,
which has a maximum excursion). So, a convention developed to use
+/-1.0 for floating point numbers. This convention predates
CoreAudio, but is 100% expected by CoreAudio when dealing with
floats. The conversion between signed integer and floating point is
done using an exact power of 2, e.g., 128, 32768, or 8388608. Thus,
0 dBFS (full scale) is mapped from +/-1.0 to whatever the analog
converters can handle. Keep in mind, though, that CoreAudio is
perfectly compatible with intermediate sample values in a signal path
which exceed the usual +/-1.0 range, and in fact can far exceed that
range (I'm not sure of the exact limit, but I believe it is hundreds
of decibels or more, maybe +770 dB). The only constraint is that the
final stage of the signal path should use whatever gain is necessary
to bring the signal back to +/-1.0 so that the conversion to signed
integer for the analog audio converters will not clip. On iOS, this
signed integer is 16-bit.
Fixed point numbers fall in between signed integers and floats in
terms of valid range versus conventional range. While it's true that
an 8.24 fixed-point number can hold all the same bit patterns as any
other 32-bit type, the convention for audio would be +/-1.0. So, the
upper 8 bits will all be 0 for a positive sample, or they'll be all 1
for a negative sample, and only the lowest 24 bits will vary. You
can see that this allows at least as much precision as 24-bit signed
integer (actually 6 dB better). As with float, intermediate stages
of the signal path are allowed to exceed +/-1.0, but you will clip
much sooner. 8.24 has a maximum signal level of +42.1442 dB before
clipping, and you have to bring the level down to 0 dBFS before
output. But iOS output should be 16-bit signed integer, so you'll
want to make sure your 8.24 samples will fit.
By the way, yet another fixed-point convention is Q.31, where 1 bit
is used for sign, and the rest are fractions. In some respects, the
Q.31 format correlates to the left-justified 32-bit signed integer
scenario that I describe above, although there are always details to
pay attention to when using a language with signed integer types for
fixed-point fractions.
Short answer: Your 8.24 values should range between -16777216 and
+16777215 before you hand them off to the CoreAudio output. They can
be anything if you're processing with AudioUnits other than AUHAL.
Keep in mind, though that -16777216 is the value you think of when
you interpret those 32 bits as a signed integer, but when you
interpret those same 32 bits as 8.24 the value is actually -1.0
instead. The C language is not designed to interpret 8.24, and printf
() is not going to show them to you that way, either.
Brian Willoughby
Sound Consulting
_______________________________________________
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