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

Routine:
  AFpar.h

Description:
  Declarations for the TSP audio file routines.

Author / revision:
  P. Kabal  Copyright (C) 1998
  $Revision: 1.47 $  $Date: 1998/06/13 02:45:33 $

----------------------------------------------------------------------*/

#ifndef AFpar_h_
#define AFpar_h_

#include <stdio.h>		/* typedef for FILE */
#include <libtsp/UTpar.h>	/* Byte swap codes DS_SWAP, etc. */

#ifndef	AFILE_t_
#  define	AFILE_t_
typedef struct AF_filepar AFILE;	/* Audio file parameters */
#endif

/* Header information string */
#define FM_AFSP		"AFsp"
#define AF_MAXINFO	10240
struct AF_info {
  char *Info;
  int N;
};

/* Audio file parameter structure */
struct AF_filepar {
  FILE *fp;		/* File pointer */
  int Op;		/* Operation (read, write) */
  int Error;		/* Error flag (0 for no error) */
  int Ftype;		/* File type */
  int Format;		/* Data format */
  int Swapb;		/* Swap flag */
  double Sfreq;		/* Sampling rate */
  double ScaleF;	/* Scale factor */
  long int Nchan;	/* Number of channels */
  long int Start;	/* Start byte */
  long int Isamp;	/* Sample offset */
  long int Nsamp;	/* Number of samples */
  long int Novld;	/* Number of points clipped */
  struct AF_info Hinfo;	/* AFsp information string */
};

/* Error codes for the Error field in the audio parameter structure */
#define AF_UEOF		-1	/* Unexpected end-of-file on read */
#define AF_IOERR	1	/* Read or write error */
#define AF_DECERR	2	/* Data decoding error on read */

/* File operation types */
enum {
  FO_NONE	= 0,	/* closed */
  FO_RO 	= 1,	/* read */
  FO_WO 	= 2	/* write */
};

/* Data format types - must be sequential */
enum {
  FD_UNDEF	= 0,	/* undefined file data format */
  FD_MULAW8	= 1,	/* mu-law 8-bit data */
  FD_ALAW8	= 2,	/* A-law 8-bit data */
  FD_UINT8	= 3,	/* offset binary integer 8-bit data */
  FD_INT8	= 4,	/* twos complement integer 8-bit data */
  FD_INT16	= 5,	/* twos complement integer 16-bit data */
  FD_FLOAT32	= 6,	/* 32-bit float data */
  FD_FLOAT64	= 7,	/* 64-bit float data */
  FD_TEXT	= 8	/* text data */
};
#define NFD		(FD_TEXT+1)
#define FD_DEFAULT	FD_INT16	/* Default data format */

/* Data format sizes */
#define FDL_MULAW8	1
#define FDL_ALAW8	1
#define FDL_UINT8	1
#define FDL_INT8	1
#define FDL_INT16	2
#define	FDL_FLOAT32	4
#define FDL_FLOAT64	8
#define FDL_TEXT	0	/* Variable size */

#ifdef AF_DATA_LENGTHS
static const int AF_DL[NFD] = {
  0,
  FDL_MULAW8,
  FDL_ALAW8,
  FDL_UINT8,
  FDL_INT8,
  FDL_INT16,
  FDL_FLOAT32,
  FDL_FLOAT64,
  FDL_TEXT
};
#endif

#ifdef AF_DATA_TYPE_NAMES
static const char *AF_DTN[NFD] = {
  NULL,
  "8-bit mu-law",
  "8-bit A-law",
  "offset-binary 8-bit integer",
  "8-bit integer",
  "16-bit integer",
  "32-bit float",
  "64-bit float",
  "text data"
};
#endif

/* === Input audio files === */
/* Internal codes for input audio file types - must be sequential for the
   standard file types
*/
enum {
  FT_ERROR	= -1,	/* error, file type cannot be determined */
  FT_UNKNOWN	= 0,	/* unknown audio file format */
  FT_NH		= 1,	/* headerless (non-standard or no header) audio file */
  FT_AU		= 2,	/* AU audio file */
  FT_WAVE	= 3,	/* RIFF WAVE file */
  FT_AIFF_C	= 4,	/* AIFF-C audio file */
  FT_SPHERE	= 5,	/* NIST SPHERE audio file */
  FT_ESPS	= 6,	/* ESPS sampled data feature file */
  FT_SF		= 7,	/* IRCAM soundfile */
  FT_SPPACK	= 8, 	/* SPPACK file */
  FT_INRS	= 9,	/* INRS-Telecom audio file */
  FT_AIFF	= 10,	/* AIFF audio file */
  FT_SPW	= 11,	/* Comdisco SPW Signal file */
  FT_TXAUD	= 12,	/* Text audio file */
  FT_AUTO	= 255,	/* automatic mode (check file header) */
  FT_UNSUP	= 256	/* unsupported audio file format */
};
#define NFT	(FT_TXAUD+1)

