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 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 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 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 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 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