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