Home | History | Annotate | Download | only in cfront
      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