1 /*---------------------------------------------------------------------------* 2 * syn_srec.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 #ifndef _RTT 32 #include "duk_io.h" 33 #endif 34 35 #include "simapi.h" 36 #include "pendian.h" 37 #include "portable.h" 38 #include "srec_context.h" 39 #include "ESR_Session.h" 40 41 static void free_buffer(char* buffer, const char* allocname) 42 { 43 FREE(buffer); 44 } 45 46 int CA_AttachArbdataToSyntax(CA_Syntax* syntax, CA_Arbdata* allotree) 47 { 48 int rc; 49 rc = FST_AttachArbdata(syntax->synx, (srec_arbdata*)allotree); 50 return rc; 51 } 52 53 int CA_AddWordToSyntax(CA_Syntax* syntax, const char* slot, 54 const char *phrase, const char* pronunciation, 55 const int weight) 56 { 57 int rc; 58 rc = FST_AddWordToGrammar(syntax->synx, slot, phrase, pronunciation, weight); 59 return rc; 60 } 61 62 int CA_ResetSyntax(CA_Syntax* syntax) 63 { 64 int rc; 65 rc = FST_ResetGrammar(syntax->synx); 66 return rc; 67 } 68 69 int CA_CompileSyntax(CA_Syntax *hSyntax) 70 { 71 return FST_PrepareContext(hSyntax->synx); 72 } 73 74 int CA_LoadSyntaxAsExtensible(CA_Syntax *hSyntax, /*CA_Arbdata* arbdata,*/ 75 char *synbase, int num_words_to_add) 76 { 77 int rc; 78 TRY_CA_EXCEPT 79 ASSERT(hSyntax); 80 if (hSyntax->setup_count > 0) 81 SERVICE_ERROR(SYNTAX_ALREADY_SETUP); 82 83 rc = FST_LoadContext(synbase, &hSyntax->synx, num_words_to_add); 84 return rc ? 1 : 0; 85 BEG_CATCH_CA_EXCEPT 86 END_CATCH_CA_EXCEPT(hSyntax) 87 } 88 89 /* this belongs part of the srec_context! */ 90 /** 91 * @todo document 92 */ 93 typedef struct 94 { 95 asr_int32_t image_format; 96 asr_int32_t image_size; 97 asr_int32_t sizes_signature; 98 } 99 context_image_header; 100 101 int CA_LoadSyntaxFromImage(CA_Syntax *hSyntax, const LCHAR* filename) 102 { 103 int result; 104 PFile* fp = NULL; 105 ESR_BOOL isLittleEndian; 106 107 /* 108 #if __BYTE_ORDER==__LITTLE_ENDIAN 109 isLittleEndian = ESR_TRUE; 110 #else 111 isLittleEndian = ESR_FALSE; 112 #endif 113 */ 114 isLittleEndian = ESR_TRUE; 115 116 fp = pfopen ( filename, L("rb") ); 117 /* CHKLOG(rc, PFileSystemCreatePFile(filename, isLittleEndian, &fp)); 118 CHKLOG(rc, PFileOpen(fp, L("rb")));*/ 119 120 if ( fp == NULL ) 121 goto CLEANUP; 122 123 result = FST_LoadContextFromImage(&hSyntax->synx, fp); 124 pfclose(fp); 125 return result ? 1 : 0; 126 CLEANUP: 127 if (fp) 128 pfclose (fp); 129 return 1; 130 } 131 132 int CA_DumpSyntax(CA_Syntax* hSyntax, const char* basename) 133 { 134 int result, totrc = 0; 135 PFile* fp; 136 char buf[256]; 137 /*ESR_ReturnCode rc;*/ 138 139 sprintf(buf, "%s.PCLG.txt", basename); 140 fp = pfopen ( buf, L("wb") ); 141 /* CHKLOG(rc, PFileSystemCreatePFile(buf, ESR_TRUE, &fp)); 142 CHKLOG(rc, PFileOpen(fp, L("wb")));*/ 143 144 if ( fp == NULL ) 145 goto CLEANUP; 146 147 result = FST_DumpGraph(hSyntax->synx, fp); 148 pfclose(fp); 149 totrc += result; 150 151 sprintf(buf, "%s.map", basename); 152 fp = pfopen ( buf, L("wb") ); 153 /* CHKLOG(rc, PFileSystemCreatePFile(buf, ESR_TRUE, &fp)); 154 CHKLOG(rc, PFileOpen(fp, L("wb")));*/ 155 156 if ( fp == NULL ) 157 goto CLEANUP; 158 159 result = FST_DumpWordMap(fp, hSyntax->synx->olabels); 160 pfclose(fp); 161 totrc += result; 162 163 sprintf(buf, "%s.Grev2.det.txt", basename); 164 fp = pfopen ( buf, L("wb") ); 165 /* CHKLOG(rc, PFileSystemCreatePFile(buf, ESR_TRUE, &fp)); 166 CHKLOG(rc, PFileOpen(fp, L("wb")));*/ 167 168 if ( fp == NULL ) 169 goto CLEANUP; 170 171 if (0) 172 result = FST_DumpReverseWordGraph(hSyntax->synx, fp); 173 pfclose(fp); 174 totrc += result; 175 176 return totrc ? 1 : 0; 177 CLEANUP: 178 return 0; 179 } 180 181 int CA_DumpSyntaxAsImage(CA_Syntax* hSyntax, const char* imagename, int version_number) 182 { 183 int result; 184 PFile* fp; 185 /*ESR_ReturnCode rc;*/ 186 ESR_BOOL isLittleEndian; 187 188 isLittleEndian = ESR_TRUE; 189 190 fp = pfopen ( imagename, L("wb") ); 191 /* CHKLOG(rc, PFileSystemCreatePFile(imagename, isLittleEndian, &fp)); 192 CHKLOG(rc, PFileOpen(fp, L("wb")));*/ 193 194 if ( fp == NULL ) 195 goto CLEANUP; 196 197 if (version_number == 2) 198 { 199 result = FST_DumpContextAsImageV2(hSyntax->synx, fp); 200 } 201 else 202 { 203 PLogError("invalid version number %d\n", version_number); 204 result = FST_FAILED_ON_INVALID_ARGS; 205 } 206 pfclose(fp); 207 return result ? 1 : 0; 208 CLEANUP: 209 return 0; 210 } 211 212 /* from syn_file.c */ 213 214 CA_Syntax *CA_AllocateSyntax(void) 215 { 216 CA_Syntax *hSyntax = NULL; 217 TRY_CA_EXCEPT 218 hSyntax = (CA_Syntax *) CALLOC_CLR(1, sizeof(CA_Syntax), "ca.hSyntax"); 219 hSyntax->has_groups = False; 220 hSyntax->has_rules = False; 221 hSyntax->setup_count = 0; 222 hSyntax->ca_rtti = CA_SYNTAX_SIGNATURE; 223 hSyntax->synx = 0; 224 return (hSyntax); 225 226 BEG_CATCH_CA_EXCEPT 227 END_CATCH_CA_EXCEPT(hSyntax) 228 } 229 230 void CA_FreeSyntax(CA_Syntax *hSyntax) 231 { 232 TRY_CA_EXCEPT 233 ASSERT(hSyntax); 234 if (hSyntax->setup_count > 0) 235 SERVICE_ERROR(SYNTAX_ALREADY_SETUP); 236 /* todo: free hSyntax internals */ 237 FST_UnloadContext((srec_context*)(hSyntax->synx)); 238 hSyntax->synx = 0; 239 FREE((char *) hSyntax); 240 return; 241 242 BEG_CATCH_CA_EXCEPT 243 END_CATCH_CA_EXCEPT(hSyntax) 244 } 245 246 CA_Arbdata* CA_LoadArbdata(const char* filename) 247 { 248 CA_Arbdata* ca_arbdata = NULL; 249 int rc; 250 251 #ifdef SREC_ENGINE_VERBOSE_LOGGING 252 PLogMessage(L("CA_LoadArbdata ... from file %s"), filename); 253 #endif 254 rc = read_arbdata_from_stream((srec_arbdata**) & ca_arbdata, (char *)filename, 0); 255 return ca_arbdata; 256 } 257 258 unsigned int CA_ArbdataGetModelVersionID(CA_Arbdata* ca_arbdata) 259 { 260 return version_arbdata_models((srec_arbdata*)ca_arbdata); 261 } 262 263 int CA_ArbdataGetModelIdsForPron(CA_Arbdata* ca_arbdata, 264 const char* pronunciation, /* WB assumed at the edges */ 265 int pronunciation_len, 266 modelID* pmodelIds) 267 { 268 srec_arbdata *allotree = (srec_arbdata*)ca_arbdata; 269 return get_modelids_for_pron( allotree, 270 pronunciation, pronunciation_len, 271 pmodelIds); 272 } 273 274 int CA_ArbdataGetModelIdsForPIC(CA_Arbdata* ca_arbdata, const char lphon, 275 const char cphon, 276 const char rphon) 277 { 278 phonemeID lphon_ID, cphon_ID, rphon_ID; 279 srec_arbdata *allotree = (srec_arbdata*)ca_arbdata; 280 if(lphon==WBPHONEME_CODE){ 281 #if !USE_WWTRIPHONE 282 lphon_ID = (phonemeID)allotree->phoneme_index[ SILENCE_CODE]; 283 #else 284 lphon_ID = WBPHONEME_CODE; //(phonemeID)allotree->phoneme_index[ WBPHONEME_CODE]; 285 #endif 286 } 287 else 288 lphon_ID = (phonemeID)allotree->phoneme_index[(const unsigned char)lphon]; 289 cphon_ID = (phonemeID)allotree->phoneme_index[(const unsigned char)cphon]; 290 if(rphon==WBPHONEME_CODE){ 291 #if !USE_WWTRIPHONE 292 rphon_ID = (phonemeID)allotree->phoneme_index[ SILENCE_CODE]; 293 #else 294 rphon_ID = WBPHONEME_CODE; //(phonemeID)allotree->phoneme_index[ WBPHONEME_CODE]; 295 #endif 296 } 297 else 298 rphon_ID = (phonemeID)allotree->phoneme_index[(const unsigned char)rphon]; 299 return (modelID)get_modelid_for_pic(allotree, lphon_ID, cphon_ID, rphon_ID); 300 } 301 302 void CA_FreeArbdata(CA_Arbdata* ca_arbdata) 303 { 304 free_buffer((char*)ca_arbdata, "srec.arbdata"); 305 } 306 /* from syn_basi.c */ 307 308 int CA_SetupSyntaxForRecognizer(CA_Syntax *hSyntax, CA_Recog *hRecog) 309 { 310 int rc; 311 const char* rule = "ROOT"; 312 rc = activate_grammar_for_recognition(hRecog->recm, hSyntax->synx, rule); 313 return rc; 314 } 315 316 int CA_IsEnrollmentSyntax(CA_Syntax *hSyntax) 317 { 318 return FST_IsVoiceEnrollment( hSyntax->synx); 319 } 320 321 int CA_CeilingSyntaxForRecognizer(CA_Syntax *hSyntax, CA_Recog *hRecog) 322 { 323 if(!hSyntax || !hRecog) 324 return 1; 325 if(!hSyntax->synx || !hRecog->recm) 326 return 1; 327 hSyntax->synx->max_searchable_nodes = hRecog->recm->max_fsm_nodes; 328 hSyntax->synx->max_searchable_arcs = hRecog->recm->max_fsm_arcs; 329 return 0; 330 } 331 332 /* checks if the phrase is in the grammar node, 0=in 1=not.in */ 333 int CA_CheckTranscription(CA_Syntax *hSyntax, const char *transcription, int no) 334 { 335 int rc; 336 char literal[512]; 337 size_t max_literal_len = 512; 338 srec_context* context = hSyntax->synx; 339 rc = FST_CheckPath(context, transcription, literal, max_literal_len); 340 if (rc == 0) strcpy((char*)transcription, literal); 341 return rc; 342 } 343 344 /*---------------------------------------------------------------------------* 345 * * 346 * do nothing functions * 347 * * 348 *---------------------------------------------------------------------------*/ 349 350 /* from syn_basi.c */ 351 352 353 void CA_ClearSyntaxForRecognizer(CA_Syntax *hSyntax, CA_Recog *hRecog) 354 { 355 int rc; 356 (void) hSyntax; /* not used */ 357 rc = clear_grammars_for_recognition(hRecog->recm); 358 return; 359 } 360