// Copyright 2003 Regents of the University of California

// Astropulse is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2, or (at your option) any later
// version.

// Astropulse is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
// more details.

// You should have received a copy of the GNU General Public License along
// with Astropulse; see the file COPYING.  If not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifndef _WIN32
#include "ap_config.h"
#endif

#include "sbtf.h"

/* splitter_bits_to_float
 *
 * Arguments:
 * raw: An array of unsigned chars, every two bits corresponds to a
 *   complex sample.  The 1 and 2 bits are the first real and imaginary
 *   sample, respectively; then the 4 and 8 bits, and so on.
 * data: An array of floats, initially empty.  This will contain
 *   an array of complex samples, in the form of pairs of floats, each
 *   of which will equal either 1.0 or -1.0
 * nsamples: The number of COMPLEX samples to convert.
 */
int splitter_bits_to_float(unsigned char *raw, float *data, int nsamples) {

  unsigned int i, iprime, j;
  unsigned char s;
  static int first_time=1;
  /* The first index to lut (look up table) is the input char.
   * For each input char, there are 8 floats to output,
   * which are indexed by the second index to lut.
   */
  static float lut[256][8];

  if ( nsamples%8 )
    return(-1);

  /* If we are running this function for the first time,
   * create a look up table.  This table converts bytes into
   * arrays of 8 floats.
   */
  if (first_time) {
    for (i=0;i<256;i++) {
      s=(unsigned char)i;
      for (j=0;j<4;j++) {
        lut[i][j*2]=2*(s & 1)-1;
        s >>= 1;
        lut[i][j*2+1]=2*(s & 1)-1;
        s >>= 1;
      }
    }
    first_time--;
  }

  /* I don't understand why we are switching the byte order
   * The data is created on a machine with little endian
   * ordering, so the low order byte is stored first, even if
   * the data is written in words.  Then the file is
   * read by Wufile::read_raw_data in ap_fileio.cpp, which
   * reads one character at a time from in.dat to an array
   * called data_chunk.  The data part of this array is then
   * read into client.rawdata.  At no point does the byte order
   * get reversed from little endian (low order first) ordering.
   * So I don't see the problem.
   * => I've commented out the line that switches the bytes
   *    It's actually irrelevant what kind of machine was used
   *    because the machine stores 16 channels in two bytes
   *    each channel is ordered in the usual way.
   */
  for (i=0;i<((unsigned int)nsamples/4);i++) {
    // iprime = (i & 1)?(i-1):(i+1); // bigendian ordering
    iprime = i;
    memcpy(data+8*i,lut[raw[iprime]],8*sizeof(float));
  }

  return(0);
}


