Re: using integer audio data
Re: using integer audio data
- Subject: Re: using integer audio data
- From: "Timothy J. Wood" <email@hidden>
- Date: Thu, 23 Aug 2001 16:12:21 -0700
On Wednesday, August 22, 2001, at 12:14 AM, Ian Ollmann wrote:
[...]
I wonder if there is a faster way to do it for signed 16 bit ints.
Yes -- this would be the best approach. Right now I'm working on some
cache management for my floating point data. Because the game engine
I'm porting expects to be able to hold onto the original short data and
I need floats for mixing, I'm ending up with 6 bytes per channel rather
than 2 or 4. My sound memory usage was up around 65MB just for the
cached floats. I got this down quite a bit by noticing that the game
loads sounds from disk right away even if they aren't used very often
(or at all). Now I only cache the float representation the first time
the sound is played (I still need to add code to toss the floats if it
isn't played for some number of seconds).
One question before I get into it: do you want to convert -32678...32767
to -32768.0 ... 32767.0 or to -1.0 ... 1.0? I am not familiar with the
floating point format in use by Core Audio since I haven't had a chance
to
use it yet. I think there is a chance you could get the scaling factor
for
free or nearly free as part of the int->FP conversion by adjusting the
constant used for the exponent. Unfortunately, there is no way to avoid
at
some load/store overhead since there is no direct path between those two
units. The shame is that in this case, I think maybe you would like to
just write the result out from the integer unit and not have to load it
into the FPU and store it back out again. That is a bit more
challenging.
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.
Anyway, it would certainly be ideal to be able to convert shorts to
single-precision floats entirely in the IU since the conversion cost
would (hopefully) be covered by memory latency anyway and I'd be able to
just store 2 bytes per channel instead of 6!
So yeah, I might be able to do a cntlzw to compute the exponent field
and just bit mask it all together (handling negative numbers by negating
before counting leading zeros or some such thing).
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
-tim