Home | History | Annotate | Download | only in cfront
      1 /*---------------------------------------------------------------------------*
      2  *  cheldsp4.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 #include <stdlib.h>
     22 #include <limits.h>
     23 #ifndef _RTT
     24 #include <stdio.h>
     25 #endif
     26 #include <string.h>
     27 #include <math.h>
     28 #include <assert.h>
     29 
     30 
     31 #include "hmm_desc.h"
     32 #include "voicing.h"
     33 #include "specnorm.h"
     34 #include "portable.h"
     35 #include "front.h"
     36 #include "portable.h"
     37 
     38 #include "sh_down.h"
     39 #include "memmove.h"
     40 
     41 
     42 #define DEBUG  0
     43 #define LOG_AS_PRINT 0
     44 
     45 
     46 #if LOG_AS_PRINT /* BP temp debug mode */
     47 #define log_report printf
     48 #endif
     49 
     50 
     51 
     52 /* Rasta */
     53 #define RASTA_SOFT_START   1   /* if this is not 1, rasta initialization is weighted */
     54 
     55 #if RASTA_SOFT_START
     56 #define RASTA_CONSTANT  0.92
     57 #define RASTA_SOFT_CONST (RASTA_CONSTANT/(1-RASTA_CONSTANT))
     58 #else
     59 #define RASTA_CONSTANT  0.85
     60 #endif
     61 
     62 static void regress(cepdata *rg, const cepdata *cp_buf, unsigned short frmind,
     63                     int mel_dim);
     64 static void dd_regress(cepdata *dd, const cepdata *cp_buf, unsigned short frmind,
     65                        int mel_dim);
     66 static void scale_data(const front_cep *cepobj, const featdata *rpram,  featdata *pram1,
     67                        featdata *pram2, featdata *ddpram, const cepdata *rast,
     68                        const cepdata *cep, const cepdata *rcep, const cepdata *ddcep);
     69 static void pack_frame(const front_cep *cepobj, featdata *dest_frame,
     70                        const featdata *rasta_data, const featdata *mel_data,
     71                        const featdata *del_data, const featdata *deldel_data);
     72 
     73 
     74 
     75 static void regress(cepdata *rg, const cepdata*cp_buf, unsigned short frmind,
     76                     int mel_dim)
     77 {
     78   int     i, j, d;
     79   cepdata val;
     80   const cepdata* cpt;
     81   /*
     82   static cepdata a = (cepdata) 0.0;
     83 
     84   if (a == (cepdata) 0.0)
     85   {
     86     for (j = 1; j <= DELTA; j++)
     87       a += j * j;
     88     a *= (cepdata) 2.0;
     89   }
     90   */
     91   /* replace above code with the following constant */
     92   cepdata a = (DELTA * (DELTA + 1) * (2 * DELTA + 1) / 6) * 2;
     93   d = DELTA;
     94   if (frmind < Q2 - 1)
     95   {
     96     cpt = cp_buf + (d - 1) * (mel_dim + 1);
     97     for (i = 0; i <= mel_dim; i++, cpt++)
     98       rg[i] = (cepdata) SHIFT_DOWN((*cpt - *(cpt + mel_dim + 1)), 1 + COSINE_TABLE_SHIFT);  /* Shift does rounding. */
     99   } /* reversed */
    100   else
    101     /* regression coefficients */
    102     for (i = 0; i <= mel_dim; i++)
    103     {
    104       cpt = cp_buf + i;
    105 			val = (cepdata) 0.;
    106 			for (j = 0; j < Q2; j++, cpt += (mel_dim + 1))
    107 				val += (d - j) * SHIFT_DOWN(*cpt, 5);          /* note d-j from j-d */
    108 			rg[i] = (cepdata) SHIFT_DOWN((bigdata)(val / a), COSINE_TABLE_SHIFT - 5); /* scale down the deltas here */
    109 		}
    110   return;
    111 }
    112 static const cepdata deldel[] = {2, 0, -1, -2, -1, 0, 2};  /* delta - delta */
    113 
    114 void dd_regress(cepdata *dd, const cepdata *cp_buf, unsigned short frmind, int mel_dim)
    115 /*
    116 **  Computes ALL delta delta mel cep pars. BP 8/96 */
    117 {
    118   int i, j, d;
    119   cepdata val;
    120   const cepdata *cpt;
    121 
    122   d = DELTA;
    123   if (frmind < Q2 - 1)
    124   {
    125     cpt = cp_buf + (mel_dim + 1);
    126     for (i = 0;i <= mel_dim;i++)
    127     {
    128       dd[i] = (*(cpt + 2 * (mel_dim + 1) + i)
    129                + *(cpt + i)
    130                - 2 * (*(cpt + (mel_dim + 1) + i)));
    131       /* Undo cosine table shifting */
    132       dd[i] = (cepdata) SHIFT_DOWN((bigdata)(dd[i]), COSINE_TABLE_SHIFT);
    133     }
    134   }
    135   else
    136   {
    137     /* DD coefficient*/
    138     for (i = 0; i <= mel_dim; i++)
    139     {
    140       cpt = cp_buf + i;
    141       val = (cepdata) 0.;
    142       for (j = 0; j < Q2; j++, cpt += (mel_dim + 1))
    143         val += deldel[j] * SHIFT_DOWN((*cpt), 4);    /* Q2 frames forward, not around...? */
    144       /* Watch out for overflows here */
    145       dd[i] = (cepdata) SHIFT_DOWN((bigdata)(val), COSINE_TABLE_SHIFT - 4);
    146     }
    147   }
    148   return;
    149 }
    150 
    151 
    152 static void scale_data(const front_cep *cepobj, const featdata *rpram,  featdata *pram1,
    153                        featdata *pram2, featdata *ddpram, const cepdata *rast,
    154                        const cepdata *cep, const cepdata *rcep, const cepdata *ddcep)
    155 {
    156   size_t   i;
    157   bigdata a;
    158 
    159   if (pram1)
    160     for (i = 0; i <= cepobj->mel_dim; i++)
    161     {
    162       /* Now take the costable scaling off the ceps. */
    163       ASSERT((cepobj->melA_scale[i] *(float)SHIFT_DOWN(cep[i], COSINE_TABLE_SHIFT))
    164              < LONG_MAX);
    165       ASSERT((cepobj->melA_scale[i] *(float)SHIFT_DOWN(cep[i], COSINE_TABLE_SHIFT))
    166              > -LONG_MAX);
    167       a = (bigdata)(SHIFT_DOWN((bigdata)cepobj->melA_scale[i]
    168                                * (bigdata) SHIFT_DOWN(cep[i], COSINE_TABLE_SHIFT)
    169                                + (bigdata)cepobj->melB_scale[i], BYTERANGE_SHIFT + LOG_SCALE_SHIFT));
    170       pram1[i] = (featdata) MAKEBYTE(a);
    171     }
    172   if (pram2)
    173     for (i = 0; i <= cepobj->mel_dim; i++)
    174     {
    175       ASSERT((cepobj->dmelA_scale[i] *(float)rcep[i]) < LONG_MAX);
    176       ASSERT((cepobj->dmelA_scale[i] *(float)rcep[i]) > -LONG_MAX);
    177       a = (bigdata) SHIFT_DOWN((bigdata)cepobj->dmelA_scale[i] * (bigdata)rcep[i] +
    178                                (bigdata)cepobj->dmelB_scale[i], BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
    179       pram2[i] = (featdata) MAKEBYTE(a);
    180     }
    181 
    182   /* Double-deltas parameter scaling */
    183   if (cepobj->do_dd_mel && ddpram)
    184     for (i = 0; i <= cepobj->mel_dim; i++)
    185     {
    186       ASSERT((cepobj->ddmelA_scale[i] *(float)ddcep[i]) < LONG_MAX);
    187       ASSERT((cepobj->ddmelA_scale[i] *(float)ddcep[i]) > -LONG_MAX);
    188       a = (bigdata) SHIFT_DOWN((bigdata)cepobj->ddmelA_scale[i] * (bigdata)ddcep[i] +
    189                                (bigdata)cepobj->ddmelB_scale[i], BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
    190       ddpram[i] = (featdata) MAKEBYTE(a); /* sort out scaling of deldel? */
    191     }
    192   return;
    193 }
    194 
    195 static void pack_frame(const front_cep *cepobj, featdata *dest_frame,
    196                        const featdata *rasta_data, const featdata *mel_data,
    197                        const featdata *del_data, const featdata *deldel_data)
    198 {
    199   size_t ii, cnt;
    200 
    201   cnt = 0;
    202   for (ii = 0; ii < cepobj->mel_dim; ii++, cnt++)
    203     dest_frame[cnt] = (featdata) mel_data[ii];
    204   for (ii = 0; ii < cepobj->mel_dim; ii++, cnt++)
    205     dest_frame[cnt] = (featdata) del_data[ii];
    206   if (cepobj->do_dd_mel)
    207     for (ii = 0; ii < cepobj->mel_dim; ii++, cnt++)
    208       dest_frame[cnt] = (featdata) deldel_data[ii];
    209 
    210 #if DEBUG
    211   log_report("Frame: ");
    212   for (ii = 0; ii < 24; ii++)
    213     log_report("%d ", dest_frame[ii]);
    214   if (cepobj->do_dd_mel)
    215     for (ii = 0; ii < cepobj->mel_dim; ii++)
    216       log_report("%d ", dest_frame[2*cepobj->mel_dim+ii]);
    217   log_report("\n");
    218 #endif
    219   return;
    220 }
    221 
    222 int make_std_frame(front_channel *channel, front_cep *cepobj, featdata *hFrame)
    223 {
    224   featdata rpram[MAX_CEP_DIM+1], spram1[MAX_CEP_DIM+1], spram2[MAX_CEP_DIM+1], ddpram[MAX_CEP_DIM+1];
    225   cepdata  rgmcep[MAX_CEP_DIM+1];     /*regression MCEP coef. */
    226   cepdata  ddmcep[MAX_CEP_DIM+1];     /*del-del-MCEP coef. */
    227   cepdata  rastapar[MAX_CEP_DIM+1];     /*del-del-MCEP coef. */
    228 
    229   channel->frame_valid = False;
    230   if (channel->frame_count >= channel->frame_delay)
    231   {
    232     /*  Part III.   Delta Cepstrum calculations
    233     */
    234     regress(rgmcep, channel->cep, (unsigned short) channel->frame_count, channel->mel_dim);
    235     if (cepobj->do_dd_mel)
    236       dd_regress(ddmcep, channel->cep, (unsigned short) channel->frame_count, channel->mel_dim);
    237 #if DEBUG
    238     log_report("Cep before scaling: ");
    239     write_scaled_frames(channel->mel_dim + 1, 1,
    240                         channel->cep  + (DELTA) *(channel->mel_dim + 1),
    241                         D_FIXED, (float)1 / (0x01 << (LOG_SCALE_SHIFT + COSINE_TABLE_SHIFT)));
    242     log_report("Delta Cep before scaling: ");
    243     write_scaled_frames(channel->mel_dim + 1, 1, rgmcep, D_FIXED, (float)1 / (0x01 << LOG_SCALE_SHIFT));
    244     log_report("DeltaDelta Cep before scaling: ");
    245     write_scaled_frames(channel->mel_dim + 1, 1, ddmcep, D_FIXED, (float)1 / (0x01 << LOG_SCALE_SHIFT));
    246 #endif
    247     scale_data(cepobj, rpram, spram1, spram2, ddpram, rastapar,
    248                channel->cep  + (DELTA) *(channel->mel_dim + 1),  rgmcep, ddmcep);
    249 #if DEBUG
    250     log_report("Cep after scaling: ");
    251     write_frames(channel->mel_dim + 1, 1, spram1, D_CHAR);
    252     log_report("Delta Cep after scaling: ");
    253     write_frames(channel->mel_dim + 1, 1, spram2, D_CHAR);
    254     log_report("DeltaDelta Cep after scaling: ");
    255     write_frames(channel->mel_dim + 1, 1, ddpram, D_CHAR);
    256 #endif
    257     channel->frame_valid = True;     /* True even if do_skip_even_frames, */
    258     pack_frame(cepobj, hFrame, rpram, spram1, spram2, ddpram);
    259   } /* >=DELTA */
    260 
    261   channel->frame_count++;
    262   return (channel->frame_valid);
    263 }
    264