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
free_buffer(char * buffer,const char * allocname)41 static void free_buffer(char* buffer, const char* allocname)
42 {
43 FREE(buffer);
44 }
45
CA_AttachArbdataToSyntax(CA_Syntax * syntax,CA_Arbdata * allotree)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
CA_AddWordToSyntax(CA_Syntax * syntax,const char * slot,const char * phrase,const char * pronunciation,const int weight)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
CA_ResetSyntax(CA_Syntax * syntax)62 int CA_ResetSyntax(CA_Syntax* syntax)
63 {
64 int rc;
65 rc = FST_ResetGrammar(syntax->synx);
66 return rc;
67 }
68
CA_CompileSyntax(CA_Syntax * hSyntax)69 int CA_CompileSyntax(CA_Syntax *hSyntax)
70 {
71 return FST_PrepareContext(hSyntax->synx);
72 }
73
CA_LoadSyntaxAsExtensible(CA_Syntax * hSyntax,char * synbase,int num_words_to_add)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
CA_LoadSyntaxFromImage(CA_Syntax * hSyntax,const LCHAR * filename)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
CA_DumpSyntax(CA_Syntax * hSyntax,const char * basename)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
CA_DumpSyntaxAsImage(CA_Syntax * hSyntax,const char * imagename,int version_number)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
CA_AllocateSyntax(void)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
CA_FreeSyntax(CA_Syntax * hSyntax)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
CA_LoadArbdata(const char * filename)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
CA_ArbdataGetModelVersionID(CA_Arbdata * ca_arbdata)258 unsigned int CA_ArbdataGetModelVersionID(CA_Arbdata* ca_arbdata)
259 {
260 return version_arbdata_models((srec_arbdata*)ca_arbdata);
261 }
262
CA_ArbdataGetModelIdsForPron(CA_Arbdata * ca_arbdata,const char * pronunciation,int pronunciation_len,modelID * pmodelIds)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
CA_ArbdataGetModelIdsForPIC(CA_Arbdata * ca_arbdata,const char lphon,const char cphon,const char rphon)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
CA_FreeArbdata(CA_Arbdata * ca_arbdata)302 void CA_FreeArbdata(CA_Arbdata* ca_arbdata)
303 {
304 free_buffer((char*)ca_arbdata, "srec.arbdata");
305 }
306 /* from syn_basi.c */
307
CA_SetupSyntaxForRecognizer(CA_Syntax * hSyntax,CA_Recog * hRecog)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
CA_IsEnrollmentSyntax(CA_Syntax * hSyntax)316 int CA_IsEnrollmentSyntax(CA_Syntax *hSyntax)
317 {
318 return FST_IsVoiceEnrollment( hSyntax->synx);
319 }
320
CA_CeilingSyntaxForRecognizer(CA_Syntax * hSyntax,CA_Recog * hRecog)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 */
CA_CheckTranscription(CA_Syntax * hSyntax,const char * transcription,int no)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
CA_ClearSyntaxForRecognizer(CA_Syntax * hSyntax,CA_Recog * hRecog)353 void 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