• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
regress(cepdata * rg,const cepdata * cp_buf,unsigned short frmind,int mel_dim)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 
dd_regress(cepdata * dd,const cepdata * cp_buf,unsigned short frmind,int mel_dim)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 
scale_data(const front_cep * cepobj,const featdata * rpram,featdata * pram1,featdata * pram2,featdata * ddpram,const cepdata * rast,const cepdata * cep,const cepdata * rcep,const cepdata * ddcep)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 
pack_frame(const front_cep * cepobj,featdata * dest_frame,const featdata * rasta_data,const featdata * mel_data,const featdata * del_data,const featdata * deldel_data)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 
make_std_frame(front_channel * channel,front_cep * cepobj,featdata * hFrame)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