/*------------- Telecommunications & Signal Processing Lab -------------- McGill University Routine: void CAcorr (AFILE *fpA, FILE *fpB, int delay, long int Nsseg, struct Stats_T *Stats) Purpose: Gather correlation statistics for two audio files Description: This routine gathers cross-statistics for audio files. The statistics are the sum of cross-products, number of differences, maximum difference, number of difference runs, and the accumulated log SNR values for segments of length Nsseg. Parameters: -> AFILE *AFpA Audio file pointer for file A -> AFILE *AFpB Audio file pointer for file B -> int delay delay of file B relative to file A -> int Nsseg Segment length in samples for segmental SNR computations <- struct Stats_T *Stats Structure containing the file statistics Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.9 $ $Date: 1996/06/01 02:41:29 $ -----------------------------------------------------------------------*/ static char rcsid[] = "$Id: CAcorr.c 1.9 1996/06/01 AFsp-V2R1 $"; #include /* fabs, log10 */ #include #include "CompAudio.h" #define NBUF 2560 #define MAXV(a, b) (((a) > (b)) ? (a) : (b)) static const struct Stats_T Init_T = { 0.0, 0L, 0.0, 0L, 0L, 0.0}; void CAcorr (AFpA, AFpB, delay, Nsseg, Stats) AFILE *AFpA; AFILE *AFpB; int delay; long int Nsseg; struct Stats_T *Stats; { int Inrun; float Xa[NBUF]; float Xb[NBUF]; int i, Na, Nb, N, k; long int ioffs; int diffa, diffb; double Sx2, Sd2, Sxy; /* Initialization */ *Stats = Init_T; Stats->Nsseg = Nsseg; Inrun = 0; Sx2 = 0.0; Sd2 = 1e-2; k = 0; ioffs = 0; diffa = MAXV (0, -delay); diffb = MAXV (0, delay); while (1) { /* Read the audio files */ Na = AFreadData (AFpA, ioffs+diffa, Xa, NBUF); Nb = AFreadData (AFpB, ioffs+diffb, Xb, NBUF); ioffs = ioffs + NBUF; if (Na <= 0 && Nb <= 0) break; /* Data comparisons */ Sxy = 0.0; N = MAXV (Na, Nb); for (i = 0; i < N; ++i) { if (Xa[i] != Xb[i]) { if (Inrun == 0) { ++Stats->Nrun; Inrun = 1; } ++Stats->Ndiff; Stats->Diffmax = MAXV (Stats->Diffmax, fabs (Xa[i] - Xb[i])); } else { Inrun = 0; } /* Cross products */ Sxy = Sxy + (double) Xa[i] * (double) Xb[i]; /* Segmental SNR update */ Sx2 = Sx2 + (double) Xa[i] * (double) Xa[i]; Sd2 = Sd2 + (double) (Xb[i] - Xa[i]) * (double) (Xb[i] - Xa[i]); ++k; if (k >= Nsseg) { Stats->SNRlog = Stats->SNRlog + log10 (1.0 + Sx2 / Sd2); ++Stats->Nseg; Sx2 = 0.0; Sd2 = 1e-2; k = 0; } } Stats->Sxy = Stats->Sxy + Sxy; } return; }