1 /*------------ Telecommunications & Signal Processing Lab --------------
2                          McGill University
3 
4 Routine:
5   PQevalAudio.h
6 
7 Description:
8   Declarations for PQevalAudio
9 
10 Author / revision:
11   P. Kabal  Copyright (C) 2003
12   $Revision: 1.24 $  $Date: 2003/05/13 01:10:54 $
13 
14 ----------------------------------------------------------------------*/
15 
16 #ifndef PQevalAudio_h_
17 #define PQevalAudio_h_
18 
19 #define PROGRAM "PQevalAudio"
20 #define VERSION	"v2r0  2003-05-12"
21 
22 #include <libtsp.h>		/* typedef for AFILE */
23 #include <libtsp/AFpar.h>	/* struct AF_NHpar */
24 #include <AO.h>			/* struct AO_FIpar */
25 
26 #define AFPATH_ENV	"$AUDIOPATH"
27 
28 #define PQ_FIpar	AO_FIpar	/* Input file structure */
29 
30 #define PQ_FS		48000.	/* Sampling frequency (double) */
31 #define PQ_NF		2048	/* Frame length */
32 #define PQ_CB_ADV	(PQ_NF/2)  /* Frame advance */
33 #define PQ_FB_ADV	192	/* Sub-sampling factor in filter bank */
34 #define PQ_FCS		1019.5	/* Test sine frequency */
35 #define PQ_AMAX		32768.	/* Max. input level corresponding to
36 				   to the max. listening level */
37 #define PQ_NL		256	/* Number of correlation lags (EHS MOV) */
38 
39 #define PQ_BASIC	0
40 #define PQ_ADVANCED	1
41 #define PQ_CBMODEL	0
42 #define PQ_FBMODEL	1
43 
44 #define PQ_NC_B		109
45 #define PQ_NC_CB_A	55
46 #define PQ_NC_FB_A	40
47 #define PQ_MAXNC	PQ_NC_B	/* Maximum number of channels */
48 
49 #define PQ_NMOV_B	11
50 #define PQ_NMOV_A	5
51 #define PQ_NMOV_MAX	11
52 
53 /* PEAQ parameter tables */
54 struct Par_FFT {
55   double hw[PQ_NF];		/* Hamming window (including all scaling) */
56 };
57 struct Par_CB {
58   double W2[PQ_NF/2+1];		/* Middle and outer ear weighting (energy) */
59   int Nc;			/* Number of bands */
60   double dz;			/* Band width in Bark */
61   const double *fc;		/* Centre frequencies */
62   int kl[PQ_MAXNC];		/* Lower band edges (DFT bin number) */
63   int ku[PQ_MAXNC];		/* Upper band edges (DFT bin number) */
64   double Ul[PQ_MAXNC];		/* Fractional bins at the lower band edges */
65   double Uu[PQ_MAXNC];		/* Fractional bins at the upper band edges */
66   double Bs[PQ_MAXNC];		/* Spreading function normalization */
67   double EIN[PQ_MAXNC];		/* Internal noise */
68 };
69 struct Par_TDS {
70   int Nc;			/* Number of bands */
71   double a[PQ_MAXNC];		/* Time domain spreading coefficients */
72   double b[PQ_MAXNC];		/* b[k] = 1 - a[k] */
73 };
74 struct Par_Patt {
75   int Nc;			/* Number of bands */
76   int M1;			/* Lower frequency averaging limit */
77   int M2;			/* Upper frequency averaging limit */
78   double a[PQ_MAXNC];		/* Smoothing coefficients */
79   double b[PQ_MAXNC];		/* b[k] = 1 - a[k] */
80 };
81 struct Par_Loud {
82   int Nc;			/* Number of bands */
83   double s[PQ_MAXNC];		/* Excitation index */
84   double Et[PQ_MAXNC];		/* Energy threshold */
85   double Ets[PQ_MAXNC];		/* Pre-computed multiplicative term */
86 };
87 struct Par_MPatt {
88   int Nc;			/* Number of bands */
89   double a[PQ_MAXNC];		/* Smoothing coefficients */
90   double b[PQ_MAXNC];		/* b[k] = 1 - a[k] */
91 };
92 struct Par_MDiff {
93   int Nc;			/* Number of bands */
94   double a[PQ_MAXNC];		/* Time domain spreading, coefficients */
95   double b[PQ_MAXNC];		/* b[k] = 1 - a[k] */
96   double Ete[PQ_MAXNC];		/* Energy threshold (0.3 power) */
97 };
98 struct Par_NLoud {
99   int Nc;			/* Number of bands */
100   double Et[PQ_MAXNC];		/* Energy threshold */
101 };
102 struct Par_BW {
103   int N;			/* Number of frequency points */
104   int kx;			/* Upper limit (DFT bin, 21586 Hz) */
105   int kl;			/* Lower limit (DFT bin, 8109 Hz) */
106   double FR;			/* Threshold factor for the reference signal */
107   double FT;			/* Threshold factor for the test signal */
108 };
109 struct Par_NMR {
110   int Nc;			/* Number of bands */
111   double gm[PQ_MAXNC];		/* Masking offset */
112 };
113 struct Par_EHS {
114   double EnThr;			/* Energy threshold (half frame) */
115   int kst;			/* Starting lag */
116   int NL;			/* Number of correlation lags */
117   int M;			/* Number of terms in a correlation sum */
118   double Hw[PQ_NL];		/* Scaled Hann window */
119 };
120 struct Par_NNet {
121   int I;			/* Number of inputs */
122   int J;			/* Number of hidden layer nodes */
123   const double *amin;		/* MOV scaling factors */
124   const double *amax;
125   const double *wx[PQ_NMOV_MAX]; /* Neural net weights */
126   const double *wxb;
127   const double *wy;
128   double wyb;
129   double bmin;			/* DI scaling factors */
130   double bmax;
131   int ClipMOV;			/* MOV clipping flag */
132 };
133 
134 /* Structure for parameter tables */
135 struct PQ_Par {
136   struct Par_FFT   FFT;
137   struct Par_CB    CB;
138   struct Par_TDS   TDS;
139   struct Par_Patt  Patt;
140   struct Par_Loud  Loud;
141   struct Par_MPatt MPatt;
142   struct Par_MDiff MDiff;
143   struct Par_NLoud NLoud;
144   struct Par_BW	   BW;
145   struct Par_NMR   NMR;
146   struct Par_EHS   EHS;
147   struct Par_NNet  NNet;
148 };
149 
150 /* Filter memory arrays */
151 struct Mem_TDS {
152   double *x[2];
153 };
154 struct Mem_Adap {
155   double *P[2];
156   double *PC[2];
157   double *Rn;
158   double *Rd;
159 };
160 struct Mem_Env {
161   double *DE[2];
162   double *Ese[2];
163   double *Eavg[2];
164 };
165 
166 /* Structure for filter memories */
167 struct PQ_FiltMem {
168   struct Mem_TDS  TDS;
169   struct Mem_Adap Adap;
170   struct Mem_Env  Env;
171 };
172 
173 /* Instantaneous MOV precursors */
174 struct MOVB_Loud {
175   double NRef;
176   double NTest;
177 };
178 struct MOVB_MDiff {
179   double Mt1B;
180   double Mt2B;
181   double Wt;
182 };
183 struct MOVB_NLoud {
184   double NL;
185 };
186 struct MOVB_BW {
187   double BWRef;
188   double BWTest;
189 };
190 struct MOVB_NMR {
191   double NMRavg;
192   double NMRmax;
193 };
194 struct MOVB_PD {
195   double p[PQ_MAXNC];
196   double q[PQ_MAXNC];
197 };
198 struct MOVB_EHS {
199   double EHS;
200 };
201 
202 /* Structure with MOV precursors for one time instant */
203 struct PQ_MOVBI {
204   struct MOVB_Loud  LoudV;
205   struct MOVB_MDiff MDiffV;
206   struct MOVB_NLoud NLoudV;
207   struct MOVB_BW    BWV;
208   struct MOVB_NMR   NMRV;
209   struct MOVB_PD    PDV;
210   struct MOVB_EHS   EHSV;
211 };
212 
213 /* Structures with time history of MOV precursors */
214 struct MOVC_Loud {
215   double *NRef[2];
216   double *NTest[2];
217 };
218 struct MOVC_MDiff {
219   double *Mt1B[2];
220   double *Mt2B[2];
221   double *Wt[2];
222 };
223 struct MOVC_NLoud {
224   double *NL[2];
225 };
226 struct MOVC_BW {
227   double *BWRef[2];
228   double *BWTest[2];
229 };
230 struct MOVC_NMR {
231   double *NMRavg[2];
232   double *NMRmax[2];
233 };
234 struct MOVC_PD {
235   double c1;
236   double *Pc;
237   double *Qc;
238 };
239 struct MOVC_EHS {
240   double *EHS[2];
241 };
242 
243 /* Structure with MOV precursors for each frame */
244 struct PQ_MOVBC {
245   struct MOVC_Loud  Loud;
246   struct MOVC_MDiff MDiff;
247   struct MOVC_NLoud NLoud;
248   struct MOVC_BW    BW;
249   struct MOVC_NMR   NMR;
250   struct MOVC_PD    PD;
251   struct MOVC_EHS   EHS;
252 };
253 
254 /* PEAQ options */
255 struct PQ_Opt {
256   double Lp;			/* Maximum listening level (dB SPL) */
257   int Ni;			/* Print every NI'th PEAQ frame */
258   int ClipMOV;			/* MOV clipping flag */
259   double PCinit;		/* Initial value for pattern corrections */
260   double PDfactor;		/* Forgetting factor for prob. detection */
261   int OverlapDelay;		/* Overlap warmup frames and delay */
262   int DataBounds;		/* Find data boundaries */
263   int EndMin;			/* Min. number of samples in last PEAQ frame */
264   int EHSLagStart;		/* First EHS correlation lag (0 or 1) */
265 };
266 
267 #define LP_DEFAULT		92.
268 #define NI_DEFAULT		-50
269 #define CLIP_MOV_DEFAULT	0
270 #define PC_INIT_DEFAULT		0.
271 #define PD_FACTOR_DEFAULT	1.
272 #define OVERLAP_DELAY_DEFAULT	1
273 #define DATA_BOUNDS_DEFAULT	1
274 #define END_MIN_DEFAULT		(PQ_NF/2)
275 #define EHS_LAG_START_DEFAULT	1
276 
277 #define OPTIONS_INIT(p) { \
278 	(p)->Lp = LP_DEFAULT; \
279 	(p)->Ni = NI_DEFAULT; \
280 	(p)->ClipMOV = CLIP_MOV_DEFAULT; \
281 	(p)->PCinit = PC_INIT_DEFAULT; \
282 	(p)->PDfactor = PD_FACTOR_DEFAULT; \
283         (p)->OverlapDelay = OVERLAP_DELAY_DEFAULT; \
284         (p)->DataBounds = DATA_BOUNDS_DEFAULT; \
285         (p)->EndMin = END_MIN_DEFAULT; \
286         (p)->EHSLagStart = EHS_LAG_START_DEFAULT; }
287 
288 /* Error messages */
289 #define PQM_BadEndMin	"Invald end_min value"
290 #define PQM_BadEHSStart	"Invalid EHS_corr_start value"
291 #define PQM_BadInfo	"Invalid info specification"
292 #define PQM_BadKey	"Invalid option keyword"
293 #define PQM_BadPCinit	"Invalid PC_init value"
294 #define PQM_BadPDfactor	"Invalid PD factor"
295 #define PQM_BadLevel	"Invalid level specification"
296 #define PQM_DiffNChan	"Numbers of channels differ"
297 #define PQM_DiffSFreq	"Sampling frequencies differ"
298 #define PQM_InvSFreq	"Invalid sampling frequency, must be 48000"
299 #define PQM_LateFPar	"Input file parameter specified after input files"
300 #define PQM_NoFName	"No filenames specified"
301 #define PQM_XFName	"Too many filenames specified"
302 #define PQM_XNChan 	"Too many channels"
303 
304 /* Usage */
305 #define PQMF_Usage "\
306 Usage: %s [options] AFileR AFileT\n\
307 Options:\n\
308   -g GAIN, --gain=GAIN        Gain factor to the input files.\n\
309   -l L:U, --limits=L:U        Input frame limits.\n\
310   -L LEVEL, --levelSPL LEVEL  Level for a max amplitude sine (dB SPL).\n\
311   -i NI, --info=NI            Print frame information every NI'th frame.\n\
312   -o OPTIONS, --options=OPTIONS Processing options,\n\
313                               \"clip_MOV\", \"no_clip_MOV\",\n\
314                               \"PC_init=V\", \"PD_factor=V\",\n\
315                               \"overlap_delay\", \"no_overlap_delay\",\n\
316                               \"data_bounds\", \"no_data_bounds\",\n\
317                               \"end_min=N\", \"EHS_lag_start=N\".\n\
318   -t FTYPE, --type=FTYPE      Input file type,\n\
319                               \"auto\", \"AU\", \"WAVE\", \"AIFF\", \"noheader\",\n\
320                               \"SPHERE\", \"ESPS\", \"IRCAM\", \"SPPACK\",\n\
321                               \"INRS\", \"SPW\", \"NSP\", or \"text\".\n\
322   -P PARMS, --parameters=PARMS  Parameters for headerless input files,\n\
323                               \"Format,Start,Sfreq,Swapb,Nchan,ScaleF\".\n\
324   -h, --help                  Print this message and exit.\n\
325   -v, --version               Print the version number and exit."
326 
327 
328 #ifdef __cplusplus
329 extern "C" {
330 #endif
331 
332 /* Prototypes */
333 void
334 PQDFTFrame (const double x[], const double hw[], double X2[], int NF);
335 void
336 PQWOME (const double f[], double W2[], int N);
337 void
338 PQadapt (const double *Ehs[2], const struct Par_Patt *Patt,
339 	 double *EP[2], struct Mem_Adap *Adap);
340 void
341 PQavgBW (const struct MOVC_BW *BW, int Nchan, int Np,
342 	 double *BandwidthRefB, double *BandwidthTestB);
343 double
344 PQavgEHS (const struct MOVC_EHS *EHS, int Nchan, int Np);
345 void
346 PQavgModDiffB (int Ndel, const struct MOVC_MDiff *MDiff, int Nchan, int Np,
347 	       double *WinModDiff1B, double *AvgModDiff1B,
348 	       double *AvgModDiff2B);
349 void
350 PQavgMOVB (const struct PQ_MOVBC *MOVC, int Nchan, int Nwup, int Np,
351 	   double MOV[]);
352 double
353 PQavgNLoud (int ist, const struct MOVC_NLoud *NLoud, int Nchan, int Np);
354 void
355 PQavgNMRB (const struct MOVC_NMR *NMR, int Nchan, int Np, double *TotalNMRB,
356 	   double *RelDistFramesB);
357 void
358 PQavgPD (const struct MOVC_PD *PD, int Np, double *ADBB, double *MFPDB);
359 void
360 PQchanPD (int Nc, int Nchan, const struct PQ_MOVBI MOVBI[],
361 	  double *Pc, double *Qc);
362 void
363 PQdataBoundary (AFILE *AFp, long int Nchan, long int StartS, long int Ns,
364 		long int Lim[2]);
365 struct PQ_MOVBI
366 PQeval (const double xR[], const double xT[], const struct PQ_Par *PQpar,
367 	struct PQ_FiltMem *Fmem);
368 void
369 PQenThresh (const double f[], double Et[], int N);
370 void
371 PQexIndex (const double f[], double s[], int N);
372 void
373 PQframeMOVB (const struct PQ_MOVBI MOVBI[], int Nchan, int i,
374 	     struct PQ_MOVBC *MOVC);
375 void
376 PQgenTables (int Version, const struct PQ_Opt *PQopt, struct PQ_Par *PQpar);
377 void
378 PQinitFMem (int Nc, double PCinit, struct PQ_FiltMem *Fmem);
379 void
380 PQintNoise (const double f[], double EIN[], int N);
381 void
382 PQgroupCB (const double F[], const struct Par_CB *CB, double Pe[]);
383 double
384 PQloud (const double Ehs[], const struct Par_Loud *Loud);
385 int
386 PQloudTest (const struct MOVC_Loud *Loud, int Nchan, int Np);
387 struct MOVB_BW
388 PQmovBW (const double *X2[], const struct Par_BW *BW);
389 double
390 PQmovEHS (const double xR[], const double xT[], const double *X2[],
391 	  const struct Par_EHS *EHS);
392 struct MOVB_MDiff
393 PQmovModDiffB (const double *M[2], const double ERavg[],
394 	       const struct Par_MDiff *MDiff);
395 double
396 PQmovNLoudB (const double *M[2], const double *EP[2],
397 	     const struct Par_NLoud *NLoud);
398 double
399 PQmovNMRA (const double EbN[], const double Ehs[], const struct Par_NMR *NMR);
400 struct MOVB_NMR
401 PQmovNMRB (const double EbN[], const double Ehs[], const struct Par_NMR *NMR);
402 struct MOVB_PD
403 PQmovPD (const double *Ehs[]);
404 void
405 PQmodPatt (const double *Es[2], const struct Par_MPatt *MPatt,
406 	   double *M[2], double ERavg[], struct Mem_Env *Env);
407 double
408 PQnNet (const double MOV[], const struct Par_NNet *NNet);
409 void
410 PQoptions (int argc, const char *argv[], struct PQ_Opt *PQopt,
411 	   struct PQ_FIpar FI[2]);
412 void
413 PQprtMOV (const double MOV[], int N, double ODG);
414 void
415 PQprtMOVCi (int Nchan, int i, const struct PQ_MOVBC *MOVC);
416 int
417 PQreadChan (AFILE *AFp, long int Nchan, long int offs, double *x[],
418 	    int Nreq);
419 void
420 PQspreadCB (const double E[], const struct Par_CB *CB, double Es[]);
421 void
422 PQtConst (double t100, double tmin, double Fs, const double f[],
423 	  double a[], double b[], int N);
424 void
425 PQtimeSpread (const double Es[], const struct Par_TDS *TDS, double Ehs[],
426 	      double Ef[]);
427 
428 #ifdef __cplusplus
429 }
430 #endif
431 
432 #endif /* PQevalAudio_h_ */
433