/*-------------- Telecommunications & Signal Processing Lab ---------------
                             McGill University

Routine:
  int AFreadI1 (AFILE *AFp, long int offs, float Fbuff[], int Nreq)

Purpose:
  Read 8-bit integer data from an audio file (return float values)

Description:
  This routine reads a specified number of 8-bit integer samples from an audio
  file.  The data in the file is converted to float format on output. The file
  must have been opened using subroutine AFopenRead.

Parameters:
  <-  int AFreadI1
      Number of data values transferred from the file.  On reaching the end of
      the file, this value may be less than Nreq.
   -> AFILE *AFp
      Audio file pointer for an audio file opened by AFopenRead
   -> long int offs
      Offset into the file in samples.  The parameter offs must be non-
      negative.
  <-  float Fbuff[]
      Array of floats to receive the samples
   -> int Nreq
      Number of samples requested.  Nreq may be zero.

Author / revision:
  P. Kabal  Copyright (C) 1996
  $Revision: 1.1 $  $Date: 1996/08/14 18:02:37 $

-------------------------------------------------------------------------*/

static char rcsid [] = "$Id: AFreadI1.c 1.1 1996/08/14 AFsp-V2R1 $";

#include <libtsp.h>
#include <libtsp/nucleus.h>
#include <libtsp/AFpar.h>
#include <libtsp/UTtypes.h>

#define LW		FDL_INT8
#define MINV(a, b)	(((a) < (b)) ? (a) : (b))
#define NBBUF		8192

int
AFreadI1 (AFp, offs, Fbuff, Nreq)

     AFILE *AFp;
     long int offs;
     float Fbuff[];
     int Nreq;

{
  long int offsb;
  int Nd, is, n, i, Nval;
  uint1_t Buf[NBBUF/LW];
  int2_t ival;

  offsb = AFp->Start + LW * offs;
  Nd = (int) MINV (Nreq, (AFp->End - offsb) / LW);  /* Nd can be negative */
  for (is = 0; is < Nd; ) {

    /* Read data from the audio file */
    n = MINV (NBBUF / LW, Nd - is);
    Nval = FLreadFile (AFp->fp, (long int) (offsb + is * LW), (void *) Buf,
		       (size_t) LW, (size_t) n);
    if (Nval != n)
      UThalt ("AFreadI1: Unexpected end-of-file");

    /* Convert to float */
    /* For compatibility with non-ANSI compilers (no "signed" keyword), we
       use unsigned characters and handle the sign ourselves */
    for (i = 0; i < Nval; ++i) {
      ival = Buf[i];
      if (ival >= 128)
	ival -= 256;
      Fbuff[is] = AFp->ScaleF * ival;
      ++is;
    }
  }

  return is;
}