Forums

-32768 to 32767 for Range of Digital Audio?

Started by Chris Barrett January 17, 2007
I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) 
held in memory.  I want to write it to disk as 16 bit audio.  Do I fill 
the range of the type short and convert my data to integers with a range 
of -32768 to 32767?  Or, do I try to preserve symmetry and convert to a 
range of -32767 to 32767?

Thanks.
cincydsp@gmail.com wrote:
> Chris Barrett wrote: > >>I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) >>held in memory. I want to write it to disk as 16 bit audio. Do I fill >>the range of the type short and convert my data to integers with a range >>of -32768 to 32767? Or, do I try to preserve symmetry and convert to a >>range of -32767 to 32767? >> >>Thanks. > > > -32768 to +32767 is typically used; it's not symmetric, but that's the > price for using two's-complement arithmetic! There's not a huge > difference anyway. > > Jason >
I'm not sure how to transform double (-1.0 to 1.0) to short (-32768 to 32767). 1.0 is 32767, right? 0.0 is 0, right? is -1.0 = -32768?
PeteS wrote:
> Chris Barrett wrote: > >>cincydsp@gmail.com wrote: >> >>>Chris Barrett wrote: >>> >>> >>>>I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) >>>>held in memory. I want to write it to disk as 16 bit audio. Do I fill >>>>the range of the type short and convert my data to integers with a range >>>>of -32768 to 32767? Or, do I try to preserve symmetry and convert to a >>>>range of -32767 to 32767? >>>> >>>>Thanks. >>> >>> >>>-32768 to +32767 is typically used; it's not symmetric, but that's the >>>price for using two's-complement arithmetic! There's not a huge >>>difference anyway. >>> >>>Jason >>> >> >>I'm not sure how to transform double (-1.0 to 1.0) to short (-32768 to >>32767). >> > > > >>1.0 is 32767, right? >> >>0.0 is 0, right? >> >>is -1.0 = -32768? > > > Not quite (but not far off) > > 32767 is 0.999969482421875 when scaled for a range of +/- 1 > -32768 = -1 on the same scale. > > 'Standard' linear 16 bit PCM data spans this range, and would be the > value to pass onto an AC97 system for playback, for instance (altough > it supports 20 bit samples in the spec) > > Cheers > > PeteS >
So would c++ code to transform double (-1.0 to 1.0) to short (-32768 to 32767) resemble the following? //---------------------------------------------------------------------- double audio64bit; // scaled from -1.0 to 1.0 short audio16bit; // scaled from -32768 to 32767 audio16bit = (short)floor((audio64bit[i]+1.0)*65535.0-32768.0+0.5 ); //----------------------------------------------------------------------
Chris Barrett wrote:
> I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) > held in memory. I want to write it to disk as 16 bit audio. Do I fill > the range of the type short and convert my data to integers with a range > of -32768 to 32767? Or, do I try to preserve symmetry and convert to a > range of -32767 to 32767? > > Thanks.
-32768 to +32767 is typically used; it's not symmetric, but that's the price for using two's-complement arithmetic! There's not a huge difference anyway. Jason
Chris Barrett wrote:
> cincydsp@gmail.com wrote: > > Chris Barrett wrote: > > > >>I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) > >>held in memory. I want to write it to disk as 16 bit audio. Do I fill > >>the range of the type short and convert my data to integers with a range > >>of -32768 to 32767? Or, do I try to preserve symmetry and convert to a > >>range of -32767 to 32767? > >> > >>Thanks. > > > > > > -32768 to +32767 is typically used; it's not symmetric, but that's the > > price for using two's-complement arithmetic! There's not a huge > > difference anyway. > > > > Jason > > > > I'm not sure how to transform double (-1.0 to 1.0) to short (-32768 to > 32767). >
> 1.0 is 32767, right? > > 0.0 is 0, right? > > is -1.0 = -32768?
Not quite (but not far off) 32767 is 0.999969482421875 when scaled for a range of +/- 1 -32768 = -1 on the same scale. 'Standard' linear 16 bit PCM data spans this range, and would be the value to pass onto an AC97 system for playback, for instance (altough it supports 20 bit samples in the spec) Cheers PeteS
PeteS wrote:
> Chris Barrett wrote: > >>cincydsp@gmail.com wrote: >> >>>Chris Barrett wrote: >>> >>> >>>>I have a program that has 64 bit audio of type double(range:-1.0 to 1.0) >>>>held in memory. I want to write it to disk as 16 bit audio. Do I fill >>>>the range of the type short and convert my data to integers with a range >>>>of -32768 to 32767? Or, do I try to preserve symmetry and convert to a >>>>range of -32767 to 32767? >>>>
..
> 32767 is 0.999969482421875 when scaled for a range of +/- 1 > -32768 = -1 on the same scale. > > 'Standard' linear 16 bit PCM data spans this range, and would be the > value to pass onto an AC97 system for playback, for instance (altough > it supports 20 bit samples in the spec) >
Not forgetting (a) to dither/noiseshape the audio prior to reduction to 16bits, and (b) ensure you have a peak amplitude not of 0dBFS but -3dBFS (16bit rounded up: +-24000), to be on the safe side of clipping. Then your output can be truly symmetrical around zero while also cutting the DAC converter just a little slack. (I confess, I always use +-32767, myself. I like symmetry.). Richard Dobson
I do it like this:

double v; // [-1.0,1.0]

// without rounding

out=(short)(v*32767.0);

// with rounding

if(v < 0.0)
out=(short)(v*32767.0-0.5);
else
out=(short)(v*32767.0+0.5);


Take care,
Robert A.