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

Routine:
  int AFwrI1 (AFILE *AFp, const float Fbuff[], int Nval)

Purpose:
  Write 8-bit integer data to an audio file (float input values)

Description:
  This routine writes a specified number of 8-bit integer samples to an audio
  file.  The input to this routine is a buffer of float values.

Parameters:
  <-  int AFwrI1
      Number of samples written.  If this value is less than Nval, an error
      has occurred.
   -> AFILE *AFp
      Audio file pointer for an audio file opened by AFopenWrite
   -> const float Fbuff[]
      Array of floats with the samples to be written
   -> int Nval
      Number of samples to be written

Author / revision:
  P. Kabal  Copyright (C) 1997
  $Revision: 1.13 $  $Date: 1997/10/15 13:45:28 $

-------------------------------------------------------------------------*/

static char rcsid [] = "$Id: AFwrI1.c 1.13 1997/10/15 libtsp-v3r0 $";

#include <libtsp/AFdataio.h>
#include <libtsp/Xstdio.h>
#include <libtsp/AFpar.h>
#include <libtsp/UTtypes.h>

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

#define UINT1_OFFSET	((UINT1_MAX+1)/2)
#define INT1_MAX	(UINT1_OFFSET - 1)
#define INT1_MIN	(-UINT1_OFFSET)

#define FWRITE(buf,size,nv,fp)	(int) fwrite ((const char *) buf, \
					      (size_t) size, (size_t) nv, fp)


int
AFwrI1 (AFp, Fbuff, Nval)

     AFILE *AFp;
     const float Fbuff[];
     int Nval;

{
  int is, N, Nw, i, Iv;
  uint1_t Buf[NBBUF/LW];
  float Fv;

/* Write data to the audio file */
  is = 0;
  while (is < Nval) {
    N = MINV (NBBUF / LW, Nval - is);
    for (i = 0; i < N; ++i) {
      Fv = AFp->ScaleF * Fbuff[i+is];
      if (Fv >= 0.0) {
	Fv += 0.5;
	if (Fv >= INT1_MAX + 1) {
	  ++AFp->Novld;
	  Fv = INT1_MAX;
	}
      }
      else {
	Fv += -0.5;
	if (Fv <= INT1_MIN - 1) {
	  ++AFp->Novld;
	  Fv = INT1_MIN;
	}
      }
      Iv = (int) Fv;
      Buf[i] = (uint1_t) Iv;	/* Result is modulo 256 */
    }
    Nw = FWRITE (Buf, LW, N, AFp->fp);
    is += Nw;
    if (Nw < N)
      break;
  }

  return is;
}
