• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
cepstrum_params(front_channel * channel,front_wave * waveobj,front_freq * freqobj,front_cep * cepobj)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 
icostrans(cepdata * cs,cepdata fb[],cepdata cep[],int nf,int nc)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
mel_spectrum_correction(cepdata * fbo,cepdata * ch_gain,int nf)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 
mel_loglookup_with_offset(front_cep * cepobj,front_channel * channel)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