PLEASE HELP - Strange problem converting from bytes to float

Discussion in 'Java' started by cpptutor2000@yahoo.com, Mar 23, 2008.

  1. Guest

    Could some Java guru please help me ? I am trying to create a simple
    application that will capture audio from the PC's default listening
    device and do some FFT with the data. The audio bytes are collected in
    a byte array, and the main problem I am having right now is how to
    convert them to the floating point numbers that would be used in the
    computation of the FFT. For prototyping purposes, I am using a
    floating point array as :

    private final int len = 4096;

    float [][] floatArray = new float[len][2];

    The reason I am using using the 2-D array is that one dimension would
    hold the real and the other the imaginary component of the complex
    numbers to be used for the FFT. To convert consecutive chunks of 4
    bytes to get a floating point number, I am using the following
    function:

    public static float arr2float (byte[] arr, int start)
    {
    int i = 0;
    int len = 4;
    int cnt = 0;
    byte[] tmp = new byte[len];
    for (i = start; i < (start + len); i++)
    {
    tmp[cnt] = arr;
    cnt++;
    }
    int accum = 0;
    i = 0;
    for ( int shiftBy = 0; shiftBy < 32;
    shiftBy += 8 )
    {
    accum |= ( (long)( tmp & 0xff )
    ) << shiftBy;
    i++;
    }
    return Float.intBitsToFloat(accum);
    }

    The actual conversion from the raw bytes to the flaoting point numbers
    is done via a loop as:

    for (int start = 0; start < 4096; start += 4)
    {
    floatArray[cnt][0] =
    RecordUtility.arr2float(recordedSoundArray,
    start);
    floatArray[cnt][1] = 0;
    System.out.println(cnt + " "
    +floatArray[cnt][0]);
    cnt++;
    }

    Unfortunately, the output of the print statement looks like:
    0 12690.33
    1 1.64703E-40
    2 3428.0837
    3 2.0703801E-19
    4 2.24E-44
    5 9.1837E-41
    6 1.121E-41
    7 2.2421E-41
    8 1.469371E-39
    9 2.8175146E20
    10 1.64653E-40

    This is what bothers me that the numbers are huge or very small, and
    there are quite a few 'NaN's.

    Could someone please kindly provide some hints as what I might be
    doing wrong?

    Thanks in advance for your help.
    , Mar 23, 2008
    #1
    1. Advertising

  2. Mark Space Guest

    wrote:
    > Could some Java guru please help me ? I am trying to create a simple
    > application that will capture audio from the PC's default listening
    > device and do some FFT with the data. The audio bytes are collected in



    Well for starters, if you're using a Clip, then sample can take a
    variable number of bits, not bytes. And they can be either big endian
    or little endian.

    <http://java.sun.com/javase/6/docs/api/javax/sound/sampled/AudioFormat.html>

    You may want to clarify first what your data actually looks like. Then
    we can give you a hand with the conversion.
    Mark Space, Mar 23, 2008
    #2
    1. Advertising

  3. Guest

    On Mar 22, 7:47 pm, Mark Space <> wrote:
    > wrote:
    > > Could some Java guru please help me ? I am trying to create a simple
    > > application that will capture audio from the PC's default listening
    > > device and do some FFT with the data. The audio bytes are collected in

    >
    > Well for starters, if you're using a Clip, then sample can take a
    > variable number of bits, not bytes. And they can be either big endian
    > or little endian.
    >
    > <http://java.sun.com/javase/6/docs/api/javax/sound/sampled/AudioFormat...>
    >
    > You may want to clarify first what your data actually looks like. Then
    > we can give you a hand with the conversion.


    I am sorry I did not provide that information. I am using PCM
    encoding, with sampling rate = 8000 and channel = 1 (mono)
    , Mar 23, 2008
    #3
  4. Logan Shaw Guest

    wrote:
    > On Mar 22, 7:47 pm, Mark Space <> wrote:
    >> wrote:
    >>> Could some Java guru please help me ? I am trying to create a simple
    >>> application that will capture audio from the PC's default listening
    >>> device and do some FFT with the data. The audio bytes are collected in

    >> Well for starters, if you're using a Clip, then sample can take a
    >> variable number of bits, not bytes. And they can be either big endian
    >> or little endian.
    >>
    >> <http://java.sun.com/javase/6/docs/api/javax/sound/sampled/AudioFormat...>
    >>
    >> You may want to clarify first what your data actually looks like. Then
    >> we can give you a hand with the conversion.

    >
    > I am sorry I did not provide that information. I am using PCM
    > encoding, with sampling rate = 8000 and channel = 1 (mono)


    Looking at AudioFormat.Encoding, it appears likely that your input
    bytes represent plain old simple base-2 integer sample values. But
    you're calling Float.intBitsToFloat(), which assumes they are IEEE
    floating point values. Instead of all that, once you've converted
    your bytes into an integer, you probably just want to use a cast to
    convert the integer into a float.

    Also, you appear to be assuming that one sample (for one channel)
    is 32 bits wide based on this loop:

    for ( int shiftBy = 0; shiftBy < 32;
    shiftBy += 8 )

    It's fairly uncommon (but not impossible, I guess) for anyone
    to use 32 bit integers for transferring audio. 24-bit integers
    are good enough, and I don't think anyone has ever built an A-to-D
    that can give 32 bits worth of integer resolution and not have
    the low order 8 bits be anything other than noise. So I would
    suspect your incoming samples are either 16-bit integers or
    24-bit integers. Or maybe even 8-bit integers if you are using
    a sample rate as low as 8000 Hz.

    - Logan
    Logan Shaw, Mar 23, 2008
    #4
  5. Roedy Green Guest

    On Sat, 22 Mar 2008 17:34:44 -0700 (PDT), ""
    <> wrote, quoted or indirectly quoted someone
    who said :

    >This is what bothers me that the numbers are huge or very small, and
    >there are quite a few 'NaN's.


    The obvious first. See http://mindprod.com/jgloss/endian.html
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Mar 23, 2008
    #5
  6. Lew Guest

    Logan Shaw wrote:
    > floating point values. Instead of all that, once you've converted
    > your bytes into an integer, you probably just want to use a cast to
    > convert the integer into a float.


    You don't need a cast because it's a widening conversion.

    --
    Lew
    Lew, Mar 23, 2008
    #6
  7. Logan Shaw Guest

    Lew wrote:
    > Logan Shaw wrote:
    >> floating point values. Instead of all that, once you've converted
    >> your bytes into an integer, you probably just want to use a cast to
    >> convert the integer into a float.

    >
    > You don't need a cast because it's a widening conversion.


    Ah, good point. Not being terribly fresh on the kinds of conversions,
    I simply assumed that any conversion that could result in loss of
    information would require a cast. But as you pointed out, that's not
    how Java works: some widening conversions can result in loss of
    information; they will not lose information about rough magnitude
    of the number, but they can lose precision.

    - Logan
    Logan Shaw, Mar 23, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy
    Replies:
    7
    Views:
    6,243
    Roedy Green
    May 10, 2004
  2. bd
    Replies:
    0
    Views:
    608
  3. mathieu
    Replies:
    9
    Views:
    731
    James Kanze
    Sep 15, 2007
  4. Carsten Fuchs
    Replies:
    45
    Views:
    1,509
    James Kanze
    Oct 8, 2009
  5. Replies:
    6
    Views:
    250
    Peter J. Holzer
    May 13, 2007
Loading...

Share This Page