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