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

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

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

Description:
  This routine writes a specified number of 16-bit integer samples to an audio
  file.  The input to this routine is a buffer of float values. The file must
  have been opened using subroutine AFopenWrite.  A warning message is printed
  if the input values exceed the dynamic range of the integer representation. 

Parameters:
   -> 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) 1996
  $Revision: 1.21 $  $Date: 1996/08/14 18:17:52 $

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

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

#define LW		FDL_INT16
#define MINV(a, b)	(((a) < (b)) ? (a) : (b))
#define NBBUF		8192
#define AMIN		(-32768.)
#define AMAX		(32767.)

void
AFwriteI2 (AFp, Fbuff, Nval)

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

{
  int is, N, i;
  long int Novld;
  long int offs;
  int2_t Buf[NBBUF/LW];
  int2_t *B;
  float Fv;
  unsigned char *cp;
  unsigned char t;

/* Write data to the audio file */
  offs = AFp->End;
  is = 0;
  Novld = AFp->Novld;
  while (is < Nval) {
    N = MINV (NBBUF / LW, Nval - is);
    B = Buf;
    for (i = 0; i < N; ++i) {
      Fv = AFp->ScaleF * Fbuff[i+is];
      if (Fv >= 0.0) {
	Fv = Fv + 0.5;
	if (Fv >= AMAX + 1.) {
	  ++Novld;
	  Fv = AMAX;
	}
      }
      else {
	Fv = Fv - 0.5;
	if (Fv <= AMIN - 1.) {
	  ++Novld;
	  Fv = AMIN;
	}
      }
      *B = (int2_t) Fv;
      if (AFp->Swapb == DS_SWAP) {
	cp = (unsigned char *) B;
	t = cp[1]; cp[1] = cp[0]; cp[0] = t;
      }
      ++B;
    }
    FLwriteFile (AFp->fp, offs, (void *) Buf, (size_t) LW, (size_t) N);
    is = is + N;
    offs = offs + LW * N;
  }

  /* Update the file position and number of overloads*/
  AFp->End = offs;
  if (Novld > 0L && AFp->Novld == 0L)
      UTwarn ("AFwriteI2 - Output data clipped");
  AFp->Novld = Novld;

  return;
}