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 41static void free_buffer(char* buffer, const char* allocname) 42{ 43 FREE(buffer); 44} 45 46int 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 53int 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 62int CA_ResetSyntax(CA_Syntax* syntax) 63{ 64 int rc; 65 rc = FST_ResetGrammar(syntax->synx); 66 return rc; 67} 68 69int CA_CompileSyntax(CA_Syntax *hSyntax) 70{ 71 return FST_PrepareContext(hSyntax->synx); 72} 73 74int 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 */ 93typedef struct 94{ 95 asr_int32_t image_format; 96 asr_int32_t image_size; 97 asr_int32_t sizes_signature; 98} 99context_image_header; 100 101int 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; 126CLEANUP: 127 if (fp) 128 pfclose (fp); 129 return 1; 130} 131 132int 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; 177CLEANUP: 178 return 0; 179} 180 181int 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; 208CLEANUP: 209 return 0; 210} 211 212/* from syn_file.c */ 213 214CA_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 230void 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 246CA_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 258unsigned int CA_ArbdataGetModelVersionID(CA_Arbdata* ca_arbdata) 259{ 260 return version_arbdata_models((srec_arbdata*)ca_arbdata); 261} 262 263int 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 274int 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 302void CA_FreeArbdata(CA_Arbdata* ca_arbdata) 303{ 304 free_buffer((char*)ca_arbdata, "srec.arbdata"); 305} 306/* from syn_basi.c */ 307 308int 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 316int CA_IsEnrollmentSyntax(CA_Syntax *hSyntax) 317{ 318 return FST_IsVoiceEnrollment( hSyntax->synx); 319} 320 321int 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 */ 333int 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 353void CA_ClearSyntaxForRecognizer(CA_Syntax *hSyntax, CA_Recog *hRecog) 354{ 355 int rc; 356 hSyntax = NULL; /* not used */ 357 rc = clear_grammars_for_recognition(hRecog->recm); 358 return; 359} 360