#ifdef AF_FILE_TYPE_NAMES
static const char *AF_FTN[NFT] = {
  NULL,
  "Audio file",		/* Headerless or non-standard audio file */
  "AU audio file",
  "RIFF WAVE file",
  "AIFF-C audio file",
  "NIST SPHERE audio file",
  "ESPS audio file",
  "IRCAM soundfile",
  "SPPACK file",
  "INRS-Telecom audio file",
  "AIFF audio file",
  "Comdisco SPW Signal file",
  "Text audio file"
};
#endif

/* Structure for headerless input audio file parameters */
struct AF_NHpar {
  int Format;		/* Data format */
  long int Start;	/* Offset in bytes to the start of data */
  double Sfreq;		/* Sampling frequency */
  int Swapb;		/* Byte swap flag */
  long int Nchan;	/* Number of channels */
  float ScaleF;		/* Scale factor */
};

/* Defines for data length checks */
/* Special values for Ldata, Nsamp and Nframe */
#define AF_LDATA_UNDEF	-1L
#define AF_NSAMP_UNDEF	-1L
#define AF_NFRAME_UNDEF	-1L

/* Header data length fixup flags */
#define AF_NOFIX		0
#define AF_FIX_NSAMP_HIGH	1
#define AF_FIX_NSAMP_LOW	2
#define AF_FIX_LDATA_HIGH	4

/* === Output audio files === */
/* Internal codes for output audio file types - must be sequential */
enum {
  FTW_AU	= 0,	/* AU audio file */
  FTW_WAVE	= 1,	/* RIFF WAVE file */
  FTW_AIFF_C	= 2,	/* AIFF-C audio file */
  FTW_NH_EB	= 3,	/* Headerless (big-endian data) */
  FTW_NH_EL	= 4,	/* Headerless (little-endian data) */
  FTW_NH_NATIVE	= 5,	/* Headerless (native byte order data) */
  FTW_NH_SWAP	= 6,	/* Headerless (byte-swapped data) */
  FTW_UNDEF	= 255	/* unknown audio file format */
};
#define FTW_DEFAULT	FTW_AFSP

/* Deprecated codes */
#define FT_SUN		FT_AU
#define	FT_AFSP		FT_AU
#define FTW_SUN		FTW_AU
#define FTW_AFSP	FTW_AU

/* External file type codes for AFopenWrite */
#define FW_FTYPE_MOD	256
#define FW_code(ftype,dformat)	((ftype) * FW_FTYPE_MOD + (dformat))
#define FW_ftype(code)		((code) / FW_FTYPE_MOD)
#define FW_dformat(code)	((code) % FW_FTYPE_MOD)

/* File types for write */
#define FW_AU		FW_code (FTW_AU, 0)
#define FW_WAVE		FW_code (FTW_WAVE, 0)
#define FW_AIFF_C	FW_code (FTW_AIFF_C, 0)
#define FW_NH_EB	FW_code (FTW_NH_EB, 0)
#define FW_NH_EL	FW_code (FTW_NH_EL, 0)
#define FW_NH_NATIVE	FW_code (FTW_NH_NATIVE, 0)
#define FW_NH_SWAP	FW_code (FTW_NH_SWAP, 0)
#define FW_UNDEF	FW_code (FTW_UNDEF, 0)	/* Undefined file type */

#define FW_DEFAULT	FW_code (FTW_DEFAULT,0 ) /* Default file type */

/* Structure for AF routine options */
struct AF_opt {
  int ErrorHalt;		/* Error handling:
				   0 - continue on error,
				   1 - halt on error */
  int NsampND;			/* Number of samples requirement (input files)
				   0 - Nsamp must be known
				   1 - Nsamp=AF_NSAMP_UNDEF allowed */
  int RAccess;			/* Random access requirement (input files):
                                   0 - input file can be sequential only or
				       random access
                                   1 - input file must be random access */
  int Ftype;			/* Input file type, FT_AUTO, FT_AU, etc. */
  struct AF_NHpar NHpar;	/* Headerless input audio file parameters */
  long int Nframe;		/* Number of frames (output files)
				   AF_NFRAME_UNDEF means this value is
				   undefined */
};

/* Default sampling frequency if the sampling frequency is zero or invalid */
#define AF_SFREQ_DEFAULT	8000.0

/* Access to options */
struct AF_opt *AFoptions p_((void));

#define AFopt_ErrorHalt	((AFoptions ())->ErrorHalt)
#define AFopt_NsampND	((AFoptions ())->NsampND)
#define AFopt_RAccess	((AFoptions ())->RAccess)
#define AFopt_Ftype	((AFoptions ())->Ftype)
#define AFopt_NHpar	((AFoptions ())->NHpar)
#define AFopt_Nframe	((AFoptions ())->Nframe)

/* Default options */
#define AF_OPT_DEFAULTS \
	{ 1, 0, 0, FT_AUTO, \
	  {FD_UNDEF, 0L, AF_SFREQ_DEFAULT, DS_NATIVE, 1L, 1.0}, \
	  AF_NFRAME_UNDEF }

#endif	/* AFpar_h_ */
