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 37static 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 41extern const float root_pi_over_2; 42 43CA_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 61void 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 74int 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 174void 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 202void 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 236void 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 253int 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