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.
Reply by Richard Dobson●January 17, 20072007-01-17
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
Reply by PeteS●January 17, 20072007-01-17
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
Reply by ●January 17, 20072007-01-17
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
Reply by Chris Barrett●January 17, 20072007-01-17
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 );
//----------------------------------------------------------------------
Reply by Chris Barrett●January 17, 20072007-01-17
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?
Reply by Chris Barrett●January 17, 20072007-01-17
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.