Home | History | Annotate | Download | only in ca
      1 /*---------------------------------------------------------------------------*
      2  *  pat_basi.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 #include <stdlib.h>
     21 #include <string.h>
     22 #ifndef _RTT
     23 #include <stdio.h>
     24 #endif
     25 
     26 #ifdef unix
     27 #include <unistd.h>
     28 #endif
     29 #include <assert.h>
     30 
     31 
     32 #include "simapi.h"
     33 #include "portable.h"
     34 #include "swicms.h"
     35 
     36 #ifdef SET_RCSID
     37 static const char *rcsid = 0 ? (const char *) &rcsid :
     38                            "$Id: pat_basi.c,v 1.9.6.11 2008/03/07 18:49:28 dahan Exp $";
     39 #endif
     40 
     41 extern const float   root_pi_over_2;
     42 
     43 CA_Pattern *CA_AllocatePattern(void)
     44 {
     45   TRY_CA_EXCEPT
     46   CA_Pattern *hPattern = NULL;
     47 
     48   hPattern = (CA_Pattern *) CALLOC_CLR(1,
     49              sizeof(CA_Pattern), "ca.hPattern");
     50   hPattern->is_loaded = False;
     51   //hPattern->setup_whole = NULL;
     52   //hPattern->setup_sub = NULL;
     53   hPattern->ca_rtti = CA_PATTERN_SIGNATURE;
     54   return (hPattern);
     55 
     56   BEG_CATCH_CA_EXCEPT
     57   END_CATCH_CA_EXCEPT(hPattern)
     58 }
     59 
     60 
     61 void CA_FreePattern(CA_Pattern *hPattern)
     62 {
     63   TRY_CA_EXCEPT
     64 
     65   ASSERT(hPattern);
     66   FREE((char *) hPattern);
     67   return;
     68 
     69   BEG_CATCH_CA_EXCEPT
     70   END_CATCH_CA_EXCEPT(hPattern)
     71 }
     72 
     73 
     74 int CA_LoadPattern(CA_Pattern *hPattern, CA_PatInputParams *hPatInput,
     75                    int dimen , char *multable , char *imelda)
     76 {
     77 
     78   TRY_CA_EXCEPT
     79 #ifndef _RTT
     80   int ii, ret_code;
     81 
     82   ASSERT(hPattern);
     83   ASSERT(hPatInput);
     84   if (hPattern->is_loaded == True)
     85     SERVICE_ERROR(PATTERN_ALREADY_LOADED);
     86   if (hPatInput->is_loaded == False)
     87     SERVICE_ERROR(PATTERN_INPUT_NOT_LOADED);
     88 
     89   hPattern->data.prep = (preprocessed *) CALLOC_CLR(1,
     90                         sizeof(preprocessed), "ca.hPattern->data.prep");
     91 
     92   /*  Load the Imelda transform if specified */
     93   if (imelda && strlen(imelda) > 0)
     94   {
     95     ret_code = init_newton_transform(hPattern->data.prep, 0, imelda, hPatInput->dimen);
     96     if (ret_code > 0)
     97       SERVICE_ERROR(PATTERN_NOT_LOADED);
     98   }
     99   else
    100   {
    101     hPattern->data.prep->use_dim = hPatInput->dimen;
    102     hPattern->data.prep->use_from = hPatInput->feat_start;
    103   }
    104 
    105   if (hPatInput->whole_dimen == 0)
    106     hPattern->data.prep->whole_dim = hPatInput->dimen;
    107   else
    108     hPattern->data.prep->whole_dim = hPatInput->whole_dimen;
    109   if (hPattern->data.prep->whole_dim > hPattern->data.prep->use_dim)
    110     SERVICE_ERROR(BAD_PARAMETER);
    111 
    112   hPattern->data.prep->mix_score_scale = (prdata)(128 * hPatInput->mix_score_scale + 0.5)
    113                                          - (prdata)0.5;
    114   hPattern->data.prep->uni_score_scale = (prdata)(128 * hPatInput->uni_score_scale + 0.5)
    115                                          - (prdata)0.5;
    116   hPattern->data.prep->uni_score_offset = (prdata) hPatInput->uni_score_offset;
    117   hPattern->data.prep->imelda_scale = (prdata)hPatInput->imelda_scale;
    118   init_preprocessed(hPattern->data.prep, dimen, hPatInput->imelda_scale); /* TODO: move this to Setup */
    119 
    120 
    121   /* Annotation parameters */
    122   hPattern->data.prep->end.rel_low  = hPatInput->rel_low;
    123   hPattern->data.prep->end.rel_high  = hPatInput->rel_high;
    124   hPattern->data.prep->end.gap_period  = hPatInput->gap_period;
    125   hPattern->data.prep->end.click_period = hPatInput->click_period;
    126   hPattern->data.prep->end.breath_period = hPatInput->breath_period;
    127   hPattern->data.prep->end.extend_annotation = hPatInput->extend_annotation;
    128   hPattern->data.prep->end.min_annotation_frames = hPatInput->min_annotation_frames;
    129   hPattern->data.prep->end.max_annotation_frames = hPatInput->max_annotation_frames;
    130   hPattern->data.prep->end.min_segment_rel_c0 = hPatInput->min_segment_rel_c0;
    131   hPattern->data.prep->end.min_initial_quiet_frames = hPatInput->min_initial_quiet_frames;
    132   hPattern->data.prep->end.delete_leading_segments = hPatInput->delete_leading_segments;
    133   hPattern->data.prep->end.leading_segment_min_frames = hPatInput->leading_segment_min_frames;
    134   hPattern->data.prep->end.leading_segment_max_frames = hPatInput->leading_segment_max_frames;
    135   hPattern->data.prep->end.leading_segment_min_silence_gap_frames
    136   = hPatInput->leading_segment_min_silence_gap_frames;
    137   hPattern->data.prep->end.leading_segment_accept_if_not_found
    138   = hPatInput->leading_segment_accept_if_not_found;
    139 #if DO_SUBTRACTED_SEGMENTATION
    140   hPattern->data.prep->end.snr_holdoff = hPatInput->snr_holdoff;
    141   hPattern->data.prep->end.min_acceptable_snr = hPatInput->min_acceptable_snr;
    142 #endif
    143   hPattern->data.prep->end.param  = hPatInput->param;
    144   hPattern->data.prep->end.beep_size = hPatInput->beep_size;
    145   hPattern->data.prep->end.beep_threshold = hPatInput->beep_threshold;
    146 
    147 
    148   /* log-lookup table */
    149   create_lookup_logadd(&hPattern->data.prep->add, (float)MUL_SCALE);
    150 
    151   /* Build the weights conversion table */
    152   for (ii = 0; ii < MAX_WTS; ii++)
    153     hPattern->data.prep->exp_wt[ii] =
    154       (prdata)(WEIGHT_SCALE * exp((double)(0x01 << WT_ADJUST) *
    155                                   (double) - ii / (MUL_SCALE * hPattern->data.prep->add.scale)) +
    156                0.5) - (prdata)0.5;
    157 
    158   hPattern->data.prep->ref_count = 1;
    159   hPattern->is_loaded = True;
    160 
    161   return (True);
    162 #else
    163   log_report("RTT not in module\n");
    164   SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
    165   return (False);
    166 #endif
    167 
    168 
    169   BEG_CATCH_CA_EXCEPT
    170   END_CATCH_CA_EXCEPT(hPattern)
    171 
    172 }
    173 
    174 void CA_UnloadPattern(CA_Pattern *hPattern)
    175 {
    176   TRY_CA_EXCEPT
    177   ASSERT(hPattern);
    178   if (hPattern->is_loaded == False)
    179     SERVICE_ERROR(PATTERN_NOT_LOADED);
    180 
    181   if (--hPattern->data.prep->ref_count == 0)
    182   {
    183     if (hPattern->data.prep->matrix)
    184       free_linear_transform(hPattern->data.prep);
    185 
    186     if (hPattern->data.prep->add.table)
    187       destroy_lookup_logadd(&hPattern->data.prep->add);
    188 
    189     clear_preprocessed(hPattern->data.prep);
    190 
    191     FREE((char *) hPattern->data.prep);
    192     hPattern->data.prep = NULL;
    193   }
    194 
    195   hPattern->is_loaded = False;
    196   return;
    197   BEG_CATCH_CA_EXCEPT
    198   END_CATCH_CA_EXCEPT(hPattern)
    199 }
    200 
    201 
    202 void CA_SetupPatternForAcoustic(CA_Pattern *hPattern, CA_Acoustic *hAcoust)
    203 {
    204   TRY_CA_EXCEPT
    205 #ifdef SREC_ENGINE_VERBOSE_LOGGING
    206   PLogMessage("in SetupPatternForAcoustic\n");
    207 #endif
    208   /*  Setup for mul-table if necessary
    209   */
    210   ASSERT(hPattern);
    211   ASSERT(hAcoust);
    212   if (hPattern->is_loaded == False)
    213     SERVICE_ERROR(PATTERN_NOT_LOADED);
    214   if (hAcoust->is_loaded == False)
    215     SERVICE_ERROR(ACOUSTIC_NOT_LOADED);
    216   /* Check that if the Acoustic object is already set up then
    217   the pattern objects must have certain similarities. */
    218   if (hAcoust->pattern_setup_count > 0)
    219   {
    220     if (hPattern->data.prep->imelda_scale != hAcoust->imelda_scale)
    221       SERVICE_ERROR(ACOUSTIC_PATTERN_MISMATCH);
    222     if (hPattern->data.prep->use_dim != hAcoust->use_dim)
    223       SERVICE_ERROR(ACOUSTIC_PATTERN_MISMATCH);
    224   }
    225 #ifdef SREC_ENGINE_VERBOSE_LOGGING
    226   //PLogMessage("mod_style %d\n", hAcoust->acc.mod_style);
    227 #endif
    228 
    229   hAcoust->pattern_setup_count++;
    230   return;
    231 
    232   BEG_CATCH_CA_EXCEPT
    233   END_CATCH_CA_EXCEPT(hPattern)
    234 }
    235 
    236 void CA_ClearPatternForAcoustic(CA_Pattern *hPattern, CA_Acoustic *hAcoust)
    237 {
    238   TRY_CA_EXCEPT
    239   ASSERT(hPattern);
    240   ASSERT(hAcoust);
    241   if (hPattern->is_loaded == False)
    242     SERVICE_ERROR(PATTERN_NOT_LOADED);
    243   if (hAcoust->pattern_setup_count == 0)
    244     SERVICE_ERROR(ACOUSTIC_HAS_NO_PATTERN);
    245   hAcoust->pattern_setup_count--;
    246 
    247   return;
    248   BEG_CATCH_CA_EXCEPT
    249   END_CATCH_CA_EXCEPT(hPattern)
    250 }
    251 
    252 
    253 int CA_MakePatternFrame(CA_Pattern *hPattern, CA_Utterance *hUtt)
    254 {
    255 
    256   TRY_CA_EXCEPT
    257   int status_code;
    258   swicms_norm_info* swicms;
    259 
    260   ASSERT(hPattern);
    261   ASSERT(hUtt);
    262 
    263   if (hPattern->is_loaded == False)
    264     SERVICE_ERROR(PATTERN_NOT_LOADED);
    265 
    266   status_code = get_data_frame(hPattern->data.prep, &hUtt->data);
    267 
    268   /* swicms_cache_frame() must be here because get_data_frame() is called from
    269      backtracing.  Is the caching at the front-end even necessary any more?
    270   */
    271   swicms = hUtt->data.gen_utt.swicms;
    272   if (!swicms->is_valid)
    273     swicms_lda_process(swicms, hPattern->data.prep);
    274 
    275   swicms_cache_frame(swicms, hPattern->data.prep->seq_unnorm,
    276                      hUtt->data.gen_utt.channorm->dim);
    277   apply_channel_normalization_in_swicms(swicms, hPattern->data.prep->seq,
    278                                         hPattern->data.prep->seq_unnorm,
    279                                         hUtt->data.gen_utt.channorm->dim);
    280 
    281   /* prepare is fairly useless and should be removed */
    282   prepare_data_frame(hPattern->data.prep);
    283   return (status_code);
    284 
    285   BEG_CATCH_CA_EXCEPT
    286   END_CATCH_CA_EXCEPT(hPattern)
    287 }
    288 
    289