Re: using integer audio data
Re: using integer audio data
- Subject: Re: using integer audio data
- From: Bill Stewart <email@hidden>
- Date: Thu, 23 Aug 2001 23:26:40 -0700
On Thursday, August 23, 2001, at 05:15 PM, Ian Ollmann wrote:
On Thu, 23 Aug 2001, Timothy J. Wood wrote:
By default CoreAudio wants -1.0..1.0, but there is a
'kAudioDevicePropertyVolumeScalar' property that is commented as:
// a Float32 between 0 and 1 that scales the volume of the
device/channel.
I'm not sure if this is something that the hardware supports or
whether this scaling done in software. Is there any way to tell? If
this was done in hardware, then I could set this to 1.0/32768.0
and get
free conversion to -1.0 .. 1.0.
I doubt our sound hardware magically started accepting floating point
input when OS X appeared. Did they already accept it? Otherwise,
my guess
is that probably the OS does the mixing in software and then does
a final
float->SInt16 conversion before sending the data to the hardware,
except
where the hardware accepts floating point input.
Why do you need floats for mixing? You can be very successful with
longs.
No hardware is floating point at the moment. That is not the reason
we did this.
I'll try writing something up tonight and if I get something useful,
I'll post it to the list. I'll probably look something like:
// build a mask of 0x0 or 0xffffffff by replicating sign bit of input
// negate input
// choose the positive input by ((neg & mask) | (pos & ~mask))
// count leading zeros of positive value
// shift exponent and positive input around to get resulting value
// or in the top bit of the mask to get the sign bit
That would work. Dont forget to rotate so that the first bit of your
significand is cut off when you insert the exponent and sign bit.
I am not
quite sure if this method is faster, though. Lets see, give or
take a bug
or two it would probably look very roughly like this:
long mask = value >> 31;
long negValue = -value;
value = (negValue & mask) | (value & ~mask);
long zeros = __cntlzw( value );
long exponent = (mask & 256) + (127 - zeros);
value <<= 8 + zeros;
value = __rlwimi( value, exponent, 23, 0, 8 );
So, 12 instructions, quite a few of which can overlap. Even with good
store to load data forwarding you will lose at least 6 cycles just
for the
transfer to the FPU plus another three for dealing with the silent
1 bit
in the FP format, so there is a good chance you can beat the standard
conversion this way by a cycle or two. More importantly some CPU's
will be
able to do one or more conversions concurrently because they have 2-3
integer units.
However, you will never get 1.0 as a result and I think the value
0 fails
to generate 0.0, though it does make a suitably small number that
it may
not matter. The worry is that the reverse float->int conversion
(if any)
before the value hits hardware will cause a replacement of all of these
with a 1 or that (1/2)/32768 appearing where a 0 should be will
cause some
unfortunate rounding in the mixer.
When recording or generating audio content in a digital domain it
has been pretty clearly demonstrated that incorrect flipping of a
single value can have an impact on the quality of the recording.
For instance, the original CD authoring was highly criticized for
its dry sound, as against the warmth of analog source. This has
been redressed through a number of products that reproduce the
noise-floor charateristics of analog in a digital medium. The
truncation or off-by-one type of artifacts are a major cause of
this problem.
There are a number of products on the market that are used in CD
production and a number of magazines that describe these processes
in more detail (I'm not going to write a research paper in this
reply:)
The headroom of floating point and its precision is a major reason
why we chose to use it - and why most (if not all) pro-audio apps
use floating point engines. Secondly, as reiterated in an earlier
email, there are a number of different audio devices now that
support a variety of bit-depths, endian-ness - using floating point
shields an application from these details without any loss in
resolution or any truncation/representation problems. Having a
floating point path when doing any kind of DSP (including sample
rate conversion - which many games still use because of disk I/O
constraints) will also ensure a more accurate rendering of the data.
As also mentioned previously, aside from the sound manager - which
will continue to be a 16bit/stereo based sound service on X through
Carbon, CoreAudio will also provide an AudioConverter (and also
some revisions to the DefaultOutputUnit) that will allow an
application to continue to do its work in an integer format and use
optimised conversion paths to the AudioDevice.
What is more important in the SInt16->float conversion, that 32767
becomes
1.0 or that 0 becomes 0.0? How do you scale it? Ints are not
symmetrically
distributed about 0.
Its not just SInt16 that you'd have to deal with - many USB devices
are 24 bit, and some are 20 bit.
Bill
Ian
---------------------------------------------------
Ian Ollmann, Ph.D. email@hidden
---------------------------------------------------
_______________________________________________
coreaudio-api mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
mailto:email@hidden
tel: +1 408 974 4056
__________________________________________________________________________
Cat: "Leave me alone, I'm trying to nap... Ah, What's that clicking
noise?"
__________________________________________________________________________