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

Routine:
  AFpar.h

Description:
  Declarations for the TSP audio file routines.

Author / revision:
  P. Kabal  Copyright (C) 1999
  $Revision: 1.56 $  $Date: 1999/06/09 03:34:45 $

----------------------------------------------------------------------*/

#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;		/* Pointer to string */
  int N;		/* Number of characters (includes nulls) */
  int Nmax;		/* Maximum number of characters (size of string) */
};

/* Structures for audio file information */
struct AF_dformat {
  int Format;		/* Data format, FD_INT16, etc. */
  int Swapb;		/* Swap code, DS_EB, DS_NATIVE, etc. */
  double ScaleF;	/* Scaling factor applied to file data */
};
struct AF_ndata {
  long int Ldata;	/* Data space in bytes */
  long int Nsamp;	/* Number of samples (all channels) */
  long int Nchan;	/* Number of channels */
};
struct AF_read {
  double Sfreq;
  struct AF_dformat DFormat;
  struct AF_ndata NData;
  struct AF_info Hinfo;
};
struct AF_write {
  double Sfreq;
  long int Nchan;
  struct AF_dformat DFormat;
  struct AF_info Hinfo;
};

/* 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, FD_INT16, etc. */
  int Swapb;		/* Swap code (DS_NATIVE or DS_SWAP) */
  double Sfreq;		/* Sampling rate */
  double ScaleF;	/* Scale factor applied to file data */
  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_NOERR	0
#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,	/* two's complement integer 8-bit data */
  FD_INT16	= 5,	/* two's complement integer 16-bit data */
  FD_INT24	= 6,	/* two's complement integer 24-bit data */
  FD_INT32	= 7,	/* two's complement integer 32-bit data */
  FD_FLOAT32	= 8,	/* 32-bit float data */
  FD_FLOAT64	= 9,	/* 64-bit float data */
  FD_TEXT	= 10	/* text data */
};
#define NFD		(FD_TEXT+1)

/* 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_INT24	3
#define FDL_INT32	4
#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_INT24,
  FDL_INT32,
  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",
  "24-bit integer",
  "32-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_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 */
};
#define NFT	(FT_TXAUD+1)
#define FT_ERROR	(-1)	/* error, file type cannot be determined */
#define FT_AUTO		255	/* automatic mode (check file header) */
#define FT_UNSUP	256	/* unsupported audio file format */

#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 === */
/* Codes for output audio file types */
#define FTW_UNDEF	0	/* Undefined */
#define FTW_AU		1	/* AU audio file */
#define FTW_WAVE	2	/* RIFF WAVE file */
#define FTW_AIFF_C	3	/* AIFF-C audio file */
#define FTW_NH		4	/* Headerless */

#define FTW_SUBTYPE_MOD	16
#define FTW_NH_EB	(FTW_NH + DS_EB * FTW_SUBTYPE_MOD)
#define FTW_NH_EL	(FTW_NH + DS_EL * FTW_SUBTYPE_MOD)
#define FTW_NH_NATIVE	(FTW_NH + DS_NATIVE * FTW_SUBTYPE_MOD)
#define FTW_NH_SWAP	(FTW_NH + DS_SWAP * FTW_SUBTYPE_MOD)

/* Deprecated names */
#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 FTW_FTYPE_MOD	256
#define FTW_code(ftype,dformat)	((ftype) * FTW_FTYPE_MOD + (dformat))
#define FTW_dformat(code)	((code) % FTW_FTYPE_MOD)
#define FTW_ftype(code)		((code) / FTW_FTYPE_MOD)
#define FTW_subtype(ftype)	((ftype) / FTW_SUBTYPE_MOD)

/* 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 FtypeI;			/* 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 (void);

#define AFopt_ErrorHalt	((AFoptions ())->ErrorHalt)
#define AFopt_NsampND	((AFoptions ())->NsampND)
#define AFopt_RAccess	((AFoptions ())->RAccess)
#define AFopt_FtypeI	((AFoptions ())->FtypeI)
#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_ */
