/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: AFILE *AFgetTApar (FILE *fp, const char Fname[], long int *Nsamp, long int *Nchan, float *Sfreq, FILE *fpout) Purpose: Get file format information from a text audio file Description: This routine reads the header for a text audio file. The header information is used to set the file data format information in the audio file pointer structure and to set the returned argument values. A banner identifying the audio file and its parameters is printed. Text audio files have been used to store audio information (specifically noise samples) on CDROM's. The audio data itself is stored as text. The text specifies integer values, with one value per line. Non-sequential access to the data involves rewinding the file for each such access. Text audio header: Offset Length Type Contents 0 4 char File identifier ("%//") - - char Sampling frequency ("%sampling rate: KHz") - - char Audio data For text audio files, the audio data is the character representation of integer values, with one value per line. Parameters: <- AFILE *AFgetSFpar Audio file pointer for the audio file -> FILE *fp File pointer for the file -> const char Fname[] File name <- long int *Nsamp Total number of samples in the file (all channels) <- long int *Nchan Number of channels <- float *Sfreq Sampling frequency from the file header -> FILE *fpout File pointer for printing the audio file identification information. If fpout is NULL, no information is printed. Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.2 $ $Date: 1996/05/07 01:52:47 $ -------------------------------------------------------------------------*/ static char rcsid [] = "$Id: AFgetTApar.c 1.2 1996/05/07 AFsp-V2R1 $"; #include #include #include #include #include #ifndef SEEK_SET /* normally defined in stdio.h */ # include #endif #define LHMIN 21 #define FM_TXAUD "\045\057\057" /* "%//" */ AFILE * AFgetTApar (fp, Fname, Nsamp, Nchan, Sfreq, fpout) FILE *fp; const char Fname[]; long int *Nsamp; long int *Nchan; float *Sfreq; FILE *fpout; { AFILE *AFp; long int Lhead, Nbytes, Ldata, Nsampx; char *line; float Sfreqx; /* Get the size of the file The minimum header length is the length of the file identifier plus the the sampling rate line */ Nbytes = FLfileSize (fp); if (Nbytes < LHMIN) UThalt ("AFgetTApar: File header too short"); /* Check the file magic */ line = FLgetLine (fp); if (strcmp (line, FM_TXAUD) != 0) UThalt ("AFgetTApar: Invalid file identifier"); /* Look for the sampling rate field */ Sfreqx = 0.0; while (1) { Lhead = ftell (fp); if (Lhead < 0) UTerror ("AFgetTApar: Error from ftell"); line = FLgetLine (fp); if (line == NULL) UThalt ("AFgetTApar: Unexpected end-of-file"); if (line[0] != '%') break; sscanf (line, "%%sampling rate:%g KHz", &Sfreqx); /* "KHz" is ignored */ } if (Sfreqx <= 0.0) UThalt ("AFgetTApar: Missing or invalid sampling frequency"); Sfreqx = 1000. * Sfreqx; Ldata = Nbytes - Lhead; /* Data size is implicit */ /* Find the number of samples */ if (fseek (fp, Lhead, SEEK_SET) != 0) UThalt ("AFgetTApar: Error from fseek"); Nsampx = 0; while (FLgetLine (fp) != NULL) ++Nsampx; if (fseek (fp, Lhead, SEEK_SET) != 0) UThalt ("AFgetTApar: Error from fseek"); /* Set the parameters for file access */ AFp = AFsetAFp (fp, FO_RO, FT_TXAUD, FD_TEXT, DS_NATIVE, 1.0, 1L, Lhead, Ldata, Nsampx); /* Check and print the header information */ AFprintAFh (AFp, Fname, "", Sfreqx, fpout); /* Set the return parameters */ *Nsamp = Nsampx; *Nchan = 1; *Sfreq = Sfreqx; return AFp; }