/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: int AFreadTA (AFILE *AFp, long int offs, float Fbuff[], int Nreq) Purpose: Read samples (text data) from an audio file (return float values) Description: This routine reads a specified number of samples from an audio file. The data in the file is converted to float format on output. The file must have been opened using subroutine AFopenRead. Parameters: <- int AFreadTX Number of data values transferred from the file. On reaching the end of the file, this value may be less than Nreq. -> AFILE *AFp Audio file pointer for an audio file opened by AFopenRead -> long int offs Offset into the file in samples. The parameter offs must be non- negative. <- float Fbuff[] Array of floats to receive the samples -> int Nreq Number of samples requested. Nreq may be zero. Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.2 $ $Date: 1996/04/28 22:23:57 $ -------------------------------------------------------------------------*/ static char rcsid [] = "$Id: AFreadTA.c 1.2 1996/04/28 AFsp-V2R1 $"; #include #include #include #ifndef SEEK_SET /* normally defined in stdio.h */ # include #endif #define MINV(a, b) (((a) < (b)) ? (a) : (b)) int AFreadTA (AFp, offs, Fbuff, Nreq) AFILE *AFp; long int offs; float Fbuff[]; int Nreq; { char *line; int n, m, Nd; char c; float Fv; /* This routine spends most of its time in sscanf. Consider a rather large file of some 24 Mb, with 4.7M samples. - read data, copy to another file, 912 sec CPU - read data (sscanf commented out), copy to another file, 88 sec CPU */ offs = MINV (offs, AFp->Nsamp); /* Rewind if the position is before the current postion */ if (offs < AFp->Isamp) { if (fseek (AFp->fp, AFp->Start, SEEK_SET) != 0) UTerror ("AFreadTA: Error from fseek"); AFp->Isamp = 0L; } /* Move forward to the desired position */ for (; AFp->Isamp < offs; ++AFp->Isamp) { line = FLgetLine (AFp->fp); if (line == NULL) UThalt ("AFreadTA: Unexpected end-of-file"); } /* Read the data */ Nd = (int) MINV (Nreq, AFp->Nsamp - AFp->Isamp); c = '\0'; for (n = 0; n < Nd; ++n) { line = FLgetLine (AFp->fp); if (line == NULL) UThalt ("AFreadTA: Unexpected end-of-file"); m = sscanf (line, "%g%c", &Fv, &c); if (m != 1 || c != '\0') UThalt ("AFreadTA: Data format error, sample: %ld", offs+n); Fbuff[n] = AFp->ScaleF * Fv; } AFp->Isamp += n; return n; }