| File: | modules/clustergen/me_mlsa.cc |
| Location: | line 568, column 15 |
| Description: | Array access (from variable 'mc') results in a null pointer dereference |
| 1 | /** | |||
| 2 | * The HMM-Based Speech Synthesis System (HTS) | |||
| 3 | * HTS Working Group | |||
| 4 | * | |||
| 5 | * Department of Computer Science | |||
| 6 | * Nagoya Institute of Technology | |||
| 7 | * and | |||
| 8 | * Interdisciplinary Graduate School of Science and Engineering | |||
| 9 | * Tokyo Institute of Technology | |||
| 10 | * | |||
| 11 | * Portions Copyright (c) 2001-2006 | |||
| 12 | * All Rights Reserved. | |||
| 13 | * | |||
| 14 | * Portions Copyright 2000-2007 DFKI GmbH. | |||
| 15 | * All Rights Reserved. | |||
| 16 | * | |||
| 17 | * Permission is hereby granted, free of charge, to use and | |||
| 18 | * distribute this software and its documentation without | |||
| 19 | * restriction, including without limitation the rights to use, | |||
| 20 | * copy, modify, merge, publish, distribute, sublicense, and/or | |||
| 21 | * sell copies of this work, and to permit persons to whom this | |||
| 22 | * work is furnished to do so, subject to the following conditions: | |||
| 23 | * | |||
| 24 | * 1. The source code must retain the above copyright notice, | |||
| 25 | * this list of conditions and the following disclaimer. | |||
| 26 | * | |||
| 27 | * 2. Any modifications to the source code must be clearly | |||
| 28 | * marked as such. | |||
| 29 | * | |||
| 30 | * 3. Redistributions in binary form must reproduce the above | |||
| 31 | * copyright notice, this list of conditions and the | |||
| 32 | * following disclaimer in the documentation and/or other | |||
| 33 | * materials provided with the distribution. Otherwise, one | |||
| 34 | * must contact the HTS working group. | |||
| 35 | * | |||
| 36 | * NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSTITUTE OF TECHNOLOGY, | |||
| 37 | * HTS WORKING GROUP, AND THE CONTRIBUTORS TO THIS WORK DISCLAIM | |||
| 38 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL | |||
| 39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT | |||
| 40 | * SHALL NAGOYA INSTITUTE OF TECHNOLOGY, TOKYO INSTITUTE OF | |||
| 41 | * TECHNOLOGY, HTS WORKING GROUP, NOR THE CONTRIBUTORS BE LIABLE | |||
| 42 | * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY | |||
| 43 | * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||
| 44 | * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS | |||
| 45 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |||
| 46 | * PERFORMANCE OF THIS SOFTWARE. | |||
| 47 | * | |||
| 48 | * | |||
| 49 | * This software was translated to C for use within Festival to offer | |||
| 50 | * multi-excitation MLSA | |||
| 51 | * Alan W Black (awb@cs.cmu.edu) 3rd April 2009 | |||
| 52 | * | |||
| 53 | */ | |||
| 54 | ||||
| 55 | #include <stdio.h> | |||
| 56 | #include <stdlib.h> | |||
| 57 | #include <string.h> | |||
| 58 | #include <math.h> | |||
| 59 | #include <EST_walloc.h> | |||
| 60 | #include "festival.h" | |||
| 61 | ||||
| 62 | #include "mlsa_resynthesis.h" | |||
| 63 | ||||
| 64 | /** | |||
| 65 | * Synthesis of speech out of speech parameters. | |||
| 66 | * Mixed excitation MLSA vocoder. | |||
| 67 | * | |||
| 68 | * Java port and extension of HTS engine version 2.0 | |||
| 69 | * Extension: mixed excitation | |||
| 70 | * @author Marcela Charfuelan | |||
| 71 | * And ported to C by Alan W Black (awb@cs.cmu.edu) | |||
| 72 | */ | |||
| 73 | ||||
| 74 | #define booleanint int | |||
| 75 | #define true1 1 | |||
| 76 | #define false0 0 | |||
| 77 | ||||
| 78 | typedef struct HTSData_struct { | |||
| 79 | ||||
| 80 | int rate; | |||
| 81 | int fperiod; | |||
| 82 | double rhos; | |||
| 83 | ||||
| 84 | int stage; | |||
| 85 | double alpha; | |||
| 86 | double beta; | |||
| 87 | booleanint useLogGain; | |||
| 88 | double uf; | |||
| 89 | booleanint algnst; /* use state level alignment for duration */ | |||
| 90 | booleanint algnph; /* use phoneme level alignment for duration */ | |||
| 91 | booleanint useMixExc; /* use Mixed Excitation */ | |||
| 92 | booleanint useFourierMag; /* use Fourier magnitudes for pulse generation */ | |||
| 93 | booleanint useGV; /* use global variance in parameter generation */ | |||
| 94 | booleanint useGmmGV; /* use global variance as a Gaussian Mixture Model */ | |||
| 95 | booleanint useUnitDurationContinuousFeature; /* for using external duration, so it will not be generated from HMMs*/ | |||
| 96 | booleanint useUnitLogF0ContinuousFeature; /* for using external f0, so it will not be generated from HMMs*/ | |||
| 97 | ||||
| 98 | /** variables for controling generation of speech in the vocoder | |||
| 99 | * these variables have default values but can be fixed and read from the | |||
| 100 | * audio effects component. [Default][min--max] */ | |||
| 101 | double length; /* total number of frame for generated speech */ | |||
| 102 | /* length of generated speech (in seconds) [N/A][0.0--30.0] */ | |||
| 103 | double durationScale; /* less than 1.0 is faster and more than 1.0 is slower, min=0.1 max=3.0 */ | |||
| 104 | ||||
| 105 | booleanint LogGain; | |||
| 106 | char *PdfStrFile, *PdfMagFile; | |||
| 107 | ||||
| 108 | int NumFilters, OrderFilters; | |||
| 109 | double **MixFilters; | |||
| 110 | double F0Std; | |||
| 111 | double F0Mean; | |||
| 112 | ||||
| 113 | } HTSData; | |||
| 114 | ||||
| 115 | #if 0 | |||
| 116 | typedef struct HTSData_struct { | |||
| 117 | ||||
| 118 | int rate = 16000; | |||
| 119 | int fperiod = 80; | |||
| 120 | double rhos = 0.0; | |||
| 121 | ||||
| 122 | int stage = 0; | |||
| 123 | double alpha = 0.42; | |||
| 124 | booleanint useLogGain = false0; | |||
| 125 | double uf = 0.5; | |||
| 126 | booleanint algnst = false0; /* use state level alignment for duration */ | |||
| 127 | booleanint algnph = false0; /* use phoneme level alignment for duration */ | |||
| 128 | booleanint useMixExc = true1; /* use Mixed Excitation */ | |||
| 129 | booleanint useFourierMag = false0; /* use Fourier magnitudes for pulse generation */ | |||
| 130 | booleanint useGV = false0; /* use global variance in parameter generation */ | |||
| 131 | booleanint useGmmGV = false0; /* use global variance as a Gaussian Mixture Model */ | |||
| 132 | booleanint useUnitDurationContinuousFeature = false0; /* for using external duration, so it will not be generated from HMMs*/ | |||
| 133 | booleanint useUnitLogF0ContinuousFeature = false0; /* for using external f0, so it will not be generated from HMMs*/ | |||
| 134 | ||||
| 135 | /** variables for controling generation of speech in the vocoder | |||
| 136 | * these variables have default values but can be fixed and read from the | |||
| 137 | * audio effects component. [Default][min--max] */ | |||
| 138 | double f0Std = 1.0; /* variable for f0 control, multiply f0 [1.0][0.0--5.0] */ | |||
| 139 | double f0Mean = 0.0; /* variable for f0 control, add f0 [0.0][0.0--100.0] */ | |||
| 140 | double length = 0.0; /* total number of frame for generated speech */ | |||
| 141 | /* length of generated speech (in seconds) [N/A][0.0--30.0] */ | |||
| 142 | double durationScale = 1.0; /* less than 1.0 is faster and more than 1.0 is slower, min=0.1 max=3.0 */ | |||
| 143 | ||||
| 144 | } HTSData; | |||
| 145 | #endif | |||
| 146 | ||||
| 147 | static int IPERIOD = 1; | |||
| 148 | static booleanint GAUSS = true1; | |||
| 149 | static int PADEORDER = 5; /* pade order for MLSA filter */ | |||
| 150 | static int IRLENG = 96; /* length of impulse response */ | |||
| 151 | ||||
| 152 | /* for MGLSA filter (mel-generalised log spectrum approximation filter) */ | |||
| 153 | static booleanint NORMFLG1 = true1; | |||
| 154 | static booleanint NORMFLG2 = false0; | |||
| 155 | static booleanint MULGFLG1 = true1; | |||
| 156 | static booleanint MULGFLG2 = false0; | |||
| 157 | static booleanint NGAIN = false0; | |||
| 158 | ||||
| 159 | static double ZERO = 1.0e-10; /* ~(0) */ | |||
| 160 | static double LZERO = (-1.0e+10); /* ~log(0) */ | |||
| 161 | ||||
| 162 | static int stage; /* Gamma=-1/stage : if stage=0 then Gamma=0 */ | |||
| 163 | static double xgamma; /* Gamma */ | |||
| 164 | static booleanint use_log_gain; /* log gain flag (for LSP) */ | |||
| 165 | static int fprd; /* frame shift */ | |||
| 166 | static int iprd; /* interpolation period */ | |||
| 167 | static booleanint gauss; /* flag to use Gaussian noise */ | |||
| 168 | static double p1; /* used in excitation generation */ | |||
| 169 | static double pc; /* used in excitation generation */ | |||
| 170 | static double *pade; /* used in mlsadf */ | |||
| 171 | static int ppade; /* offset for vector ppade */ | |||
| 172 | ||||
| 173 | static double *C; /* used in the MLSA/MGLSA filter */ | |||
| 174 | static double *CC; /* used in the MLSA/MGLSA filter */ | |||
| 175 | static double *CINC; /* used in the MLSA/MGLSA filter */ | |||
| 176 | static double *D1; /* used in the MLSA/MGLSA filter */ | |||
| 177 | static int CINC_length, CC_length, C_length, D1_length; | |||
| 178 | ||||
| 179 | static double rate; | |||
| 180 | static int pt1; /* used in mlsadf1 */ | |||
| 181 | static int pt2; /* used in mlsadf2 */ | |||
| 182 | static int *pt3; /* used in mlsadf2 */ | |||
| 183 | ||||
| 184 | /* mixed excitation variables */ | |||
| 185 | static int numM; /* Number of bandpass filters for mixed excitation */ | |||
| 186 | static int orderM; /* Order of filters for mixed excitation */ | |||
| 187 | static double **h; /* filters for mixed excitation */ | |||
| 188 | static double *xpulseSignal; /* the size of this should be orderM */ | |||
| 189 | static double *xnoiseSignal; /* the size of this should be orderM */ | |||
| 190 | static booleanint mixedExcitation = false0; | |||
| 191 | static booleanint fourierMagnitudes = false0; | |||
| 192 | ||||
| 193 | static booleanint lpcVocoder = false0; /* true if lpc vocoder is used, then the input should be lsp parameters */ | |||
| 194 | ||||
| 195 | void initVocoder(int mcep_order, int mcep_vsize, HTSData *htsData); | |||
| 196 | int htsMLSAVocoder(EST_Track *lf0Pst, | |||
| 197 | EST_Track *mcepPst, | |||
| 198 | EST_Track *strPst, | |||
| 199 | EST_Track *magPst, | |||
| 200 | int *voiced, | |||
| 201 | HTSData *htsData, | |||
| 202 | EST_Wave *wave); | |||
| 203 | ||||
| 204 | ||||
| 205 | LISP me_mlsa_resynthesis(LISP ltrack, LISP strack) | |||
| 206 | { | |||
| 207 | /* Resynthesizes a wave from given track with mixed excitation*/ | |||
| 208 | EST_Track *t; | |||
| 209 | EST_Track *str_track; | |||
| 210 | EST_Wave *wave = 0; | |||
| 211 | EST_Track *mcep; | |||
| 212 | EST_Track *f0v; | |||
| 213 | EST_Track *str; | |||
| 214 | EST_Track *mag; | |||
| 215 | int *voiced; | |||
| 216 | int sr = 16000; | |||
| 217 | int i,j; | |||
| 218 | double shift; | |||
| 219 | HTSData htsData; | |||
| 220 | ||||
| 221 | htsData.alpha = 0.42; | |||
| 222 | htsData.beta = 0.0; | |||
| 223 | ||||
| 224 | if ((ltrack == NULL__null) || | |||
| 225 | (TYPEP(ltrack,tc_string)( (ltrack != __null) && ((((ltrack) == ((struct obj * ) 0)) ? 0 : ((*(ltrack)).type)) == (13)) ) && | |||
| 226 | (streq(get_c_string(ltrack),"nil")(strcmp(get_c_string(ltrack),"nil")==0)))) | |||
| 227 | return siod(new EST_Wave(0,1,sr)); | |||
| 228 | ||||
| 229 | t = track(ltrack); | |||
| 230 | str_track = track(strack); | |||
| 231 | ||||
| 232 | f0v = new EST_Track(t->num_frames(),1); | |||
| 233 | mcep = new EST_Track(t->num_frames(),25); | |||
| 234 | str = new EST_Track(t->num_frames(),5); | |||
| 235 | mag = new EST_Track(t->num_frames(),10); | |||
| 236 | voiced = walloc(int,t->num_frames())((int *)safe_walloc(sizeof(int)*(t->num_frames()))); | |||
| 237 | ||||
| 238 | for (i=0; i<t->num_frames(); i++) | |||
| 239 | { | |||
| 240 | f0v->a(i) = t->a(i,0); | |||
| 241 | if (f0v->a(i) > 0) | |||
| 242 | voiced[i] = 1; | |||
| 243 | else | |||
| 244 | voiced[i] = 0; | |||
| 245 | for (j=1; j<26; j++) | |||
| 246 | mcep->a(i,j-1) = t->a(i,j); | |||
| 247 | ||||
| 248 | for (j=0; j<5; j++) | |||
| 249 | { | |||
| 250 | str->a(i,j) = str_track->a(i,j); | |||
| 251 | } | |||
| 252 | /* printf("awb_debug str %d 0 %f 1 %f 2 %f 3 %f 4 %f\n", | |||
| 253 | i,str->a(i,0),str->a(i,1),str->a(i,2),str->a(i,3),str->a(i,4));*/ | |||
| 254 | #if 0 | |||
| 255 | for (j=57; j<66; j++) | |||
| 256 | mag->a(i,j-57) = t->a(i,j); | |||
| 257 | #endif | |||
| 258 | } | |||
| 259 | ||||
| 260 | if (t->num_frames() > 1) | |||
| 261 | shift = 1000.0*(t->t(1)-t->t(0)); | |||
| 262 | else | |||
| 263 | shift = 5.0; | |||
| 264 | ||||
| 265 | htsData.alpha = FLONM(siod_get_lval("mlsa_alpha_param",((*siod_get_lval("mlsa_alpha_param", "mlsa: mlsa_alpha_param not set" )).storage_as.flonum.data) | |||
| 266 | "mlsa: mlsa_alpha_param not set"))((*siod_get_lval("mlsa_alpha_param", "mlsa: mlsa_alpha_param not set" )).storage_as.flonum.data); | |||
| 267 | htsData.beta = FLONM(siod_get_lval("mlsa_beta_param",((*siod_get_lval("mlsa_beta_param", "mlsa: mlsa_beta_param not set" )).storage_as.flonum.data) | |||
| 268 | "mlsa: mlsa_beta_param not set"))((*siod_get_lval("mlsa_beta_param", "mlsa: mlsa_beta_param not set" )).storage_as.flonum.data); | |||
| 269 | htsData.stage = 0; | |||
| 270 | htsData.LogGain = false0; | |||
| 271 | htsData.fperiod = 80; | |||
| 272 | htsData.rate = 16000; | |||
| 273 | htsData.rhos = 0.0; | |||
| 274 | ||||
| 275 | htsData.uf = 0.5; | |||
| 276 | htsData.algnst = false0; /* use state level alignment for duration */ | |||
| 277 | htsData.algnph = false0; /* use phoneme level alignment for duration */ | |||
| 278 | htsData.useMixExc = true1; /* use Mixed Excitation */ | |||
| 279 | htsData.useFourierMag = false0; /* use Fourier magnitudes for pulse generation */ | |||
| 280 | htsData.useGV = false0; /* use global variance in parameter generation */ | |||
| 281 | htsData.useGmmGV = false0; /* use global variance as a Gaussian Mixture Model */ | |||
| 282 | htsData.useUnitDurationContinuousFeature = false0; /* for using external duration, so it will not be generated from HMMs*/ | |||
| 283 | htsData.useUnitLogF0ContinuousFeature = false0; /* for using external f0, so it will not be generated from HMMs*/ | |||
| 284 | ||||
| 285 | /** variables for controling generation of speech in the vocoder | |||
| 286 | * these variables have default values but can be fixed and read from the | |||
| 287 | * audio effects component. [Default][min--max] */ | |||
| 288 | htsData.F0Std = 1.0; /* variable for f0 control, multiply f0 [1.0][0.0--5.0] */ | |||
| 289 | htsData.F0Mean = 0.0; /* variable for f0 control, add f0 [0.0][0.0--100.0] */ | |||
| 290 | htsData.length = 0.0; /* total number of frame for generated speech */ | |||
| 291 | /* length of generated speech (in seconds) [N/A][0.0--30.0] */ | |||
| 292 | htsData.durationScale = 1.0; /* less than 1.0 is faster and more than 1.0 is slower, min=0.1 max=3.0 */ | |||
| 293 | ||||
| 294 | LISP filters = siod_get_lval("me_mix_filters", | |||
| 295 | "mlsa: me_mix_filters not set"); | |||
| 296 | LISP f; | |||
| 297 | int fl; | |||
| 298 | htsData.NumFilters = 5; | |||
| 299 | for (fl=0,f=filters; f; fl++) | |||
| 300 | f=cdr(f); | |||
| 301 | htsData.OrderFilters = fl/htsData.NumFilters; | |||
| 302 | htsData.MixFilters = walloc(double *,htsData.NumFilters)((double * *)safe_walloc(sizeof(double *)*(htsData.NumFilters ))); | |||
| 303 | for (i=0; i < htsData.NumFilters; i++) | |||
| 304 | { | |||
| 305 | htsData.MixFilters[i] = walloc(double,htsData.OrderFilters)((double *)safe_walloc(sizeof(double)*(htsData.OrderFilters)) ); | |||
| 306 | for (j=0; j<htsData.OrderFilters; j++) | |||
| 307 | { | |||
| 308 | htsData.MixFilters[i][j] = FLONM(car(filters))((*car(filters)).storage_as.flonum.data); | |||
| 309 | filters = cdr(filters); | |||
| 310 | } | |||
| 311 | } | |||
| 312 | ||||
| 313 | wave = new EST_Wave(0,1,sr); | |||
| 314 | ||||
| 315 | if (mcep->num_frames() > 0) | |||
| 316 | /* mcep_order and number of deltas */ | |||
| 317 | htsMLSAVocoder(f0v,mcep,str,mag,voiced,&htsData,wave); | |||
| 318 | ||||
| 319 | delete f0v; | |||
| 320 | delete mcep; | |||
| 321 | delete str; | |||
| 322 | delete mag; | |||
| 323 | delete voiced; | |||
| 324 | ||||
| 325 | return siod(wave); | |||
| 326 | } | |||
| 327 | ||||
| 328 | /** The initialisation of VocoderSetup should be done when there is already | |||
| 329 | * information about the number of feature vectors to be processed, | |||
| 330 | * size of the mcep vector file, etc. */ | |||
| 331 | void initVocoder(int mcep_order, int mcep_vsize, HTSData *htsData) | |||
| 332 | { | |||
| 333 | int vector_size; | |||
| 334 | double xrand; | |||
| 335 | ||||
| 336 | stage = htsData->stage; | |||
| 337 | if(stage != 0) | |||
| 338 | xgamma = -1.0 / stage; | |||
| 339 | else | |||
| 340 | xgamma = 0.0; | |||
| 341 | use_log_gain = htsData->LogGain; | |||
| 342 | ||||
| 343 | fprd = htsData->fperiod; | |||
| 344 | rate = htsData->rate; | |||
| 345 | iprd = IPERIOD; | |||
| 346 | gauss = GAUSS; | |||
| 347 | ||||
| 348 | /* XXX */ | |||
| 349 | xrand = rand(); | |||
| 350 | ||||
| 351 | if(stage == 0 ){ /* for MCP */ | |||
| 352 | ||||
| 353 | /* mcep_order=74 and pd=PADEORDER=5 (if no HTS_EMBEDDED is used) */ | |||
| 354 | vector_size = (mcep_vsize * ( 3 + PADEORDER) + 5 * PADEORDER + 6) - (3 * (mcep_order+1)); | |||
| 355 | CINC_length = CC_length = C_length = mcep_order+1; | |||
| 356 | D1_length = vector_size; | |||
| 357 | C = walloc(double,C_length)((double *)safe_walloc(sizeof(double)*(C_length))); | |||
| 358 | CC = walloc(double,CC_length)((double *)safe_walloc(sizeof(double)*(CC_length))); | |||
| 359 | CINC = walloc(double,CINC_length)((double *)safe_walloc(sizeof(double)*(CINC_length))); | |||
| 360 | D1 = walloc(double,D1_length)((double *)safe_walloc(sizeof(double)*(D1_length))); | |||
| 361 | ||||
| 362 | vector_size=21; | |||
| 363 | pade = walloc(double,vector_size)((double *)safe_walloc(sizeof(double)*(vector_size))); | |||
| 364 | /* ppade is a copy of pade in mlsadf() function : ppade = &( pade[pd*(pd+1)/2] ); */ | |||
| 365 | ppade = PADEORDER*(PADEORDER+1)/2; /* offset for vector pade */ | |||
| 366 | pade[0] = 1.0; | |||
| 367 | pade[1] = 1.0; | |||
| 368 | pade[2] = 0.0; | |||
| 369 | pade[3] = 1.0; | |||
| 370 | pade[4] = 0.0; | |||
| 371 | pade[5] = 0.0; | |||
| 372 | pade[6] = 1.0; | |||
| 373 | pade[7] = 0.0; | |||
| 374 | pade[8] = 0.0; | |||
| 375 | pade[9] = 0.0; | |||
| 376 | pade[10] = 1.0; | |||
| 377 | pade[11] = 0.4999273; | |||
| 378 | pade[12] = 0.1067005; | |||
| 379 | pade[13] = 0.01170221; | |||
| 380 | pade[14] = 0.0005656279; | |||
| 381 | pade[15] = 1.0; | |||
| 382 | pade[16] = 0.4999391; | |||
| 383 | pade[17] = 0.1107098; | |||
| 384 | pade[18] = 0.01369984; | |||
| 385 | pade[19] = 0.0009564853; | |||
| 386 | pade[20] = 0.00003041721; | |||
| 387 | ||||
| 388 | pt1 = PADEORDER+1; | |||
| 389 | pt2 = ( 2 * (PADEORDER+1)) + (PADEORDER * (mcep_order+2)); | |||
| 390 | pt3 = new int[PADEORDER+1]; | |||
| 391 | for(int i=PADEORDER; i>=1; i--) | |||
| 392 | pt3[i] = ( 2 * (PADEORDER+1)) + ((i-1)*(mcep_order+2)); | |||
| 393 | ||||
| 394 | } else { /* for LSP */ | |||
| 395 | vector_size = ((mcep_vsize+1) * (stage+3)) - ( 3 * (mcep_order+1)); | |||
| 396 | CINC_length = CC_length = C_length = mcep_order+1; | |||
| 397 | D1_length = vector_size; | |||
| 398 | C = walloc(double,C_length)((double *)safe_walloc(sizeof(double)*(C_length))); | |||
| 399 | CC = walloc(double,CC_length)((double *)safe_walloc(sizeof(double)*(CC_length))); | |||
| 400 | CINC = walloc(double,CINC_length)((double *)safe_walloc(sizeof(double)*(CINC_length))); | |||
| 401 | D1 = walloc(double,D1_length)((double *)safe_walloc(sizeof(double)*(D1_length))); | |||
| 402 | } | |||
| 403 | ||||
| 404 | /* excitation initialisation */ | |||
| 405 | p1 = -1; | |||
| 406 | pc = 0.0; | |||
| 407 | ||||
| 408 | } /* method initVocoder */ | |||
| 409 | ||||
| 410 | ||||
| 411 | ||||
| 412 | /** | |||
| 413 | * HTS_MLSA_Vocoder: Synthesis of speech out of mel-cepstral coefficients. | |||
| 414 | * This procedure uses the parameters generated in pdf2par stored in: | |||
| 415 | * PStream mceppst: Mel-cepstral coefficients | |||
| 416 | * PStream strpst : Filter bank stregths for mixed excitation | |||
| 417 | * PStream magpst : Fourier magnitudes ( OJO!! this is not used yet) | |||
| 418 | * PStream lf0pst : Log F0 | |||
| 419 | */ | |||
| 420 | #if 0 | |||
| 421 | AudioInputStream htsMLSAVocoder(HTSParameterGeneration pdf2par, HMMData htsData) | |||
| 422 | { | |||
| 423 | float sampleRate = 16000.0F; //8000,11025,16000,22050,44100 | |||
| 424 | int sampleSizeInBits = 16; //8,16 | |||
| 425 | int channels = 1; //1,2 | |||
| 426 | booleanint signed = true1; //true,false | |||
| 427 | booleanint bigEndian = false0; //true,false | |||
| 428 | AudioFormat af = new AudioFormat( | |||
| 429 | sampleRate, | |||
| 430 | sampleSizeInBits, | |||
| 431 | channels, | |||
| 432 | signed, | |||
| 433 | bigEndian); | |||
| 434 | double [] audio_double = NULL__null; | |||
| 435 | ||||
| 436 | audio_double = htsMLSAVocoder(pdf2par.getlf0Pst(), pdf2par.getMcepPst(), pdf2par.getStrPst(), pdf2par.getMagPst(), | |||
| 437 | pdf2par.getVoicedArray(), htsData); | |||
| 438 | ||||
| 439 | long lengthInSamples = (audio_double.length * 2 ) / (sampleSizeInBits/8); | |||
| 440 | logger.info("length in samples=" + lengthInSamples ); | |||
| 441 | ||||
| 442 | /* Normalise the signal before return, this will normalise between 1 and -1 */ | |||
| 443 | double MaxSample = MathUtils.getAbsMax(audio_double); | |||
| 444 | for (int i=0; i<audio_double.length; i++) | |||
| 445 | audio_double[i] = 0.3 * ( audio_double[i] / MaxSample ); | |||
| 446 | ||||
| 447 | DDSAudioInputStream oais = new DDSAudioInputStream(new BufferedDoubleDataSource(audio_double), af); | |||
| 448 | return oais; | |||
| 449 | ||||
| 450 | ||||
| 451 | } /* method htsMLSAVocoder() */ | |||
| 452 | #endif | |||
| 453 | ||||
| 454 | static double mlsafir(double x, double *b, int m, double a, double aa, double *d, int _pt3 ) | |||
| 455 | { | |||
| 456 | double y = 0.0; | |||
| 457 | int i; | |||
| 458 | ||||
| 459 | d[_pt3+0] = x; | |||
| 460 | d[_pt3+1] = aa * d[_pt3+0] + ( a * d[_pt3+1] ); | |||
| 461 | ||||
| 462 | for(i=2; i<=m; i++){ | |||
| 463 | d[_pt3+i] += a * ( d[_pt3+i+1] - d[_pt3+i-1]); | |||
| 464 | } | |||
| 465 | ||||
| 466 | for(i=2; i<=m; i++){ | |||
| 467 | y += d[_pt3+i] * b[i]; | |||
| 468 | } | |||
| 469 | ||||
| 470 | for(i=m+1; i>1; i--){ | |||
| 471 | d[_pt3+i] = d[_pt3+i-1]; | |||
| 472 | } | |||
| 473 | ||||
| 474 | return(y); | |||
| 475 | } | |||
| 476 | ||||
| 477 | /** mlsdaf1: sub functions for MLSA filter */ | |||
| 478 | static double mlsadf1(double x, double *b, int m, double a, double aa, double *d) | |||
| 479 | { | |||
| 480 | double v; | |||
| 481 | double out = 0.0; | |||
| 482 | int i; | |||
| 483 | //pt1 --> pt = &d1[pd+1] | |||
| 484 | ||||
| 485 | for(i=PADEORDER; i>=1; i--) { | |||
| 486 | d[i] = aa * d[pt1+i-1] + a * d[i]; | |||
| 487 | d[pt1+i] = d[i] * b[1]; | |||
| 488 | v = d[pt1+i] * pade[ppade+i]; | |||
| 489 | ||||
| 490 | //x += (1 & i) ? v : -v; | |||
| 491 | if(i == 1 || i == 3 || i == 5) | |||
| 492 | x += v; | |||
| 493 | else | |||
| 494 | x += -v; | |||
| 495 | out += v; | |||
| 496 | } | |||
| 497 | d[pt1+0] = x; | |||
| 498 | out += x; | |||
| 499 | ||||
| 500 | return(out); | |||
| 501 | ||||
| 502 | } | |||
| 503 | ||||
| 504 | /** mlsdaf2: sub functions for MLSA filter */ | |||
| 505 | static double mlsadf2(double x, double *b, int m, double a, double aa, double *d) | |||
| 506 | { | |||
| 507 | double v; | |||
| 508 | double out = 0.0; | |||
| 509 | int i; | |||
| 510 | // pt2 --> pt = &d1[pd * (m+2)] | |||
| 511 | // pt3 --> pt = &d1[ 2*(pd+1) ] | |||
| 512 | ||||
| 513 | for(i=PADEORDER; i>=1; i--) { | |||
| 514 | d[pt2+i] = mlsafir(d[(pt2+i)-1], b, m, a, aa, d, pt3[i]); | |||
| 515 | v = d[pt2+i] * pade[ppade+i]; | |||
| 516 | ||||
| 517 | if(i == 1 || i == 3 || i == 5) | |||
| 518 | x += v; | |||
| 519 | else | |||
| 520 | x += -v; | |||
| 521 | out += v; | |||
| 522 | ||||
| 523 | } | |||
| 524 | d[pt2+0] = x; | |||
| 525 | out += x; | |||
| 526 | ||||
| 527 | return out; | |||
| 528 | } | |||
| 529 | ||||
| 530 | /** mlsadf: HTS Mel Log Spectrum Approximation filter */ | |||
| 531 | static double mlsadf(double x, double *b, int m, double a, double aa, double *d) | |||
| 532 | { | |||
| 533 | ||||
| 534 | x = mlsadf1(x, b, m, a, aa, d); | |||
| 535 | x = mlsadf2(x, b, m-1, a, aa, d); | |||
| 536 | ||||
| 537 | return x; | |||
| 538 | } | |||
| 539 | ||||
| 540 | ||||
| 541 | /** uniform_rand: generate uniformly distributed random numbers 1 or -1 */ | |||
| 542 | static double uniformRand() | |||
| 543 | { | |||
| 544 | double x; | |||
| 545 | ||||
| 546 | x = rand(); /* double uniformly distributed between 0.0 <= Math.random() < 1.0.*/ | |||
| 547 | if(x >= RAND_MAX2147483647/2.0) | |||
| 548 | return 1.0; | |||
| 549 | else | |||
| 550 | return -1.0; | |||
| 551 | } | |||
| 552 | ||||
| 553 | /** mc2b: transform mel-cepstrum to MLSA digital filter coefficients */ | |||
| 554 | static void mc2b(double *mc, double *b, int m, double a ) | |||
| 555 | { | |||
| 556 | ||||
| 557 | b[m] = mc[m]; | |||
| 558 | for(m--; m>=0; m--) { | |||
| 559 | b[m] = mc[m] - a * b[m+1]; | |||
| 560 | } | |||
| 561 | } | |||
| 562 | ||||
| 563 | /** b2mc: transform MLSA digital filter coefficients to mel-cepstrum */ | |||
| 564 | static void b2mc(double *b, double *mc, int m, double a) | |||
| 565 | { | |||
| 566 | double d, o; | |||
| 567 | int i; | |||
| 568 | d = mc[m] = b[m]; | |||
| ||||
| 569 | for(i=m--; i>=0; i--) { | |||
| 570 | o = b[i] + (a * d); | |||
| 571 | d = b[i]; | |||
| 572 | mc[i] = o; | |||
| 573 | } | |||
| 574 | } | |||
| 575 | ||||
| 576 | ||||
| 577 | /** freqt: frequency transformation */ | |||
| 578 | //private void freqt(double c1[], int m1, int cepIndex, int m2, double a){ | |||
| 579 | static void freqt(double *c1, int m1, double *c2, int m2, double a) | |||
| 580 | { | |||
| 581 | double *freqt_buff=NULL__null; /* used in freqt */ | |||
| 582 | int freqt_size=0; /* buffer size for freqt */ | |||
| 583 | int i, j; | |||
| 584 | double b = 1 - a * a; | |||
| 585 | int g; /* offset of freqt_buff */ | |||
| 586 | ||||
| 587 | if(m2 > freqt_size) { | |||
| 588 | freqt_buff = walloc(double,m2 + m2 + 2)((double *)safe_walloc(sizeof(double)*(m2 + m2 + 2))); | |||
| 589 | freqt_size = m2; | |||
| 590 | } | |||
| 591 | g = freqt_size +1; | |||
| 592 | ||||
| 593 | for(i = 0; i < m2+1; i++) | |||
| 594 | freqt_buff[g+i] = 0.0; | |||
| 595 | ||||
| 596 | for(i = -m1; i <= 0; i++){ | |||
| 597 | if(0 <= m2 ) | |||
| 598 | freqt_buff[g+0] = c1[-i] + a * (freqt_buff[0] = freqt_buff[g+0]); | |||
| 599 | if(1 <= m2) | |||
| 600 | freqt_buff[g+1] = b * freqt_buff[0] + a * (freqt_buff[1] = freqt_buff[g+1]); | |||
| 601 | ||||
| 602 | for(j=2; j<=m2; j++) | |||
| 603 | freqt_buff[g+j] = freqt_buff[j-1] + a * ( (freqt_buff[j] = freqt_buff[g+j]) - freqt_buff[g+j-1]); | |||
| 604 | ||||
| 605 | } | |||
| 606 | ||||
| 607 | /* move memory */ | |||
| 608 | for(i=0; i<m2+1; i++) | |||
| 609 | c2[i] = freqt_buff[g+i]; | |||
| 610 | ||||
| 611 | if (freqt_buff) | |||
| 612 | wfree(freqt_buff); | |||
| 613 | ||||
| 614 | } | |||
| 615 | ||||
| 616 | /** c2ir: The minimum phase impulse response is evaluated from the minimum phase cepstrum */ | |||
| 617 | static void c2ir(double *c, int nc, double *hh, int leng ) | |||
| 618 | { | |||
| 619 | int n, k, upl; | |||
| 620 | double d; | |||
| 621 | ||||
| 622 | hh[0] = exp(c[0]); | |||
| 623 | for(n = 1; n < leng; n++) { | |||
| 624 | d = 0; | |||
| 625 | upl = (n >= nc) ? nc - 1 : n; | |||
| 626 | for(k = 1; k <= upl; k++ ) | |||
| 627 | d += k * c[k] * hh[n - k]; | |||
| 628 | hh[n] = d / n; | |||
| 629 | } | |||
| 630 | } | |||
| 631 | ||||
| 632 | /** b2en: functions for postfiltering */ | |||
| 633 | static double b2en(double *b, int m, double a) | |||
| 634 | { | |||
| 635 | double *spectrum2en_buff=NULL__null; /* used in spectrum2en */ | |||
| ||||
| 636 | int spectrum2en_size=0; /* buffer size for spectrum2en */ | |||
| 637 | double en = 0.0; | |||
| 638 | int i; | |||
| 639 | double *cep, *ir; | |||
| 640 | ||||
| 641 | if(spectrum2en_size < m) { | |||
| 642 | spectrum2en_buff = walloc(double,(m+1) + 2 * IRLENG)((double *)safe_walloc(sizeof(double)*((m+1) + 2 * IRLENG))); | |||
| 643 | spectrum2en_size = m; | |||
| 644 | } | |||
| 645 | cep = walloc(double,(m+1) + 2 * IRLENG)((double *)safe_walloc(sizeof(double)*((m+1) + 2 * IRLENG))); /* CHECK! these sizes!!! */ | |||
| 646 | ir = walloc(double,(m+1) + 2 * IRLENG)((double *)safe_walloc(sizeof(double)*((m+1) + 2 * IRLENG))); | |||
| 647 | ||||
| 648 | b2mc(b, spectrum2en_buff, m, a); | |||
| 649 | /* freqt(vs->mc, m, vs->cep, vs->irleng - 1, -a);*/ | |||
| 650 | freqt(spectrum2en_buff, m, cep, IRLENG-1, -a); | |||
| 651 | /* HTS_c2ir(vs->cep, vs->irleng, vs->ir, vs->irleng); */ | |||
| 652 | c2ir(cep, IRLENG, ir, IRLENG); | |||
| 653 | en = 0.0; | |||
| 654 | ||||
| 655 | for(i = 0; i < IRLENG; i++) | |||
| 656 | en += ir[i] * ir[i]; | |||
| 657 | ||||
| 658 | if (spectrum2en_buff) | |||
| 659 | wfree(spectrum2en_buff); | |||
| 660 | wfree(cep); | |||
| 661 | wfree(ir); | |||
| 662 | ||||
| 663 | return(en); | |||
| 664 | } | |||
| 665 | ||||
| 666 | /** ignorm: inverse gain normalization */ | |||
| 667 | static void ignorm(double *c1, double *c2, int m, double ng) | |||
| 668 | { | |||
| 669 | double k; | |||
| 670 | int i; | |||
| 671 | if(ng != 0.0 ) { | |||
| 672 | k = pow(c1[0], ng); | |||
| 673 | for(i=m; i>=1; i--) | |||
| 674 | c2[i] = k * c1[i]; | |||
| 675 | c2[0] = (k - 1.0) / ng; | |||
| 676 | } else { | |||
| 677 | /* movem */ | |||
| 678 | for(i=1; i<m; i++) | |||
| 679 | c2[i] = c1[i]; | |||
| 680 | c2[0] = log(c1[0]); | |||
| 681 | } | |||
| 682 | } | |||
| 683 | ||||
| 684 | /** ignorm: gain normalization */ | |||
| 685 | static void gnorm(double *c1, double *c2, int m, double g) | |||
| 686 | { | |||
| 687 | double k; | |||
| 688 | int i; | |||
| 689 | if(g != 0.0) { | |||
| 690 | k = 1.0 + g * c1[0]; | |||
| 691 | for(; m>=1; m--) | |||
| 692 | c2[m] = c1[m] / k; | |||
| 693 | c2[0] = pow(k, 1.0 / g); | |||
| 694 | } else { | |||
| 695 | /* movem */ | |||
| 696 | for(i=1; i<=m; i++) | |||
| 697 | c2[i] = c1[i]; | |||
| 698 | c2[0] = exp(c1[0]); | |||
| 699 | } | |||
| 700 | ||||
| 701 | } | |||
| 702 | ||||
| 703 | /** lsp2lpc: transform LSP to LPC. lsp[1..m] --> a=lpc[0..m] a[0]=1.0 */ | |||
| 704 | static void lsp2lpc(double *lsp, double *a, int m) | |||
| 705 | { | |||
| 706 | double *lsp2lpc_buff=NULL__null; /* used in lsp2lpc */ | |||
| 707 | int lsp2lpc_size=0; /* buffer size of lsp2lpc */ | |||
| 708 | int i, k, mh1, mh2, flag_odd; | |||
| 709 | double xx, xf, xff; | |||
| 710 | int p, q; /* offsets of lsp2lpc_buff */ | |||
| 711 | int a0, a1, a2, b0, b1, b2; /* offsets of lsp2lpc_buff */ | |||
| 712 | ||||
| 713 | flag_odd = 0; | |||
| 714 | if(m % 2 == 0) | |||
| 715 | mh1 = mh2 = m / 2; | |||
| 716 | else { | |||
| 717 | mh1 = (m+1) / 2; | |||
| 718 | mh2 = (m-1) / 2; | |||
| 719 | flag_odd = 1; | |||
| 720 | } | |||
| 721 | ||||
| 722 | if(m > lsp2lpc_size){ | |||
| 723 | lsp2lpc_buff = walloc(double,5 * m + 6)((double *)safe_walloc(sizeof(double)*(5 * m + 6))); | |||
| 724 | lsp2lpc_size = m; | |||
| 725 | } | |||
| 726 | ||||
| 727 | /* offsets of lsp2lpcbuff */ | |||
| 728 | p = m; | |||
| 729 | q = p + mh1; | |||
| 730 | a0 = q + mh2; | |||
| 731 | a1 = a0 + (mh1 +1); | |||
| 732 | a2 = a1 + (mh1 +1); | |||
| 733 | b0 = a2 + (mh1 +1); | |||
| 734 | b1 = b0 + (mh2 +1); | |||
| 735 | b2 = b1 + (mh2 +1); | |||
| 736 | ||||
| 737 | /* move lsp -> lsp2lpc_buff */ | |||
| 738 | for(i=0; i<m; i++) | |||
| 739 | lsp2lpc_buff[i] = lsp[i+1]; | |||
| 740 | ||||
| 741 | for (i = 0; i < mh1 + 1; i++) | |||
| 742 | lsp2lpc_buff[a0 + i] = 0.0; | |||
| 743 | for (i = 0; i < mh1 + 1; i++) | |||
| 744 | lsp2lpc_buff[a1 + i] = 0.0; | |||
| 745 | for (i = 0; i < mh1 + 1; i++) | |||
| 746 | lsp2lpc_buff[a2 + i] = 0.0; | |||
| 747 | for (i = 0; i < mh2 + 1; i++) | |||
| 748 | lsp2lpc_buff[b0 + i] = 0.0; | |||
| 749 | for (i = 0; i < mh2 + 1; i++) | |||
| 750 | lsp2lpc_buff[b1 + i] = 0.0; | |||
| 751 | for (i = 0; i < mh2 + 1; i++) | |||
| 752 | lsp2lpc_buff[b2 + i] = 0.0; | |||
| 753 | ||||
| 754 | /* lsp filter parameters */ | |||
| 755 | for (i = k = 0; i < mh1; i++, k += 2) | |||
| 756 | lsp2lpc_buff[p + i] = -2.0 * cos(lsp2lpc_buff[k]); | |||
| 757 | for (i = k = 0; i < mh2; i++, k += 2) | |||
| 758 | lsp2lpc_buff[q + i] = -2.0 * cos(lsp2lpc_buff[k + 1]); | |||
| 759 | ||||
| 760 | /* impulse response of analysis filter */ | |||
| 761 | xx = 1.0; | |||
| 762 | xf = xff = 0.0; | |||
| 763 | ||||
| 764 | for (k = 0; k <= m; k++) { | |||
| 765 | if (flag_odd == 1) { | |||
| 766 | lsp2lpc_buff[a0 + 0] = xx; | |||
| 767 | lsp2lpc_buff[b0 + 0] = xx - xff; | |||
| 768 | xff = xf; | |||
| 769 | xf = xx; | |||
| 770 | } else { | |||
| 771 | lsp2lpc_buff[a0 + 0] = xx + xf; | |||
| 772 | lsp2lpc_buff[b0 + 0] = xx - xf; | |||
| 773 | xf = xx; | |||
| 774 | } | |||
| 775 | ||||
| 776 | for (i = 0; i < mh1; i++) { | |||
| 777 | lsp2lpc_buff[a0 + i + 1] = lsp2lpc_buff[a0 + i] + lsp2lpc_buff[p + i] * lsp2lpc_buff[a1 + i] + lsp2lpc_buff[a2 + i]; | |||
| 778 | lsp2lpc_buff[a2 + i] = lsp2lpc_buff[a1 + i]; | |||
| 779 | lsp2lpc_buff[a1 + i] = lsp2lpc_buff[a0 + i]; | |||
| 780 | } | |||
| 781 | ||||
| 782 | for (i = 0; i < mh2; i++) { | |||
| 783 | lsp2lpc_buff[b0 + i + 1] = lsp2lpc_buff[b0 + i] + lsp2lpc_buff[q + i] * lsp2lpc_buff[b1 + i] + lsp2lpc_buff[b2 + i]; | |||
| 784 | lsp2lpc_buff[b2 + i] = lsp2lpc_buff[b1 + i]; | |||
| 785 | lsp2lpc_buff[b1 + i] = lsp2lpc_buff[b0 + i]; | |||
| 786 | } | |||
| 787 | ||||
| 788 | if (k != 0) | |||
| 789 | a[k - 1] = -0.5 * (lsp2lpc_buff[a0 + mh1] + lsp2lpc_buff[b0 + mh2]); | |||
| 790 | xx = 0.0; | |||
| 791 | } | |||
| 792 | ||||
| 793 | for (i = m - 1; i >= 0; i--) | |||
| 794 | a[i + 1] = -a[i]; | |||
| 795 | a[0] = 1.0; | |||
| 796 | ||||
| 797 | if (lsp2lpc_buff) | |||
| 798 | wfree(lsp2lpc_buff); | |||
| 799 | } | |||
| 800 | ||||
| 801 | /** gc2gc: generalized cepstral transformation */ | |||
| 802 | static void gc2gc(double *c1, int m1, double g1, double *c2, int m2, double g2) | |||
| 803 | { | |||
| 804 | double *gc2gc_buff=NULL__null; /* used in gc2gc */ | |||
| 805 | int gc2gc_size=0; /* buffer size for gc2gc */ | |||
| 806 | int i, min, k, mk; | |||
| 807 | double ss1, ss2, cc; | |||
| 808 | ||||
| 809 | if( m1 > gc2gc_size ) { | |||
| 810 | gc2gc_buff = walloc(double,m1 + 1)((double *)safe_walloc(sizeof(double)*(m1 + 1))); /* check if these buffers should be created all the time */ | |||
| 811 | gc2gc_size = m1; | |||
| 812 | } | |||
| 813 | ||||
| 814 | /* movem*/ | |||
| 815 | for(i=0; i<(m1+1); i++) | |||
| 816 | gc2gc_buff[i] = c1[i]; | |||
| 817 | ||||
| 818 | c2[0] = gc2gc_buff[0]; | |||
| 819 | ||||
| 820 | for( i=1; i<=m2; i++){ | |||
| 821 | ss1 = ss2 = 0.0; | |||
| 822 | min = m1 < i ? m1 : i - 1; | |||
| 823 | for(k=1; k<=min; k++){ | |||
| 824 | mk = i - k; | |||
| 825 | cc = gc2gc_buff[k] * c2[mk]; | |||
| 826 | ss2 += k * cc; | |||
| 827 | ss1 += mk * cc; | |||
| 828 | } | |||
| 829 | ||||
| 830 | if(i <= m1) | |||
| 831 | c2[i] = gc2gc_buff[i] + (g2 * ss2 - g1 * ss1) / i; | |||
| 832 | else | |||
| 833 | c2[i] = (g2 * ss2 - g1 * ss1) / i; | |||
| 834 | } | |||
| 835 | ||||
| 836 | if (gc2gc_buff) | |||
| 837 | wfree(gc2gc_buff); | |||
| 838 | } | |||
| 839 | ||||
| 840 | /** mgc2mgc: frequency and generalized cepstral transformation */ | |||
| 841 | static void mgc2mgc(double *c1, int m1, double a1, double g1, double *c2, int m2, double a2, double g2) | |||
| 842 | { | |||
| 843 | double a; | |||
| 844 | ||||
| 845 | if(a1 == a2){ | |||
| 846 | gnorm(c1, c1, m1, g1); | |||
| 847 | gc2gc(c1, m1, g1, c2, m2, g2); | |||
| 848 | ignorm(c2, c2, m2, g2); | |||
| 849 | } else { | |||
| 850 | a = (a2 -a1) / (1 - a1 * a2); | |||
| 851 | freqt(c1, m1, c2, m2, a); | |||
| 852 | gnorm(c2, c2, m2, g1); | |||
| 853 | gc2gc(c2, m2, g1, c2, m2, g2); | |||
| 854 | ignorm(c2, c2, m2, g2); | |||
| 855 | ||||
| 856 | } | |||
| 857 | } | |||
| 858 | ||||
| 859 | /** lsp2mgc: transform LSP to MGC. lsp=C[0..m] mgc=C[0..m] */ | |||
| 860 | static void lsp2mgc(double *lsp, double *mgc, int m, double alpha) | |||
| 861 | { | |||
| 862 | int i; | |||
| 863 | /* lsp2lpc */ | |||
| 864 | lsp2lpc(lsp, mgc, m); /* lsp starts in 1! lsp[1..m] --> mgc[0..m] */ | |||
| 865 | if(use_log_gain) | |||
| 866 | mgc[0] = exp(lsp[0]); | |||
| 867 | else | |||
| 868 | mgc[0] = lsp[0]; | |||
| 869 | ||||
| 870 | /* mgc2mgc*/ | |||
| 871 | if(NORMFLG1) | |||
| 872 | ignorm(mgc, mgc, m, xgamma); | |||
| 873 | else if(MULGFLG1) | |||
| 874 | mgc[0] = (1.0 - mgc[0]) * stage; | |||
| 875 | ||||
| 876 | if(MULGFLG1) | |||
| 877 | for(i=m; i>=1; i--) | |||
| 878 | mgc[i] *= -stage; | |||
| 879 | ||||
| 880 | mgc2mgc(mgc, m, alpha, xgamma, mgc, m, alpha, xgamma); /* input and output is in mgc=C */ | |||
| 881 | ||||
| 882 | if(NORMFLG2) | |||
| 883 | gnorm(mgc, mgc, m, xgamma); | |||
| 884 | else if(MULGFLG2) | |||
| 885 | mgc[0] = mgc[0] * xgamma + 1.0; | |||
| 886 | ||||
| 887 | if(MULGFLG2) | |||
| 888 | for(i=m; i>=1; i--) | |||
| 889 | mgc[i] *= xgamma; | |||
| 890 | ||||
| 891 | } | |||
| 892 | ||||
| 893 | /** mglsadf: sub functions for MGLSA filter */ | |||
| 894 | static double mglsadff(double x, double *b, int m, double a, double *d, int d_offset) | |||
| 895 | { | |||
| 896 | int i; | |||
| 897 | double y; | |||
| 898 | y = d[d_offset+0] * b[1]; | |||
| 899 | ||||
| 900 | for(i=1; i<m; i++) { | |||
| 901 | d[d_offset+i] += a * (d[d_offset+i+1] -d[d_offset+i-1]); | |||
| 902 | y += d[d_offset+i] * b[i+1]; | |||
| 903 | } | |||
| 904 | x -= y; | |||
| 905 | ||||
| 906 | for(i=m; i>0; i--) | |||
| 907 | d[d_offset+i] = d[d_offset+i-1]; | |||
| 908 | d[d_offset+0] = a * d[d_offset+0] + (1 - a * a) * x; | |||
| 909 | ||||
| 910 | return x; | |||
| 911 | } | |||
| 912 | ||||
| 913 | static double mglsadf(double x, double *b, int m, double a, int n, double *d) | |||
| 914 | { | |||
| 915 | int i; | |||
| 916 | for(i=0; i<n; i++) | |||
| 917 | x = mglsadff(x, b, m, a, d, (i*(m+1))); | |||
| 918 | ||||
| 919 | return x; | |||
| 920 | } | |||
| 921 | ||||
| 922 | /** posfilter: postfilter for mel-cepstrum. It uses alpha and beta defined in HMMData */ | |||
| 923 | static void postfilter_mcp(double *mcp, int m, double alpha, double beta) | |||
| 924 | { | |||
| 925 | double *postfilter_buff=NULL__null; /* used in postfiltering */ | |||
| 926 | int postfilter_size = 0; /* buffer size for postfiltering */ | |||
| 927 | ||||
| 928 | double e1, e2; | |||
| 929 | int k; | |||
| 930 | ||||
| 931 | if(beta > 0.0 && m > 1){ | |||
| 932 | if(postfilter_size < m){ | |||
| 933 | postfilter_buff = walloc(double,m+1)((double *)safe_walloc(sizeof(double)*(m+1))); | |||
| 934 | postfilter_size = m; | |||
| 935 | } | |||
| 936 | mc2b(mcp, postfilter_buff, m, alpha); | |||
| 937 | e1 = b2en(postfilter_buff, m, alpha); | |||
| 938 | ||||
| 939 | postfilter_buff[1] -= beta * alpha * mcp[2]; | |||
| 940 | for(k = 2; k < m; k++) | |||
| 941 | postfilter_buff[k] *= (1.0 +beta); | |||
| 942 | e2 = b2en(postfilter_buff, m, alpha); | |||
| 943 | postfilter_buff[0] += log(e1/e2) / 2; | |||
| 944 | b2mc(postfilter_buff, mcp, m, alpha); | |||
| 945 | ||||
| 946 | } | |||
| 947 | ||||
| 948 | if (postfilter_buff) | |||
| 949 | wfree(postfilter_buff); | |||
| 950 | ||||
| 951 | } | |||
| 952 | ||||
| 953 | static int modShift(int n, int N) | |||
| 954 | { | |||
| 955 | if( n < 0 ) | |||
| 956 | while( n < 0 ) | |||
| 957 | n = n + N; | |||
| 958 | else | |||
| 959 | while( n >= N ) | |||
| 960 | n = n - N; | |||
| 961 | return n; | |||
| 962 | } | |||
| 963 | ||||
| 964 | /** Generate one pitch period from Fourier magnitudes */ | |||
| 965 | static double *genPulseFromFourierMag(EST_Track *mag, int n, double f0, booleanint aperiodicFlag) | |||
| 966 | { | |||
| 967 | ||||
| 968 | int numHarm = mag->num_channels(); | |||
| 969 | int i; | |||
| 970 | int currentF0 = (int)round(f0); | |||
| 971 | int T, T2; | |||
| 972 | double *pulse = NULL__null; | |||
| 973 | ||||
| 974 | if(currentF0 < 512) | |||
| 975 | T = 512; | |||
| 976 | else | |||
| 977 | T = 1024; | |||
| 978 | T2 = 2*T; | |||
| 979 | ||||
| 980 | /* since is FFT2 no aperiodicFlag or jitter of 25% is applied */ | |||
| 981 | ||||
| 982 | /* get the pulse */ | |||
| 983 | pulse = walloc(double,T)((double *)safe_walloc(sizeof(double)*(T))); | |||
| 984 | EST_FVector real(T2); | |||
| 985 | EST_FVector imag(T2); | |||
| 986 | ||||
| 987 | /* copy Fourier magnitudes (Wai C. Chu "Speech Coding algorithms foundation and evolution of standardized coders" pg. 460) */ | |||
| 988 | real[0] = real[T] = 0.0; /* DC component set to zero */ | |||
| 989 | for(i=1; i<=numHarm; i++){ | |||
| 990 | real[i] = real[T-i] = real[T+i] = real[T2-i] = mag->a(n, i-1); /* Symetric extension */ | |||
| 991 | imag[i] = imag[T-i] = imag[T+i] = imag[T2-i] = 0.0; | |||
| 992 | } | |||
| 993 | for(i=(numHarm+1); i<(T-numHarm); i++){ /* Default components set to 1.0 */ | |||
| 994 | real[i] = real[T-i] = real[T+i] = real[T2-i] = 1.0; | |||
| 995 | imag[i] = imag[T-i] = imag[T+i] = imag[T2-i] = 0.0; | |||
| 996 | } | |||
| 997 | ||||
| 998 | /* Calculate inverse Fourier transform */ | |||
| 999 | IFFT(real, imag); | |||
| 1000 | ||||
| 1001 | /* circular shift and normalise multiplying by sqrt(F0) */ | |||
| 1002 | double sqrt_f0 = sqrt((float)currentF0); | |||
| 1003 | for(i=0; i<T; i++) | |||
| 1004 | pulse[i] = real[modShift(i-numHarm,T)] * sqrt_f0; | |||
| 1005 | ||||
| 1006 | return pulse; | |||
| 1007 | ||||
| 1008 | } | |||
| 1009 | ||||
| 1010 | int htsMLSAVocoder(EST_Track *lf0Pst, | |||
| 1011 | EST_Track *mcepPst, | |||
| 1012 | EST_Track *strPst, | |||
| 1013 | EST_Track *magPst, | |||
| 1014 | int *voiced, | |||
| 1015 | HTSData *htsData, | |||
| 1016 | EST_Wave *wave) | |||
| 1017 | { | |||
| 1018 | ||||
| 1019 | double inc, x; | |||
| 1020 | double xp=0.0,xn=0.0,fxp,fxn,mix; /* samples for pulse and for noise and the filtered ones */ | |||
| 1021 | int i, j, k, m, s, mcepframe, lf0frame, s_double; | |||
| 1022 | double alpha = htsData->alpha; | |||
| 1023 | double beta = htsData->beta; | |||
| 1024 | double aa = 1-alpha*alpha; | |||
| 1025 | int audio_size; /* audio size in samples, calculated as num frames * frame period */ | |||
| 1026 | double *audio_double = NULL__null; | |||
| 1027 | double *magPulse = NULL__null; /* pulse generated from Fourier magnitudes */ | |||
| 1028 | int magSample, magPulseSize; | |||
| 1029 | booleanint aperiodicFlag = false0; | |||
| 1030 | ||||
| 1031 | double *d; /* used in the lpc vocoder */ | |||
| 1032 | ||||
| 1033 | double f0, f0Std, f0Shift, f0MeanOri; | |||
| 1034 | double *mc = NULL__null; /* feature vector for a particular frame */ | |||
| 1035 | double *hp = NULL__null; /* pulse shaping filter, initialised once it is known orderM */ | |||
| 1036 | double *hn = NULL__null; /* noise shaping filter, initialised once it is known orderM */ | |||
| 1037 | ||||
| 1038 | /* Initialise vocoder and mixed excitation, once initialised it is known the order | |||
| 1039 | * of the filters so the shaping filters hp and hn can be initialised. */ | |||
| 1040 | m = mcepPst->num_channels(); | |||
| 1041 | mc = walloc(double,m)((double *)safe_walloc(sizeof(double)*(m))); | |||
| 1042 | ||||
| 1043 | initVocoder(m-1, mcepPst->num_frames(), htsData); | |||
| 1044 | ||||
| 1045 | d = walloc(double,m)((double *)safe_walloc(sizeof(double)*(m))); | |||
| 1046 | if (lpcVocoder) | |||
| 1047 | { | |||
| 1048 | /* printf("Using LPC vocoder\n"); */ | |||
| 1049 | for(i=0; i<m; i++) | |||
| 1050 | d[i] = 0.0; | |||
| 1051 | } | |||
| 1052 | mixedExcitation = htsData->useMixExc; | |||
| 1053 | fourierMagnitudes = htsData->useFourierMag; | |||
| 1054 | ||||
| 1055 | if ( mixedExcitation ) | |||
| 1056 | { | |||
| 1057 | numM = htsData->NumFilters; | |||
| 1058 | orderM = htsData->OrderFilters; | |||
| 1059 | ||||
| 1060 | xpulseSignal = walloc(double,orderM)((double *)safe_walloc(sizeof(double)*(orderM))); | |||
| 1061 | xnoiseSignal = walloc(double,orderM)((double *)safe_walloc(sizeof(double)*(orderM))); | |||
| 1062 | /* initialise xp_sig and xn_sig */ | |||
| 1063 | for(i=0; i<orderM; i++) | |||
| 1064 | xpulseSignal[i] = xnoiseSignal[i] = 0; | |||
| 1065 | ||||
| 1066 | h = htsData->MixFilters; | |||
| 1067 | hp = walloc(double,orderM)((double *)safe_walloc(sizeof(double)*(orderM))); | |||
| 1068 | hn = walloc(double,orderM)((double *)safe_walloc(sizeof(double)*(orderM))); | |||
| 1069 | ||||
| 1070 | //Check if the number of filters is equal to the order of strpst | |||
| 1071 | //i.e. the number of filters is equal to the number of generated strengths per frame. | |||
| 1072 | #if 0 | |||
| 1073 | if(numM != strPst->num_channels()) { | |||
| 1074 | printf("htsMLSAVocoder: error num mix-excitation filters = %d " | |||
| 1075 | " in configuration file is different from generated str order= %d\n", | |||
| 1076 | numM, strPst->num_channels()); | |||
| 1077 | } | |||
| 1078 | printf("HMM speech generation with mixed-excitation.\n"); | |||
| 1079 | #endif | |||
| 1080 | } | |||
| 1081 | #if 0 | |||
| 1082 | else | |||
| 1083 | printf("HMM speech generation without mixed-excitation.\n"); | |||
| 1084 | ||||
| 1085 | if( fourierMagnitudes && htsData->PdfMagFile != NULL__null) | |||
| 1086 | printf("Pulse generated with Fourier Magnitudes.\n"); | |||
| 1087 | else | |||
| 1088 | printf("Pulse generated as a unit pulse.\n"); | |||
| 1089 | ||||
| 1090 | if(beta != 0.0) | |||
| 1091 | printf("Postfiltering applied with beta=%f",(float)beta); | |||
| 1092 | else | |||
| 1093 | printf("No postfiltering applied.\n"); | |||
| 1094 | #endif | |||
| 1095 | ||||
| 1096 | /* Clear content of c, should be done if this function is | |||
| 1097 | called more than once with a new set of generated parameters. */ | |||
| 1098 | for(i=0; i< C_length; i++) | |||
| 1099 | C[i] = CC[i] = CINC[i] = 0.0; | |||
| 1100 | for(i=0; i< D1_length; i++) | |||
| 1101 | D1[i]=0.0; | |||
| 1102 | ||||
| 1103 | f0Std = htsData->F0Std; | |||
| 1104 | f0Shift = htsData->F0Mean; | |||
| 1105 | f0MeanOri = 0.0; | |||
| 1106 | ||||
| 1107 | /* XXX */ | |||
| 1108 | for (mcepframe=0,lf0frame=0; mcepframe<mcepPst->num_frames(); mcepframe++) | |||
| 1109 | { | |||
| 1110 | if(voiced[mcepframe]) | |||
| 1111 | { /* WAS WRONG */ | |||
| 1112 | f0MeanOri = f0MeanOri + lf0Pst->a(mcepframe, 0); | |||
| 1113 | lf0frame++; | |||
| 1114 | } | |||
| 1115 | } | |||
| 1116 | f0MeanOri = f0MeanOri/lf0frame; | |||
| 1117 | ||||
| 1118 | /* ____________________Synthesize speech waveforms_____________________ */ | |||
| 1119 | /* generate Nperiod samples per mcepframe */ | |||
| 1120 | s = 0; /* number of samples */ | |||
| 1121 | s_double = 0; | |||
| 1122 | audio_size = mcepPst->num_frames() * (fprd); | |||
| 1123 | audio_double = walloc(double,audio_size)((double *)safe_walloc(sizeof(double)*(audio_size))); /* initialise buffer for audio */ | |||
| 1124 | magSample = 1; | |||
| 1125 | magPulseSize = 0; | |||
| 1126 | ||||
| 1127 | for(mcepframe=0,lf0frame=0; mcepframe<mcepPst->num_frames(); mcepframe++) | |||
| 1128 | { | |||
| 1129 | /* get current feature vector mcp */ | |||
| 1130 | for(i=0; i<m; i++) | |||
| 1131 | mc[i] = mcepPst->a(mcepframe, i); | |||
| 1132 | ||||
| 1133 | /* f0 modification through the MARY audio effects */ | |||
| 1134 | if(voiced[mcepframe]){ | |||
| 1135 | f0 = f0Std * lf0Pst->a(mcepframe, 0) + (1-f0Std) * f0MeanOri + f0Shift; | |||
| 1136 | lf0frame++; | |||
| 1137 | if(f0 < 0.0) | |||
| 1138 | f0 = 0.0; | |||
| 1139 | } | |||
| 1140 | else{ | |||
| 1141 | f0 = 0.0; | |||
| 1142 | } | |||
| 1143 | ||||
| 1144 | /* if mixed excitation get shaping filters for this frame */ | |||
| 1145 | if (mixedExcitation) | |||
| 1146 | { | |||
| 1147 | for(j=0; j<orderM; j++) | |||
| 1148 | { | |||
| 1149 | hp[j] = hn[j] = 0.0; | |||
| 1150 | for(i=0; i<numM; i++) | |||
| 1151 | { | |||
| 1152 | hp[j] += strPst->a(mcepframe, i) * h[i][j]; | |||
| 1153 | hn[j] += ( 1 - strPst->a(mcepframe, i) ) * h[i][j]; | |||
| 1154 | } | |||
| 1155 | } | |||
| 1156 | } | |||
| 1157 | ||||
| 1158 | /* f0->pitch, in original code here it is used p, so f0=p in the c code */ | |||
| 1159 | if(f0 != 0.0) | |||
| 1160 | f0 = rate/f0; | |||
| 1161 | ||||
| 1162 | /* p1 is initialised in -1, so this will be done just for the first frame */ | |||
| 1163 | if( p1 < 0 ) { | |||
| 1164 | p1 = f0; | |||
| 1165 | pc = p1; | |||
| 1166 | /* for LSP */ | |||
| 1167 | if(stage != 0){ | |||
| 1168 | if( use_log_gain) | |||
| 1169 | C[0] = LZERO; | |||
| 1170 | else | |||
| 1171 | C[0] = ZERO; | |||
| 1172 | for(i=0; i<m; i++ ) | |||
| 1173 | C[i] = i * PI3.14159265358979323846 / m; | |||
| 1174 | /* LSP -> MGC */ | |||
| 1175 | lsp2mgc(C, C, (m-1), alpha); | |||
| 1176 | mc2b(C, C, (m-1), alpha); | |||
| 1177 | gnorm(C, C, (m-1), xgamma); | |||
| 1178 | for(i=1; i<m; i++) | |||
| 1179 | C[i] *= xgamma; | |||
| 1180 | } | |||
| 1181 | ||||
| 1182 | } | |||
| 1183 | ||||
| 1184 | if(stage == 0){ | |||
| 1185 | /* postfiltering, this is done if beta>0.0 */ | |||
| 1186 | postfilter_mcp(mc, (m-1), alpha, beta); | |||
| 1187 | /* mc2b: transform mel-cepstrum to MLSA digital filter coefficients */ | |||
| 1188 | mc2b(mc, CC, (m-1), alpha); | |||
| 1189 | for(i=0; i<m; i++) | |||
| 1190 | CINC[i] = (CC[i] - C[i]) * iprd / fprd; | |||
| 1191 | } else { | |||
| 1192 | ||||
| 1193 | lsp2mgc(mc, CC, (m-1), alpha ); | |||
| 1194 | ||||
| 1195 | mc2b(CC, CC, (m-1), alpha); | |||
| 1196 | ||||
| 1197 | gnorm(CC, CC, (m-1), xgamma); | |||
| 1198 | ||||
| 1199 | for(i=1; i<m; i++) | |||
| 1200 | CC[i] *= xgamma; | |||
| 1201 | ||||
| 1202 | for(i=0; i<m; i++) | |||
| 1203 | CINC[i] = (CC[i] - C[i]) * iprd / fprd; | |||
| 1204 | ||||
| 1205 | } | |||
| 1206 | ||||
| 1207 | /* p=f0 in c code!!! */ | |||
| 1208 | if( p1 != 0.0 && f0 != 0.0 ) { | |||
| 1209 | inc = (f0 - p1) * (double)iprd/(double)fprd; | |||
| 1210 | //System.out.println(" inc=(f0-p1)/80=" + inc ); | |||
| 1211 | } else { | |||
| 1212 | inc = 0.0; | |||
| 1213 | pc = f0; | |||
| 1214 | p1 = 0.0; | |||
| 1215 | } | |||
| 1216 | ||||
| 1217 | /* Here need to generate both xp:pulse and xn:noise signals seprately*/ | |||
| 1218 | gauss = false0; /* Mixed excitation works better with nomal noise */ | |||
| 1219 | ||||
| 1220 | /* Generate fperiod samples per feature vector, normally 80 samples per frame */ | |||
| 1221 | //p1=0.0; | |||
| 1222 | gauss=false0; | |||
| 1223 | for(j=fprd-1, i=(iprd+1)/2; j>=0; j--) { | |||
| 1224 | if(p1 == 0.0) { | |||
| 1225 | if(gauss) | |||
| 1226 | x = 0 /* rand.nextGaussian() */; /* XXX returns double, gaussian distribution mean=0.0 and var=1.0 */ | |||
| 1227 | else | |||
| 1228 | x = uniformRand(); /* returns 1.0 or -1.0 uniformly distributed */ | |||
| 1229 | ||||
| 1230 | if(mixedExcitation) { | |||
| 1231 | xn = x; | |||
| 1232 | xp = 0.0; | |||
| 1233 | } | |||
| 1234 | } else { | |||
| 1235 | if( (pc += 1.0) >= p1 ){ | |||
| 1236 | if(fourierMagnitudes){ | |||
| 1237 | /* jitter is applied just in voiced frames when the stregth of the first band is < 0.5*/ | |||
| 1238 | /* this will work just if Radix FFT is used */ | |||
| 1239 | /*if(strPst.getPar(mcepframe, 0) < 0.5) | |||
| 1240 | aperiodicFlag = true; | |||
| 1241 | else | |||
| 1242 | aperiodicFlag = false; | |||
| 1243 | magPulse = genPulseFromFourierMagRadix(magPst, mcepframe, p1, aperiodicFlag); | |||
| 1244 | */ | |||
| 1245 | ||||
| 1246 | magPulse = genPulseFromFourierMag(magPst, mcepframe, p1, aperiodicFlag); | |||
| 1247 | magSample = 0; | |||
| 1248 | magPulseSize = -27 /* magPulse.length*/; /** XXX **/ | |||
| 1249 | x = magPulse[magSample]; | |||
| 1250 | magSample++; | |||
| 1251 | } else | |||
| 1252 | x = sqrt(p1); | |||
| 1253 | ||||
| 1254 | pc = pc - p1; | |||
| 1255 | } else { | |||
| 1256 | ||||
| 1257 | if(fourierMagnitudes){ | |||
| 1258 | if(magSample >= magPulseSize ){ | |||
| 1259 | x = 0.0; | |||
| 1260 | } | |||
| 1261 | else | |||
| 1262 | x = magPulse[magSample]; | |||
| 1263 | magSample++; | |||
| 1264 | } else | |||
| 1265 | x = 0.0; | |||
| 1266 | } | |||
| 1267 | ||||
| 1268 | if(mixedExcitation) { | |||
| 1269 | xp = x; | |||
| 1270 | if(gauss) | |||
| 1271 | xn = 0 /* rand.nextGaussian() */ ; /* XXX */ | |||
| 1272 | else | |||
| 1273 | xn = uniformRand(); | |||
| 1274 | } | |||
| 1275 | } | |||
| 1276 | ||||
| 1277 | /* apply the shaping filters to the pulse and noise samples */ | |||
| 1278 | /* i need memory of at least for M samples in both signals */ | |||
| 1279 | if(mixedExcitation) { | |||
| 1280 | fxp = 0.0; | |||
| 1281 | fxn = 0.0; | |||
| 1282 | for(k=orderM-1; k>0; k--) { | |||
| 1283 | fxp += hp[k] * xpulseSignal[k]; | |||
| 1284 | fxn += hn[k] * xnoiseSignal[k]; | |||
| 1285 | xpulseSignal[k] = xpulseSignal[k-1]; | |||
| 1286 | xnoiseSignal[k] = xnoiseSignal[k-1]; | |||
| 1287 | } | |||
| 1288 | fxp += hp[0] * xp; | |||
| 1289 | fxn += hn[0] * xn; | |||
| 1290 | xpulseSignal[0] = xp; | |||
| 1291 | xnoiseSignal[0] = xn; | |||
| 1292 | ||||
| 1293 | /* x is a pulse noise excitation and mix is mixed excitation */ | |||
| 1294 | mix = fxp+fxn; | |||
| 1295 | ||||
| 1296 | /* comment this line if no mixed excitation, just pulse and noise */ | |||
| 1297 | x = mix; /* excitation sample */ | |||
| 1298 | /* printf("awb_debug me %d %f\n",(int)(s_double),(float)x); */ | |||
| 1299 | } | |||
| 1300 | ||||
| 1301 | if(lpcVocoder){ | |||
| 1302 | // LPC filter C[k=0] = gain is not used! | |||
| 1303 | if(!NGAIN) | |||
| 1304 | x *= C[0]; | |||
| 1305 | for(k=(m-1); k>1; k--){ | |||
| 1306 | x = x - (C[k] * d[k]); | |||
| 1307 | d[k] = d[k-1]; | |||
| 1308 | } | |||
| 1309 | x = x - (C[1] * d[1]); | |||
| 1310 | d[1] = x; | |||
| 1311 | ||||
| 1312 | } else if(stage == 0 ){ | |||
| 1313 | if(x != 0.0 ) | |||
| 1314 | x *= exp(C[0]); | |||
| 1315 | x = mlsadf(x, C, m, alpha, aa, D1); | |||
| 1316 | ||||
| 1317 | } else { | |||
| 1318 | if(!NGAIN) | |||
| 1319 | x *= C[0]; | |||
| 1320 | x = mglsadf(x, C, (m-1), alpha, stage, D1); | |||
| 1321 | } | |||
| 1322 | ||||
| 1323 | audio_double[s_double] = x; | |||
| 1324 | s_double++; | |||
| 1325 | ||||
| 1326 | if((--i) == 0 ) { | |||
| 1327 | p1 += inc; | |||
| 1328 | for(k=0; k<m; k++){ | |||
| 1329 | C[k] += CINC[k]; | |||
| 1330 | } | |||
| 1331 | i = iprd; | |||
| 1332 | } | |||
| 1333 | } /* for each sample in a period fprd */ | |||
| 1334 | ||||
| 1335 | p1 = f0; | |||
| 1336 | ||||
| 1337 | /* move elements in c */ | |||
| 1338 | /* HTS_movem(v->cc, v->c, m + 1); */ | |||
| 1339 | for(i=0; i<m; i++){ | |||
| 1340 | C[i] = CC[i]; | |||
| 1341 | } | |||
| 1342 | ||||
| 1343 | } /* for each mcep frame */ | |||
| 1344 | ||||
| 1345 | /* printf("Finish processing %d mcep frames.\n",mcepframe); */ | |||
| 1346 | ||||
| 1347 | wave->resize(audio_size,1); | |||
| 1348 | for (i=0; i<s_double; i++) | |||
| 1349 | wave->a(i) = (short)audio_double[i]; | |||
| 1350 | ||||
| 1351 | return 0; | |||
| 1352 | ||||
| 1353 | } /* method htsMLSAVocoder() */ | |||
| 1354 | ||||
| 1355 |