• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  wav_acc.c  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 
21 
22 static const char wav_acc_c[] = "$Id: wav_acc.c,v 1.6.6.7 2007/10/15 18:06:24 dahan Exp $";
23 
24 #ifndef _RTT
25 #include "pstdio.h"
26 #endif
27 #include <stdlib.h>
28 #include <limits.h>
29 #include <math.h>
30 #include <string.h>
31 #include "passert.h"
32 #include "pendian.h"
33 #include "portable.h"
34 
35 
36 #ifndef _RTT
37 #include "duk_io.h"
38 #endif
39 
40 #include "sample.h"
41 #include "mulaw.h"
42 
43 #include "portable.h"
44 
45 
create_sample_buffer(wave_info * wave,int frame_size,int window_size)46 void create_sample_buffer(wave_info *wave, int frame_size, int window_size)
47 {
48   ASSERT(wave);
49   ASSERT(frame_size > 0);
50   ASSERT(window_size >= frame_size);
51   wave->income = (samdata *) CALLOC(window_size, sizeof(samdata), "cfront.wave.income");
52   wave->outgo = (samdata *) CALLOC(window_size, sizeof(samdata), "cfront.wave.outgo");
53   wave->window_size = window_size;
54   wave->frame_size = frame_size;
55 #if DEBUG
56   log_report("window %d frame %d\n", window_size, frame_size);
57 #endif
58   return;
59 }
60 
free_sample_buffer(wave_info * wave)61 void free_sample_buffer(wave_info *wave)
62 {
63   ASSERT(wave);
64   if (wave->income)
65     FREE((char *)wave->income);
66   if (wave->outgo)
67     FREE((char *)wave->outgo);
68   wave->income = NULL;
69   wave->outgo = NULL;
70   wave->window_size = 0;
71   wave->frame_size = 0;
72   return;
73 }
74 
reset_sig_check(wave_stats * ws)75 void reset_sig_check(wave_stats *ws)
76 /*
77 **  Resets the wave statistics
78 */
79 {
80   int ii;
81 
82   ASSERT(ws);
83 
84   ws->sum  = 0;
85   ws->sum2 = 0;
86   ws->sumsqu = 0;
87   ws->sumsqu2 = 0;
88   ws->nsam = 0;
89   ws->highclip = 0;
90   ws->lowclip = 0;
91 
92   for (ii = 0; ii < MAXHISTBITS; ii++)
93     ws->bithist[ii] = 0;
94 }
95 
96 #define OVERFLOW_MASK 0x40000000
97 
get_sig_check(wave_stats * ws,int * nsam,int * pclowclip,int * pchighclip,int * dc_offset,int * amp,int * pc5,int * pc95,int * overflow)98 void get_sig_check(wave_stats *ws, int *nsam, int *pclowclip, int *pchighclip,
99                    int *dc_offset, int *amp, int *pc5, int *pc95,
100                    int *overflow)
101 /*
102 **  Returns the wave statistics
103 */
104 {
105   float mean;
106   int num;
107   int ntot;
108   int npc;
109   int ii;
110   float sqr_devn;
111 
112   ASSERT(ws);
113 
114   /* *nsam = ws->nsam / 100; */
115   *nsam = ws->nsam;
116 
117   *overflow = 0;
118 
119   if (ws->nsam == 0)
120   {
121     *pclowclip  = 0;
122     *pchighclip = 0;
123     *dc_offset  = 0;
124     *amp        = 0;
125     *pc5 = 0;
126     *pc95 = 0;
127     return;
128   }
129 
130   if (ws->nsam > OVERFLOW_MASK) *overflow = 1;
131 
132   *pclowclip  = (int)(((float)ws->lowclip  * 10000.0) / (float)ws->nsam);
133   *pchighclip = (int)(((float)ws->highclip * 10000.0) / (float)ws->nsam);
134 
135   mean = ((float)ws->sum + (float)ws->sum2 * OVERFLOW_MASK) / ws->nsam;
136 
137   *dc_offset = (int) mean;
138   sqr_devn = (((float)ws->sumsqu + (float)ws->sumsqu2 * OVERFLOW_MASK)
139               / (float)ws->nsam) - (mean * mean);
140   *amp = integer_square_root((int)sqr_devn);
141 
142   /* now analyse the histogram */
143 
144   num = 0;
145   for (ii = 0; ii < MAXHISTBITS; ii++)
146   {
147     num += ws->bithist[ii];
148   }
149 
150   ntot = num;
151   npc = ntot / 20; /* 5% cutoff */
152 
153   for (ii = num = 0; (ii < MAXHISTBITS) && (num < npc); ii++)
154   {
155     num += ws->bithist[ii];
156   }
157 
158   *pc5 = ii;
159 
160   npc = (int)(0.95 * ntot);  /* 95% cutoff */
161 
162   for (ii = num = 0; (ii < MAXHISTBITS) && (num < npc); ii++)
163   {
164     num += ws->bithist[ii];
165   }
166 
167   *pc95 = ii;
168   return;
169 }
170 
acc_wave_stats(wave_info * wave)171 void acc_wave_stats(wave_info* wave)
172 /*
173 **  Updates the wave statistics
174 */
175 {
176   int ii;
177   int val;
178   samdata hclip;
179   samdata lclip;
180   wave_stats *ws;
181   int sumabs;
182   int num;
183 
184   ASSERT(wave);
185 
186   ws = &wave->stats;
187   hclip = ws->highclip_level;
188   lclip = ws->lowclip_level;
189 
190   if (ws->nsam > OVERFLOW_MASK) return;
191   /* as soon as we have at least 1073741824 */
192   /* samples, stop accumulating.   */
193 
194   sumabs = 0;
195   num = 0;
196 
197   for (ii = 0; ii < wave->num_samples; ii++)
198   {
199     val = (int) wave->income[ii];
200     ws->sum += val;
201     ws->sumsqu += val * val;
202     if (ws->sumsqu > OVERFLOW_MASK)
203     {
204       ws->sumsqu -= OVERFLOW_MASK;
205       ws->sumsqu2++;
206     }
207     /* nasty bit here as ANSI C does not do >32bit */
208     /* Assumes that samples are no larger than */
209     /* signed shorts    */
210 
211     ws->nsam++;
212 
213     if (val >= hclip) ws->highclip++;
214     if (val <= lclip) ws->lowclip++;
215 
216     sumabs += abs(val);
217     num++;
218   }
219 
220   if (ws->sum >= OVERFLOW_MASK)
221   {
222     ws->sum -= OVERFLOW_MASK;
223     ws->sum2++;
224   }
225   else if (ws->sum < -OVERFLOW_MASK)
226   {
227     ws->sum += OVERFLOW_MASK;
228     ws->sum2--;
229   }
230   /* another >32bit workaround  */
231   /* assumes wave->num_samples < 32878 */
232   /* this is really overkill as we expect */
233   /* the mean to be around zero anyway */
234 
235   if (num > 0) sumabs /= num;
236   ii = 0;
237   while (sumabs)
238   {
239     sumabs >>= 1;
240     ii++;
241   }
242 
243   ASSERT(ii <= 16); /* unusual case i=16 if all samples -32678 */
244   ws->bithist[ii]++;
245   return;
246 }
247