1 /*-------------- Telecommunications & Signal Processing Lab ---------------
2                              McGill University
3 
4 Routine:
5   struct MOVB_NMR PQmovNMRB (const double EbN[], const double Ehs[],
6                              const struct Par_NMR *NMR)
7   void PQavgNMRB (const struct MOVC_NMR *NMR, int Nchan, int Np,
8                   double *TotalNMRB, double *RelDistFramesB)
9 
10 Purpose:
11   Calculate the noise-to-mask ratio (PEAQ Basic version)
12   Calculate the NMR model output variables (PEAQ Basic version)
13 
14 Description:
15   PQmovNMRB:
16   This routine calculates the average and maximum noise-to-mask ratio for a
17   frame of data (PEAQ Basic Version).
18 
19   PQavgNMRB:
20   This routine averages the NMR values to give the NMR model output variables.
21 
22 Parameters:
23   PQmovNMRB:
24   <-  struct MOVB_NMR
25       Output structure with NMR values
26    -> const double EbN[]
27       Noise patterns
28    -> const double Ehs[]
29       Excitation patterns
30    -> const struct Par_NMR *NMR
31       Structure with NMR tables
32 
33   PQavgNMRB:
34    -> const struct MOVC_NMR *NMR
35       Structure containing the NMR values for each PEAQ frame
36    -> int Nchan
37       Number of channels
38    -> int Np
39       Number of PEAQ frames
40   <-  double *TotalNMRB
41       Model Output variable
42   <-  double *RelDistFramesB
43       Model Output variable
44 
45 Author / revision:
46   P. Kabal  Copyright (C) 2003
47   $Revision: 1.7 $  $Date: 2003/05/13 01:15:13 $
48 
49 -------------------------------------------------------------------------*/
50 
51 #include <math.h>
52 
53 #include "PQevalAudio.h"
54 
55 #define DBP(x)		(10.0 * log10 (x))
56 
57 static double
58 PQ_FractThr (double Thr, const double x[], int N);
59 static double
60 PQ_LinAvg (const double x[], int N);
61 
62 
63 struct MOVB_NMR
PQmovNMRB(const double EbN[],const double Ehs[],const struct Par_NMR * NMR)64 PQmovNMRB (const double EbN[], const double Ehs[], const struct Par_NMR *NMR)
65 
66 {
67   int m;
68   double s, NMRm;
69   struct MOVB_NMR NMRV;
70 
71   const int Nc = NMR->Nc;
72   const double *gm = NMR->gm;
73 
74   NMRV.NMRmax = 0;
75   s = 0;
76   for (m = 0; m < Nc; ++m) {
77     NMRm = EbN[m] / (gm[m] * Ehs[m]);
78     s += NMRm;
79     if (NMRm > NMRV.NMRmax)
80       NMRV.NMRmax = NMRm;
81   }
82   NMRV.NMRavg = s / Nc;
83 
84   return NMRV;
85 }
86 
87 /* Average NMR values */
88 
89 void
PQavgNMRB(const struct MOVC_NMR * NMR,int Nchan,int Np,double * TotalNMRB,double * RelDistFramesB)90 PQavgNMRB (const struct MOVC_NMR *NMR, int Nchan, int Np, double *TotalNMRB,
91 	   double *RelDistFramesB)
92 
93 {
94   int j;
95   double s, Thr;
96 
97   const double ThrdB = 1.5;	/* Threshold in dB */
98   Thr = pow (10, ThrdB / 10);
99 
100   /* Average log values */
101   s = 0;
102   for (j = 0; j < Nchan; ++j)
103     s += DBP (PQ_LinAvg (NMR->NMRavg[j], Np));
104   *TotalNMRB = s / Nchan;
105 
106   s = 0;
107   for (j = 0; j < Nchan; ++j)
108     s += PQ_FractThr (Thr, NMR->NMRmax[j], Np);
109   *RelDistFramesB = s / Nchan;
110 
111   return;
112 }
113 
114 /* Fraction of values above a threshold */
115 
116 static double
PQ_FractThr(double Thr,const double x[],int N)117 PQ_FractThr (double Thr, const double x[], int N)
118 
119 {
120   int Nv, i;
121   double Fd;
122 
123   Nv = 0;
124   for (i = 0; i < N; ++i) {
125     if (x[i] > Thr)
126       ++Nv;
127   }
128 
129   if (N > 0)
130     Fd = ((double) Nv) / N;
131   else
132     Fd = 0;
133 
134   return Fd;
135 }
136 
137 /* Linear average */
138 
139 static double
PQ_LinAvg(const double x[],int N)140 PQ_LinAvg (const double x[], int N)
141 
142 {
143   int i;
144   double s;
145 
146   s = 0;
147   for (i = 0; i < N; ++i)
148     s += x[i];
149 
150   if (N > 0)
151     s = s / N;
152 
153   return s;
154 }
155