[Tutor] Converting audio samples from 16-bit signed int to float?

Peter Otten __peter__ at web.de
Mon Jun 21 15:19:19 CEST 2010


Joe Veldhuis wrote:

> Hello all. I'm writing a program that needs to capture audio from a
> soundcard and run FFTs to determine peak frequency for further processing.
> The soundcard's native capture format is 16-bit little-endian signed
> integer samples (values 0-65535), and of course the FFT function requires
> floating-point values (-1.0 - +1.0).
> 
> So, what is the most efficient way to do the necessary conversion? I'm
> using the pyalsaaudio module to access the soundcard, if it matters.

Using numpy should be pretty efficient. Assuming you get your data as a 
bytestring:

>>> import numpy
>>> data = "\x00\x80\x00\x00\xff\x7f"
>>> a = numpy.fromstring(data, dtype="<h")
>>> a
array([-32768,      0,  32767], dtype=int16)
>>> a/32768.
array([-1.        ,  0.        ,  0.99996948])

Or, if you don't find the half-open interval acceptable:

>>> (a+.5)/32767.5
array([ -1.00000000e+00,   1.52590219e-05,   1.00000000e+00])

If you want to use the full interval and avoid moving the origin:

>>> (a>0)*a/32767.+(a<0)*a/32768.
array([-1.,  0.,  1.])

(There may be a better way as I'm not very familiar with numpy and found the 
above by trial and error)

Peter





More information about the Tutor mailing list