/*------------- Telecommunications & Signal Processing Lab -------------- McGill University Routine: void CAstats (AFILE *AFp, struct Stats_F *Stats) Purpose: Gather statistics from an audio file Description: This routine gathers statistics for an audio files. The statistics are the sum of values, the sum of squared values, minimum value, and maximum value. In addition, the number overloads, number of overload runs, and number of anomalous transitions is returned. Parameters: -> AFILE *AFp Audio file pointer for an audio file opened by AFopenRead <- struct Stats_F *Stats Structure containing the file statistics Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.11 $ $Date: 1996/06/01 02:42:41 $ -----------------------------------------------------------------------*/ static char rcsid[] = "$Id: CAstats.c 1.11 1996/06/01 AFsp-V2R1 $"; #include #include #include "CompAudio.h" #define NBUF 2560 #define MINV(a, b) (((a) < (b)) ? (a) : (b)) #define MAXV(a, b) (((a) > (b)) ? (a) : (b)) static const float Amax = 32767.; static const float Amin = -32768.; static const float Aup = 16383.; static const float Alw = -16384.; /* Initial values for Stats_F structure */ /* This structure should have component Vmax initialized to -FLT_MAX, but DEC cc 2.0 does not accept this expression for initialization; instead we have to assign this value at run time. */ static const struct Stats_F Init_F = { 0L, 0.0, 0.0, 0.0, 0.0, 0L, 0L, 0L, 0}; void CAstats (AFp, Stats) AFILE *AFp; struct Stats_F *Stats; { float X[NBUF]; int Inrange, i, N; long int ioffs; double Sx, Sx2; /* Initialization */ *Stats = Init_F; Stats->Vmin = FLT_MAX; Stats->Vmax = -FLT_MAX; Inrange = 0; ioffs = 0; while (1) { /* Read the audio file */ N = AFreadData (AFp, ioffs, X, NBUF); if (N <= 0) break; Stats->N = Stats->N + N; ioffs = ioffs + NBUF; /* Gather statistics */ Sx = 0.0; Sx2 = 0.0; for (i = 0; i < N; ++i) { Stats->Vmax = MAXV (Stats->Vmax, X[i]); Stats->Vmin = MINV (Stats->Vmin, X[i]); /* Detect overloads and anomalous transitions */ if (X[i] > Aup) { if (X[i] >= Amax) { ++Stats->Novload; if (Inrange != 2) ++Stats->Nrun; Inrange = 2; } else { if (Inrange == -1) ++Stats->Nanomal; Inrange = 1; } } else if (X[i] < Alw) { if (X[i] <= Amin) { ++Stats->Novload; if (Inrange != -2) ++Stats->Nrun; Inrange = -2; } else { if (Inrange == 1) ++Stats->Nanomal; Inrange = -1; } } else { Inrange = 0; } /* Accumulate the double sums and sums of products */ Sx = Sx + X[i]; Sx2 = Sx2 + (double) X[i] * (double) X[i]; } /* Update the sum and sum of products */ Stats->Sx = Stats->Sx + Sx; Stats->Sx2 = Stats->Sx2 + Sx2; } return; }