Home | History | Annotate | Download | only in cfront
      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 
     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 
     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 
    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 
    136 void delete_config_object(front_config *config)
    137 {
    138   ASSERT(config);
    139   FREE((char *) config);
    140   return;
    141 }
    142 
    143 
    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 
    154 void delete_channel_object(front_channel *channel)
    155 {
    156   ASSERT(channel);
    157   FREE((char *) channel);
    158 }
    159 
    160 
    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 
    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 */
    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 
    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 
    289 static void delete_wave_object(front_wave *waveobj)
    290 {
    291   ASSERT(waveobj);
    292   FREE((char *) waveobj);
    293   return;
    294 }
    295 
    296 
    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 
    320 static void clear_wave_object(front_wave *waveobj)
    321 {
    322   ASSERT(waveobj);
    323   return;
    324 }
    325 
    326 /******************************************************************************
    327 **  FREQUENCY OBJECT
    328 *******************************************************************************/
    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 
    341 static void delete_freq_object(front_freq *freqobj)
    342 {
    343   ASSERT(freqobj);
    344   FREE((char *) freqobj);
    345   return;
    346 }
    347 
    348 
    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 
    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 
    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 
    523 static void reset_freq_object(front_freq *freqobj)
    524 {
    525   ASSERT(freqobj);
    526   return;
    527 }
    528 
    529 
    530 /******************************************************************************
    531 **  CEPSTRAL OBJECT
    532 *******************************************************************************/
    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 
    541 static void delete_cep_object(front_cep *cepobj)
    542 {
    543   ASSERT(cepobj);
    544   FREE((char *) cepobj);
    545   return;
    546 }
    547 
    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 
    641 static void reset_cep_object(front_cep *cepobj)
    642 {
    643   ASSERT(cepobj);
    644   return;
    645 }
    646 
    647 
    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