Home | History | Annotate | Download | only in cfront
      1 /*---------------------------------------------------------------------------*
      2  *  chelmel4.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 #include <stdlib.h>
     23 #ifndef _RTT
     24 #include <stdio.h>
     25 #endif
     26 #include <string.h>
     27 #include <math.h>
     28 #include <limits.h>
     29 #include <assert.h>
     30 
     31 #include "hmm_desc.h"
     32 #include "front.h"
     33 #include "portable.h"
     34 
     35 #define DEBUG           0
     36 #define LOG_AS_PRINT 0
     37 
     38 #define LPCMAX 100
     39 
     40 
     41 #if LOG_AS_PRINT /* BP temp hack */
     42 #define log_report printf
     43 #endif
     44 
     45 #include "sh_down.h"
     46 
     47 
     48 /* cepstrum_params has been broken into three functions:
     49  filterbank_emulation    - does preemp, window, fft and filtbank
     50  gain_adjustment                 - estimates gain
     51  cepstrum_params                 - does gain adj.(if on), spec corr and cos transform
     52    This enables us to bypass gain adjustment.
     53 */
     54 
     55 //static void mel_cuberoot_offset(cepdata *fbo, cepdata *ch_off, int nf);
     56 #if SPEC_CORRECT
     57 static void mel_spectrum_correction(cepdata *fbo, cepdata *ch_gain, int nf);
     58 #endif
     59 static void mel_loglookup_with_offset(front_cep *cepobj,
     60                                       front_channel *channel);
     61 //static void mel_exp(cepdata *fbo, int nf);
     62 //static void durbin(cepdata *a, cepdata *r, int n);
     63 //static void lpc_to_cepstral_recursion(cepdata *c, cepdata *a, int nc, int n);
     64 static void icostrans(cepdata *cs, cepdata fb[], cepdata cep[], int nf, int nc);
     65 
     66 
     67 void cepstrum_params(front_channel *channel, front_wave *waveobj,
     68                      front_freq *freqobj, front_cep *cepobj)
     69 {
     70 #if SPEC_CORRECT
     71   /*  2.30 Apply a spectrum correction */
     72   if (cepobj->mel_loop)
     73     mel_spectrum_correction(freqobj->filterbank, cepobj->mel_loop, channel->num_freq);
     74 #endif
     75   /*  2.33 Calculate log dB energy values */
     76     mel_loglookup_with_offset(cepobj, channel);
     77 #if DEBUG
     78   log_report("Filterbank output: ");
     79   write_scaled_frames(freqobj->nf, 1, channel->filterbank, D_FIXED, 1 / (float)LOG_SCALE);
     80 #endif
     81 
     82   /*  2.34 Cosine transformation */
     83   icostrans(cepobj->cs, channel->filterbank, channel->cep,
     84             channel->num_freq, cepobj->mel_dim);
     85 
     86 #if DEBUG
     87   log_report("Cepstrum coefficients: ");
     88   write_scaled_frames((cepobj->mel_dim + 1), 1, channel->cep, D_FIXED, (float)1 / (0x01 << (LOG_SCALE_SHIFT + COSINE_TABLE_SHIFT)));
     89 #endif
     90   return;
     91 }
     92 
     93 static void icostrans(cepdata *cs, cepdata fb[], cepdata cep[], int nf, int nc)
     94 /*
     95 **  inv rotated-cosine transform
     96 **  ref Davis and Mermelstein, ASSP 1980 */
     97 {
     98   int   i, j;
     99   cepdata *cp;
    100   cepdata temp;
    101 
    102   for (i = 0; i <= nc; i++)
    103   {
    104     cp = &cs[i*nf];
    105     for (j = 0, temp = 0; j < nf; j++)
    106       temp += fb[j] * cp[j];
    107     cep[i] = temp;
    108   }
    109   return;
    110 }
    111 
    112 #if SPEC_CORRECT
    113 static void mel_spectrum_correction(cepdata *fbo, cepdata *ch_gain, int nf)
    114 /*
    115 **  pwr spect -> filter bank output */
    116 {
    117   int i;
    118 
    119   for (i = 0;i < nf; i++)
    120     fbo[i] = fbo[i] * ch_gain[i]; /* TODO: Fixedpt scale up and down */
    121   return;
    122 }
    123 #endif
    124 
    125 static void mel_loglookup_with_offset(front_cep *cepobj,
    126                                       front_channel *channel)
    127 /*
    128 **  pwr spect -> filter bank output */
    129 {
    130   int ii;
    131 
    132   if (channel->shift > 0)
    133     for (ii = 0; ii < channel->num_freq; ii++)
    134     {
    135       channel->filterbank[ii] = (cepdata) log_lookup(&cepobj->logtab,
    136                                 (int)(channel->filterbank[ii] +
    137                                       SHIFT_DOWN(cepobj->mel_offset[ii], channel->shift)),
    138                                 channel->shift);
    139     }
    140   else
    141     for (ii = 0; ii < channel->num_freq; ii++)
    142     {
    143       channel->filterbank[ii] = (cepdata) log_lookup(&cepobj->logtab,
    144                                 (int)(channel->filterbank[ii] +
    145                                       SHIFT_UP(cepobj->mel_offset[ii], -channel->shift)),
    146                                 channel->shift);
    147     }
    148 
    149   return;
    150 }
    151 
    152 //static void mel_exp(cepdata *fbo, int nf)
    153 ///*
    154 //**  pwr spect -> filter bank output */
    155 //{
    156 //  int i;
    157 //  for (i = 0; i < nf; i++)
    158 //  {
    159 //    fbo[i] = (cepdata) exp((double) fbo[i]);
    160 //  }
    161 //  return;
    162 //}
    163 //
    164 //static void durbin(
    165 //  cepdata *a,   /* lpc coefficients           */
    166 //  cepdata *r,   /* autocorrelation coefficients       */
    167 //  int n)     /* order of lpc analysis        */
    168 //{
    169 //  int i, j;
    170 //  cepdata A[LPCMAX+1][LPCMAX+1], sum;
    171 //  cepdata k[LPCMAX+1];
    172 //  cepdata e[LPCMAX+1];
    173 //
    174 //  e[0] = r[0];
    175 //  for (i = 1; i <= n; i++)
    176 //  {
    177 //    sum = 0;
    178 //    for (j = 1; j <= (i - 1); j++)
    179 //    {
    180 //      sum += A[j][i-1] * r[i-j];
    181 //    }
    182 //    k[i] = -(r[i] + sum) / e[i-1];
    183 //    A[i][i] = k[i] ;
    184 //    for (j = 1; j <= (i - 1); j++)
    185 //    {
    186 //      A[j][i] = A[j][i-1] + k[i] * A[i-j][i-1];
    187 //    }
    188 //    e[i] = (1 - k[i] * k[i]) * e[i-1];
    189 //  }
    190 //  for (j = 1 ; j <= n; j++)
    191 //  {
    192 //    a[j] = A[j][n];
    193 //  }
    194 //
    195 //  a[0] = (cepdata) 1.0 ;
    196 //  return;
    197 //}
    198 //
    199 //static void lpc_to_cepstral_recursion(
    200 //  cepdata *c,     /* cepstral coefficients        */
    201 //  cepdata *a,     /* lpc coeffiecients            */
    202 //  int nc,         /* order of cepstra             */
    203 //  int n)          /* order of lpc                 */
    204 //{
    205 //  int k, i;
    206 //  cepdata sum;
    207 //
    208 //  ASSERT(nc < LPCMAX);
    209 //
    210 //  for (i = n + 1; i <= nc; i++)
    211 //  {
    212 //    a[i] = (cepdata) 0.0;
    213 //  }
    214 //  /* if lpc order less    */
    215 //  /* than cepstral order  */
    216 //  /* define higher lpccos */
    217 //
    218 //  for (i = 1; i <= nc; i++)
    219 //  {
    220 //    sum = (cepdata) 0.0;
    221 //    for (k = 1; k <= (i - 1); k++)
    222 //    {
    223 //      sum = sum + k * c[k] * a[i-k]; /* TODO: fixedpt range for mult */
    224 //    }
    225 //    c[i] = -a[i] - (sum / i);               /* cepstral calculated  */
    226 //    /* to <=nc in icostrans */
    227 //    /* so I shall do the    */                                                      /* same here            */
    228 //  }
    229 //}
    230 
    231