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)
26extern "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
54static void hamming_window(fftdata *ham, int win_len);
55
56static front_wave *create_wave_object(void);
57static void delete_wave_object(front_wave *waveobj);
58static void setup_wave_object(front_wave *waveobj, front_parameters *parameters);
59static void clear_wave_object(front_wave *waveobj);
60
61static front_freq *create_freq_object(void);
62static void delete_freq_object(front_freq *freqobj);
63static void setup_freq_object(front_freq *freqobj, front_parameters *parameters, int mel_dim);
64static void reset_freq_object(front_freq *freqobj);
65static void clear_freq_object(front_freq *freqobj);
66
67static front_cep *create_cep_object(void);
68static void delete_cep_object(front_cep *cepobj);
69static void setup_cep_object(front_cep *cepobj, front_parameters *parameters,
70                             size_t num_fb, size_t mel_dim);
71static void reset_cep_object(front_cep *cepobj);
72static void clear_cep_object(front_cep *cepobj);
73
74
75
76front_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
99void 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
117void 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
136void delete_config_object(front_config *config)
137{
138  ASSERT(config);
139  FREE((char *) config);
140  return;
141}
142
143
144front_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
154void delete_channel_object(front_channel *channel)
155{
156  ASSERT(channel);
157  FREE((char *) channel);
158}
159
160
161void 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
217void 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 */
246void 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
279static 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
289static void delete_wave_object(front_wave *waveobj)
290{
291  ASSERT(waveobj);
292  FREE((char *) waveobj);
293  return;
294}
295
296
297static 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
320static void clear_wave_object(front_wave *waveobj)
321{
322  ASSERT(waveobj);
323  return;
324}
325
326/******************************************************************************
327**  FREQUENCY OBJECT
328*******************************************************************************/
329static 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
341static void delete_freq_object(front_freq *freqobj)
342{
343  ASSERT(freqobj);
344  FREE((char *) freqobj);
345  return;
346}
347
348
349static 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
490static 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
508static 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
523static void reset_freq_object(front_freq *freqobj)
524{
525  ASSERT(freqobj);
526  return;
527}
528
529
530/******************************************************************************
531**  CEPSTRAL OBJECT
532*******************************************************************************/
533static 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
541static void delete_cep_object(front_cep *cepobj)
542{
543  ASSERT(cepobj);
544  FREE((char *) cepobj);
545  return;
546}
547
548static 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
641static void reset_cep_object(front_cep *cepobj)
642{
643  ASSERT(cepobj);
644  return;
645}
646
647
648static 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