1 /*---------------------------------------------------------------------------*
2 * frontobj.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
23
24 #include <stdlib.h>
25 #if defined(__cplusplus) && defined(_MSC_VER)
26 extern "C"
27 {
28 #include <string.h>
29 }
30 #else
31 #include <string.h>
32 #endif
33
34 #ifndef _RTT
35 #include <stdio.h>
36 #endif
37 #ifdef unix
38 #include <unistd.h>
39 #endif
40 #ifndef POSIX
41 #include <memory.h>
42 #endif
43 #include <assert.h>
44
45 #include "front.h"
46
47 #include "portable.h"
48
49 #include "sh_down.h"
50
51 #define DEBUG 0
52
53
54 static void hamming_window(fftdata *ham, int win_len);
55
56 static front_wave *create_wave_object(void);
57 static void delete_wave_object(front_wave *waveobj);
58 static void setup_wave_object(front_wave *waveobj, front_parameters *parameters);
59 static void clear_wave_object(front_wave *waveobj);
60
61 static front_freq *create_freq_object(void);
62 static void delete_freq_object(front_freq *freqobj);
63 static void setup_freq_object(front_freq *freqobj, front_parameters *parameters, int mel_dim);
64 static void reset_freq_object(front_freq *freqobj);
65 static void clear_freq_object(front_freq *freqobj);
66
67 static front_cep *create_cep_object(void);
68 static void delete_cep_object(front_cep *cepobj);
69 static void setup_cep_object(front_cep *cepobj, front_parameters *parameters,
70 size_t num_fb, size_t mel_dim);
71 static void reset_cep_object(front_cep *cepobj);
72 static void clear_cep_object(front_cep *cepobj);
73
74
75
create_config_object(void)76 front_config *create_config_object(void)
77 {
78 front_config *config;
79 config = (front_config *) CALLOC_CLR(1,
80 sizeof(front_config), "cfront.front_config");
81 return config;
82 }
83
84
85 /*******************************************************************************
86 ** FUNCTION: setup_config_object
87 **
88 ** DESCRIPTION: Set up the front end using the paramteters. This function
89 ** configures the member Wave, Freq and Cep objects, by calling their
90 ** create and setup
91 ** functions.
92 **
93 ** ARGUMENTS:
94 **
95 ** RETURNS: pointer to config object
96 **
97 *******************************************************************************/
98
setup_config_object(front_config * config,front_parameters * parameters)99 void setup_config_object(front_config *config, front_parameters *parameters)
100 {
101
102 ASSERT(config);
103 ASSERT(parameters);
104
105 /* Create and configure sub-components */
106 config->waveobj = create_wave_object();
107 config->freqobj = create_freq_object();
108 config->cepobj = create_cep_object();
109
110 setup_wave_object(config->waveobj, parameters);
111 setup_freq_object(config->freqobj, parameters, parameters->mel_dim);
112 setup_cep_object(config->cepobj, parameters, config->freqobj->nf,
113 parameters->mel_dim);
114 return;
115 }
116
clear_config_object(front_config * config)117 void clear_config_object(front_config *config)
118 {
119
120 ASSERT(config);
121
122 clear_wave_object(config->waveobj);
123 clear_freq_object(config->freqobj);
124 clear_cep_object(config->cepobj);
125
126 delete_wave_object(config->waveobj);
127 config->waveobj = NULL;
128 delete_freq_object(config->freqobj);
129 config->freqobj = NULL;
130 delete_cep_object(config->cepobj);
131 config->cepobj = NULL;
132 return;
133 }
134
135
delete_config_object(front_config * config)136 void delete_config_object(front_config *config)
137 {
138 ASSERT(config);
139 FREE((char *) config);
140 return;
141 }
142
143
create_channel_object(void)144 front_channel *create_channel_object(void)
145 {
146 front_channel *channel;
147
148 channel = (front_channel *) CALLOC_CLR(1,
149 sizeof(front_channel), "cfront.channel");
150 return channel;
151 }
152
153
delete_channel_object(front_channel * channel)154 void delete_channel_object(front_channel *channel)
155 {
156 ASSERT(channel);
157 FREE((char *) channel);
158 }
159
160
setup_channel_object(front_channel * channel,front_wave * waveobj,front_freq * freqobj,front_cep * cepobj)161 void setup_channel_object(
162 front_channel *channel, front_wave *waveobj,
163 front_freq *freqobj, front_cep *cepobj)
164 {
165 ASSERT(channel);
166 ASSERT(waveobj);
167 ASSERT(freqobj);
168 ASSERT(cepobj);
169
170 channel->prebuff = (fftdata *) CALLOC(freqobj->window_length + 1,
171 sizeof(fftdata), "cfront.prebuff");
172 channel->prerefbuff = (fftdata *) CALLOC(freqobj->window_length + 1,
173 sizeof(fftdata), "cfront.prerefbuff");
174 channel->buff_size = freqobj->window_length + 1;
175
176 /* Create gain normalization object, and space for filter bank storage. BP */
177 channel->num_freq = freqobj->nf;
178 channel->filterbank = (cepdata *) CALLOC(channel->num_freq,
179 sizeof(cepdata), "cfront.filterbank");
180 channel->filterbankref = (cepdata *) CALLOC(channel->num_freq,
181 sizeof(cepdata), "cfront.filterbankref");
182
183 channel->mel_dim = cepobj->mel_dim;
184 channel->cep = (cepdata *) CALLOC((Q2 + 1) * (channel->mel_dim + 1),
185 sizeof(cepdata), "cfront.cep");
186 channel->rasta = (cepdata *) CALLOC((channel->mel_dim + 1),
187 sizeof(cepdata), "cfront.rasta");
188 channel->framdata = (featdata *) CALLOC(3 * (channel->mel_dim + 1),
189 sizeof(featdata), "cfront.chan_framdata");
190
191 if (freqobj->do_spectral_sub)
192 {
193 /* Spectral subtraction requires estimate of BG levels. This is currently
194 estimated on the first config->spectral_sub_frame_dur frames, which are
195 assumed to be in silence. The channel means are estimated when the
196 frame count is reached, and is_valid is set, in
197 estimate_spectral_sub_means. Spectral subtraction is turned on with
198 config->do_spectral_sub.
199 */
200
201 channel->spectral_sub = (spectral_sub_info *) CALLOC_CLR(1,
202 sizeof(spectral_sub_info), "cfront.spectral_sub_info");
203 channel->spectral_sub->sub_vector = (cepdata *) CALLOC(NUM_MEL_FREQS,
204 sizeof(cepdata), "cfront.spectral_sub_vector");
205 channel->spectral_sub->frame_dur = cepobj->spectral_sub_frame_dur;
206 channel->spectral_sub->scale = cepobj->spec_sub_scale;
207 }
208
209 ASSERT(freqobj->frame_period > 0);
210 channel->frame_delay = DELTA + (freqobj->window_length / freqobj->frame_period) - 1;
211 channel->forget_factor = cepobj->forget_factor;
212 reset_channel_object(channel);
213 return;
214 }
215
216
clear_channel_object(front_channel * channel)217 void clear_channel_object(front_channel *channel)
218 {
219 ASSERT(channel);
220 FREE((char *) channel->prebuff);
221 channel->prebuff = NULL;
222 FREE((char *) channel->prerefbuff);
223 channel->prerefbuff = NULL;
224 FREE((char *) channel->filterbank);
225 channel->filterbank = NULL;
226 FREE((char *) channel->filterbankref);
227 channel->filterbankref = NULL;
228 FREE((char *) channel->cep);
229 channel->cep = NULL;
230 FREE((char *) channel->rasta);
231 channel->rasta = NULL;
232 FREE((char *) channel->framdata);
233 channel->framdata = NULL;
234 if (channel->spectral_sub)
235 {
236 FREE((char *) channel->spectral_sub->sub_vector);
237 FREE((char *) channel->spectral_sub);
238 channel->spectral_sub = NULL;
239 }
240 channel->buff_size = 0;
241 return;
242 }
243
244
245 /* Replacement fns for reset_std_channel */
reset_channel_object(front_channel * channel)246 void reset_channel_object(front_channel *channel)
247 {
248 size_t ii;
249
250 ASSERT(channel);
251
252 #if DEBUG
253 log_report("Channel reset\n");
254 #endif
255 memset(channel->cep, 0x00, Q2 *(channel->mel_dim + 1) * sizeof(float));
256 memset(channel->prebuff, 0x00, channel->buff_size * sizeof(fftdata));
257 memset(channel->prerefbuff, 0x00, channel->buff_size * sizeof(fftdata));
258 channel->lastx = 0;
259
260 for (ii = 0; ii <= channel->mel_dim; ii++)
261 channel->rasta[ii] = 0;
262
263 if (channel->spectral_sub)
264 {
265 channel->spectral_sub->is_valid = False;
266 for (ii = 0; ii < NUM_MEL_FREQS; ii++)
267 channel->spectral_sub->sub_vector[ii] = (cepdata) 0.0;
268 }
269 channel->frame_count = 0;
270
271 return;
272 }
273
274
275 /******************************************************************************
276 ** WAVE OBJECT
277 *******************************************************************************/
278
create_wave_object(void)279 static front_wave *create_wave_object(void)
280 {
281 front_wave *waveobj;
282
283 waveobj = (front_wave *) CALLOC_CLR(1, sizeof(front_wave), "cfront.waveobj");
284 return waveobj;
285 }
286
287
288
delete_wave_object(front_wave * waveobj)289 static void delete_wave_object(front_wave *waveobj)
290 {
291 ASSERT(waveobj);
292 FREE((char *) waveobj);
293 return;
294 }
295
296
setup_wave_object(front_wave * waveobj,front_parameters * parameters)297 static void setup_wave_object(front_wave *waveobj, front_parameters *parameters)
298 {
299 ASSERT(waveobj);
300 ASSERT(parameters);
301
302 waveobj->samplerate = parameters->samplerate;
303 /* Be careful about the value of COEFDATA_SHIFT - it should be <16.
304 During preemphasis the data is shifted up by COEFDATA_SHIFT too.
305 */
306 waveobj->pre_mel = (coefdata) fixed_point_convert(parameters->pre_mel,
307 COEFDATA_SHIFT);
308 waveobj->high_clip = parameters->high_clip;
309 waveobj->low_clip = parameters->low_clip;
310 waveobj->max_per10000_clip = parameters->max_per10000_clip;
311 waveobj->max_dc_offset = parameters->max_dc_offset;
312 waveobj->high_noise_level_bit = parameters->high_noise_level_bit;
313 waveobj->low_speech_level_bit = parameters->low_speech_level_bit;
314 waveobj->min_samples = parameters->min_samples;
315
316 return;
317 }
318
319
clear_wave_object(front_wave * waveobj)320 static void clear_wave_object(front_wave *waveobj)
321 {
322 ASSERT(waveobj);
323 return;
324 }
325
326 /******************************************************************************
327 ** FREQUENCY OBJECT
328 *******************************************************************************/
create_freq_object(void)329 static front_freq *create_freq_object(void)
330 {
331 front_freq *freqobj;
332 freqobj = (front_freq *) CALLOC_CLR(1,
333 sizeof(front_freq), "cfront.freqobj");
334 freqobj->fc = &freqobj->fcb[1];
335 freqobj->lognp = 4;
336 reset_freq_object(freqobj);
337 return freqobj;
338 }
339
340
delete_freq_object(front_freq * freqobj)341 static void delete_freq_object(front_freq *freqobj)
342 {
343 ASSERT(freqobj);
344 FREE((char *) freqobj);
345 return;
346 }
347
348
setup_freq_object(front_freq * freqobj,front_parameters * parameters,int mel_dim)349 static void setup_freq_object(front_freq *freqobj,
350 front_parameters *parameters, int mel_dim)
351 {
352 int fmax, i, j, high_cut, bandwidth;
353 float t, finc, f;
354
355 ASSERT(freqobj);
356 ASSERT(parameters);
357 ASSERT(FRAMERATE > 0);
358 ASSERT(parameters->samplerate);
359
360 freqobj->framerate = FRAMERATE;
361 freqobj->frame_period = parameters->samplerate / freqobj->framerate;
362 freqobj->samplerate = parameters->samplerate;
363 freqobj->window_length = (int)(parameters->window_factor * freqobj->frame_period);
364 freqobj->low_cut = parameters->low_cut;
365 freqobj->high_cut = parameters->high_cut;
366 freqobj->do_spectral_sub = parameters->do_spectral_sub;
367 freqobj->do_filterbank_input = parameters->do_filterbank_input;
368 freqobj->do_filterbank_dump = parameters->do_filterbank_dump;
369 freqobj->num_fb_to_use = parameters->num_fb_to_use;
370 freqobj->do_nonlinear_filter = True; /* on by default */
371 freqobj->spectrum_filter_num = 0;
372 freqobj->warp_scale = parameters->warp_scale; /*## */
373 freqobj->piecewise_start = parameters->piecewise_start; /*## */
374
375 if (freqobj->high_cut > 0)
376 high_cut = freqobj->high_cut;
377 else
378 high_cut = parameters->samplerate / 2;
379
380 bandwidth = parameters->samplerate / 2;
381 ASSERT(bandwidth != 0);
382
383 freqobj->np = 1 << freqobj->lognp; /* fft sizing */
384 while (freqobj->np < freqobj->window_length)
385 freqobj->np *= 2, freqobj->lognp++;
386 while (freqobj->np < 128)
387 freqobj->np *= 2, freqobj->lognp++;
388 if (freqobj->np > NP)
389 SERVICE_ERROR(FFT_TOO_SMALL);
390
391 /* Change the values of the peakpick forward and backward coefficients
392 to compensate for sample rate. */
393 t = (float) exp(log((double)parameters->peakpickup)
394 * ((double)parameters->samplerate / (double)11025)
395 / ((double)freqobj->np / (double)256));
396 freqobj->peakpickup = (fftdata) fixed_point_convert(t, COEFDATA_SHIFT);
397 t = (float) exp(log((double)parameters->peakpickdown)
398 * ((double)parameters->samplerate / (double)11025)
399 / ((double)freqobj->np / (double)256));
400 freqobj->peakpickdown = (fftdata) fixed_point_convert(t, COEFDATA_SHIFT);
401
402 #if BIGGER_WINDOW
403 freqobj->window_length = freqobj->np;
404 #endif
405 configure_fft(&freqobj->fft, freqobj->np);
406 freqobj->ns = freqobj->np / 2 + 1;
407 fmax = bandwidth;
408 finc = (float)parameters->samplerate / (float)freqobj->np;
409 /* finc= fmax/freqobj->ns; */
410 freqobj->cut_off_below = (int)(((long)freqobj->low_cut * freqobj->np) / (2.0 * bandwidth));
411 freqobj->cut_off_above = (int)(((long)high_cut * freqobj->np) / (2.0 * bandwidth));
412
413 freqobj->fc[-1] = (fftdata) freqobj->low_cut; /* 1st channel at cutoff */
414 i = ((int)freqobj->low_cut + 50) / 100 + 1; /* other channels at x00Hz */
415 for (freqobj->nf = 0; i <= 10; i++, freqobj->nf++)
416 freqobj->fc[freqobj->nf] = (fftdata)(100 * i); /* 100 Hz */
417 for (f = 1000.; f <= high_cut; freqobj->nf++)
418 {
419 f *= (float)1.1; /* 10% */
420 freqobj->fc[freqobj->nf] = (fftdata) fixed_round(f); /* 10 % */
421 }
422 freqobj->nf--;
423
424 if ((freqobj->fc[freqobj->nf] + freqobj->fc[freqobj->nf-1]) / 2. > high_cut)
425 freqobj->nf--;
426 freqobj->fc[freqobj->nf] = (fftdata) high_cut;
427 freqobj->fc[freqobj->nf+1] = (fftdata) high_cut;
428
429 #if DEBUG
430 write_frames(freqobj->nf + 1, 1, freqobj->fc, D_FLOAT);
431 #endif
432
433 for (i = 0; i <= freqobj->cut_off_below; i++)
434 freqobj->framp[i] = 0;
435 freqobj->fcscl[0] = 0;
436 freqobj->fcmid[0] = freqobj->cut_off_below;
437 f = (freqobj->cut_off_below + 1) * finc;
438 for (i = 0, j = freqobj->cut_off_below + 1; i <= freqobj->nf; i++)
439 {
440 freqobj->fcscl[i+1] = (fftdata) 0.0;
441 for (; f < freqobj->fc[i] && f < (float) high_cut; f += finc, j++)
442 {
443 t = (f - freqobj->fc[i-1]) / (freqobj->fc[i] - freqobj->fc[i-1]);
444 freqobj->framp[j] = (fftdata) fixed_point_convert(t, RAMP_SHIFT); /* scale it up by 12 bits, (16 - 4) */
445 freqobj->fcscl[i] += (fftdata) SHIFT_UP(1, RAMP_SHIFT) - freqobj->framp[j]; /* scale it up by 12 bits as well () */
446 freqobj->fcscl[i+1] += freqobj->framp[j]; /* scale it up by 12 bits as well () */
447 }
448 if (j > freqobj->cut_off_above)
449 freqobj->fcmid[i+1] = freqobj->cut_off_above;
450 else
451 freqobj->fcmid[i+1] = j;
452 }
453 /* Put in a check to validate the range of fcscl[] for fixed point f/e
454 */
455 #if DEBUG
456 write_frames(freqobj->nf, 1, freqobj->fcmid, D_LONG);
457 write_frames(freqobj->nf, 1, freqobj->fcscl, D_LONG);
458 write_frames(freqobj->ns, 1, freqobj->framp, D_LONG);
459 #endif
460
461 if (mel_dim > freqobj->nf)
462 SERVICE_ERROR(BAD_COSINE_TRANSFORM);
463
464 if (freqobj->nf > NF)
465 SERVICE_ERROR(BAD_COSINE_TRANSFORM);
466
467 /* Weighting function construction */
468 freqobj->ham = (fftdata *) CALLOC(freqobj->window_length + 1,
469 sizeof(fftdata), "cfront.ham");
470 hamming_window(freqobj->ham, freqobj->window_length);
471
472 /* Sine tables for FFT */
473
474 #if DEBUG
475 #define log_report printf
476 log_report("fc\n");
477 write_scaled_frames(freqobj->nf + 1, 1, freqobj->fc, D_FIXED, 1);
478
479 log_report("framp\n");
480 write_scaled_frames(freqobj->ns, 1, freqobj->framp, D_FIXED, 1);
481 #endif
482
483 create_spectrum_filter(freqobj, parameters->spectrum_filter_freq,
484 parameters->spectrum_filter_spread);
485 if (freqobj->spectrum_filter_num == 0)
486 clear_spectrum_filter(freqobj);
487 return;
488 }
489
hamming_window(fftdata * ham,int win_len)490 static void hamming_window(fftdata *ham, int win_len)
491 /*
492 ** add Hamming window on speech data */
493 {
494 int i;
495 double f;
496 double coef;
497
498 f = (2 * M_PI) / win_len;
499 for (i = 0; i <= win_len; i++)
500 {
501 coef = 0.54 - 0.46 * cos(f * (double)i);
502 ham[i] = (fftdata) fixed_point_convert((float)coef,
503 HALF_FFTDATA_SIZE - 1);
504 }
505 return;
506 }
507
clear_freq_object(front_freq * freqobj)508 static void clear_freq_object(front_freq *freqobj)
509 {
510 ASSERT(freqobj);
511 if (freqobj->ham)
512 {
513 FREE((char *)freqobj->ham);
514 freqobj->ham = NULL;
515 }
516 unconfigure_fft(&freqobj->fft);
517
518 if (freqobj->spectrum_filter_num > 0)
519 clear_spectrum_filter(freqobj);
520 return;
521 }
522
reset_freq_object(front_freq * freqobj)523 static void reset_freq_object(front_freq *freqobj)
524 {
525 ASSERT(freqobj);
526 return;
527 }
528
529
530 /******************************************************************************
531 ** CEPSTRAL OBJECT
532 *******************************************************************************/
create_cep_object(void)533 static front_cep *create_cep_object(void)
534 {
535 front_cep *cepobj;
536 cepobj = (front_cep *) CALLOC_CLR(1, sizeof(front_cep), "cfront.cepobj");
537 return cepobj;
538 }
539
540
delete_cep_object(front_cep * cepobj)541 static void delete_cep_object(front_cep *cepobj)
542 {
543 ASSERT(cepobj);
544 FREE((char *) cepobj);
545 return;
546 }
547
setup_cep_object(front_cep * cepobj,front_parameters * parameters,size_t num_fb,size_t mel_dim)548 static void setup_cep_object(front_cep *cepobj, front_parameters *parameters,
549 size_t num_fb, size_t mel_dim)
550 {
551 float f;
552 size_t i, j;
553
554 ASSERT(cepobj);
555 ASSERT(parameters);
556 cepobj->mel_dim = mel_dim;
557 cepobj->do_dd_mel = parameters->do_dd_mel;
558 cepobj->do_skip_even_frames = parameters->do_skip_even_frames;
559 cepobj->do_smooth_c0 = parameters->do_smooth_c0;
560 cepobj->sv6_margin = parameters->sv6_margin;
561 cepobj->forget_factor = parameters->forget_factor;
562 cepobj->spectral_sub_frame_dur = parameters->spectral_sub_frame_dur;
563 cepobj->spec_sub_scale = (coefdata) fixed_point_convert(
564 parameters->spec_sub_scale, COEFDATA_SHIFT);
565 cepobj->lpc_order = parameters->lpc_order;
566
567
568 cepobj->mel_offset = (cepdata *) CALLOC(MEL_FREQ_ARRAY_SIZE,
569 sizeof(cepdata), "cfront.mel_offset");
570 cepobj->mel_loop = (cepdata *) CALLOC(MEL_FREQ_ARRAY_SIZE,
571 sizeof(cepdata), "cfront.mel_loop");
572 cepobj->melA_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
573 sizeof(cepdata), "cfront.melA_scale");
574 cepobj->dmelA_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
575 sizeof(cepdata), "cfront.dmelA_scale");
576 cepobj->ddmelA_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
577 sizeof(cepdata), "cfront.ddmelA_scale");
578 cepobj->melB_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
579 sizeof(cepdata), "cfront.melB_scale");
580 cepobj->dmelB_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
581 sizeof(cepdata), "cfront.dmelB_scale");
582 cepobj->ddmelB_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
583 sizeof(cepdata), "cfront.ddmelB_scale");
584 cepobj->rastaA_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
585 sizeof(cepdata), "cfront.rastaA_scale");
586 cepobj->rastaB_scale = (cepdata *) CALLOC(cepobj->mel_dim + 1,
587 sizeof(cepdata), "cfront.rastaB_scale");
588
589 cepobj->do_scales = True; /* Hack so default scalings are loaded */
590
591 for (i = 0; i < MEL_FREQ_ARRAY_SIZE; ++i)
592 {
593 cepobj->mel_offset[i] = (cepdata) parameters->mel_offset[i];
594 cepobj->mel_loop[i] = (cepdata) parameters->mel_loop[i];
595 }
596
597 for (i = 0; i <= cepobj->mel_dim; ++i)
598 {
599 cepobj->melA_scale[i] = (cepdata) parameters->melA_scale[i];
600 cepobj->dmelA_scale[i] = (cepdata) parameters->dmelA_scale[i];
601 cepobj->ddmelA_scale[i] = (cepdata) parameters->ddmelA_scale[i];
602 cepobj->melB_scale[i] = (cepdata) parameters->melB_scale[i];
603 cepobj->dmelB_scale[i] = (cepdata) parameters->dmelB_scale[i];
604 cepobj->ddmelB_scale[i] = (cepdata) parameters->ddmelB_scale[i];
605 cepobj->rastaA_scale[i] = (cepdata) parameters->rastaA_scale[i];
606 cepobj->rastaB_scale[i] = (cepdata) parameters->rastaB_scale[i];
607 cepobj->melA_scale[i] = (cepdata) fixed_point_convert((float) parameters->melA_scale[i],
608 BYTERANGE_SHIFT);
609 cepobj->dmelA_scale[i] = (cepdata) fixed_point_convert((float) parameters->dmelA_scale[i],
610 BYTERANGE_SHIFT);
611 cepobj->ddmelA_scale[i] = (cepdata) fixed_point_convert((float) parameters->ddmelA_scale[i],
612 BYTERANGE_SHIFT);
613 cepobj->melB_scale[i] = (cepdata) fixed_point_convert((float) parameters->melB_scale[i],
614 BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
615 cepobj->dmelB_scale[i] = (cepdata) fixed_point_convert((float) parameters->dmelB_scale[i],
616 BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
617 cepobj->ddmelB_scale[i] = (cepdata) fixed_point_convert((float) parameters->ddmelB_scale[i],
618 BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
619 cepobj->rastaA_scale[i] = (cepdata) fixed_point_convert((float) parameters->rastaA_scale[i],
620 BYTERANGE_SHIFT);
621 cepobj->rastaB_scale[i] = (cepdata) fixed_point_convert((float) parameters->rastaB_scale[i],
622 BYTERANGE_SHIFT + LOG_SCALE_SHIFT);
623 }
624
625 /* Now allocate space for the cosine matrix. Previously fixed. */
626 f = (float)(M_PI / num_fb);
627 cepobj->cs = (cepdata *) CALLOC(num_fb * num_fb, sizeof(cepdata), "cfront.cosine_matrix");
628 for (i = 0; i < num_fb; ++i)
629 {
630 for (j = 0; j < num_fb; ++j) /* TODO: fixedpt cosine matrix */
631 cepobj->cs[i*(num_fb)+j] = (cepdata) fixed_point_convert(
632 (float)(cos((double)(i * (j + .5) * f)) / num_fb),
633 COSINE_TABLE_SHIFT); /* balanced after icostrans */
634 }
635 create_lookup_log(&cepobj->logtab, 12); /* TODO: rename 12 as macro */
636 reset_cep_object(cepobj);
637 return;
638 }
639
640
reset_cep_object(front_cep * cepobj)641 static void reset_cep_object(front_cep *cepobj)
642 {
643 ASSERT(cepobj);
644 return;
645 }
646
647
clear_cep_object(front_cep * cepobj)648 static void clear_cep_object(front_cep *cepobj)
649 {
650 ASSERT(cepobj);
651 if (cepobj->melA_scale)
652 FREE((char*)cepobj->melA_scale);
653 cepobj->melA_scale = NULL; /* Set to null in either case, for simplicity */
654 if (cepobj->dmelA_scale)
655 FREE((char*)cepobj->dmelA_scale);
656 cepobj->dmelA_scale = NULL;
657 if (cepobj->ddmelA_scale)
658 FREE((char*)cepobj->ddmelA_scale);
659 cepobj->ddmelA_scale = NULL;
660 if (cepobj->melB_scale)
661 FREE((char*)cepobj->melB_scale);
662 cepobj->melB_scale = NULL;
663 if (cepobj->dmelB_scale)
664 FREE((char*)cepobj->dmelB_scale);
665 cepobj->dmelB_scale = NULL;
666 if (cepobj->ddmelB_scale)
667 FREE((char*)cepobj->ddmelB_scale);
668 cepobj->ddmelB_scale = NULL;
669 if (cepobj->rastaA_scale)
670 FREE((char*)cepobj->rastaA_scale);
671 cepobj->rastaA_scale = NULL;
672 if (cepobj->rastaB_scale)
673 FREE((char*)cepobj->rastaB_scale);
674 cepobj->rastaB_scale = NULL;
675 if (cepobj->cs)
676 FREE((char *) cepobj->cs);
677 cepobj->cs = NULL;
678 if (cepobj->mel_offset)
679 FREE((char*)cepobj->mel_offset);
680 cepobj->mel_offset = NULL;
681 if (cepobj->mel_loop)
682 FREE((char*)cepobj->mel_loop);
683 cepobj->mel_loop = NULL;
684 destroy_lookup_log(&cepobj->logtab);
685 return;
686 }
687