• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  AcousticModelsImpl.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 
21 #ifndef lint
22 #endif /* lint */
23 
24 #include "ESR_Session.h"
25 #include "IntArrayList.h"
26 #include "LCHAR.h"
27 #include "passert.h"
28 #include "plog.h"
29 #include "pmemory.h"
30 #include "SR_AcousticModels.h"
31 #include "SR_AcousticModelsImpl.h"
32 #include "pstdio.h"
33 #include "SR_EventLog.h"
34 
35 #define MTAG NULL
36 
37 #define CHKINTARRAY(rc, list, operation) rc = operation; \
38   if (rc!=ESR_SUCCESS) \
39   { \
40     IntArrayListDestroy(list); \
41     list = NULL; \
42     PLogError(ESR_rc2str(rc)); \
43     return rc; \
44   }
45 
46 
47 
48 
49 /**
50  * Initializes acoustic-models properties to default values.
51  *
52  * Replaces setup_acoustic_parameters()
53  */
SR_AcousticModels_ToSession()54 ESR_ReturnCode SR_AcousticModels_ToSession()
55 {
56   ESR_ReturnCode rc;
57 
58   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.dimen", 16));
59   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.skip", 5));
60   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.stay", 5));
61   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.whole_skip", 10));
62   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.whole_stay", 10));
63   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.durscale", 5));
64   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.frame_period", 10));
65   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.minvar", 1));
66   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Acoustic.maxvar", 64000));
67   CHKLOG(rc, ESR_SessionSetBoolIfEmpty("CREC.Acoustic.load_all_at_once", ESR_FALSE));
68   CHKLOG(rc, ESR_SessionSetLCHARIfEmpty("CREC.Acoustic.load_models", L("all")));
69   return ESR_SUCCESS;
70 CLEANUP:
71   return rc;
72 }
73 
74 /**
75  * Initializes pattern properties to default values.
76  *
77  * Replaces setup_pattern_parameters()
78  */
SR_AcousticModels_PatternToSession()79 ESR_ReturnCode SR_AcousticModels_PatternToSession()
80 {
81   ESR_ReturnCode rc;
82 
83   /* Old comment: Remember to keep "ca_pip.h" up to date with these parameters... */
84 
85   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.dimen", 16));
86   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.whole_dimen", 0));
87   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.start", 0));
88   CHKLOG(rc, ESR_SessionSetBoolIfEmpty("CREC.Pattern.chelt_imelda", ESR_FALSE));
89   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.vfrlimit", 100));
90   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.vfrthresh", 0));
91   CHKLOG(rc, ESR_SessionSetFloatIfEmpty("CREC.Pattern.mix_score_scale", 0.46f));
92   CHKLOG(rc, ESR_SessionSetFloatIfEmpty("CREC.Pattern.imelda_scale", 16));
93   CHKLOG(rc, ESR_SessionSetFloatIfEmpty("CREC.Pattern.uni_score_scale", 0.46f));
94   CHKLOG(rc, ESR_SessionSetFloatIfEmpty("CREC.Pattern.uni_score_offset", 0));
95   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.forget_speech", 40));
96   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.forget_background", 100));
97   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.rel_low", 15));
98   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.rel_high", 30));
99 
100   /* Gap: longest stop gap */
101   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.gap_period", 16));
102 
103   /* Click: longest isolated high-amplitude insert in silence */
104   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.click_period", 6));
105 
106   /* Breath: longest isolated medium amplitude */
107   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.breath_period", 50));
108   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.extend_annotation", 0));
109   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.min_initial_quiet_frames", 0));
110   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.min_annotation_frames", 0));
111   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.max_annotation_frames", 800));
112   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.min_segment_rel_c0", 800));
113   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.delete_leading_segments", 0));
114   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.leading_segment_min_frames", 0));
115   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.leading_segment_max_frames", 20));
116   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.leading_segment_min_silence_gap_frames", 20));
117   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.leading_segment_accept_if_not_found", 0));
118 
119 #if DO_SUBTRACTED_SEGMENTATION
120   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.snr_holdoff", 0));
121   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.min_acceptable_snr", 0));
122 #endif
123 
124   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.param", 0));
125   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.beep_size", 0));
126   CHKLOG(rc, ESR_SessionSetIntIfEmpty("CREC.Pattern.beep_threshold", 0));
127 
128   return ESR_SUCCESS;
129 
130 CLEANUP:
131   return rc;
132 }
133 
134 /**
135  * Populates legacy pattern parameters from the session.
136  *
137  * Replaces setup_pattern_parameters()
138  */
SR_AcousticModels_LoadLegacyPatternParameters(CA_PatInputParams * params)139 ESR_ReturnCode SR_AcousticModels_LoadLegacyPatternParameters(CA_PatInputParams* params)
140 {
141   ESR_ReturnCode rc;
142 
143   passert(params != NULL);
144   params->is_loaded = ESR_FALSE;
145   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.dimen", &params->dimen));
146   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.whole_dimen", &params->whole_dimen));
147   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.start", &params->feat_start));
148   CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.mix_score_scale", &params->mix_score_scale));
149   CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.imelda_scale", &params->imelda_scale));
150   CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.uni_score_scale", &params->uni_score_scale));
151   CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.uni_score_offset", &params->uni_score_offset));
152   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.forget_speech", &params->forget_speech));
153   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.forget_background", &params->forget_background));
154   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.rel_low", &params->rel_low));
155   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.rel_high", &params->rel_high));
156   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.gap_period", &params->gap_period));
157   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.click_period", &params->click_period));
158   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.breath_period", &params->breath_period));
159   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.extend_annotation", &params->extend_annotation));
160   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_initial_quiet_frames", &params->min_initial_quiet_frames));
161   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_annotation_frames", &params->min_annotation_frames));
162   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.max_annotation_frames", &params->max_annotation_frames));
163   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_segment_rel_c0", &params->min_segment_rel_c0));
164   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.delete_leading_segments", &params->delete_leading_segments));
165   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_min_frames", &params->leading_segment_min_frames));
166   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_max_frames", &params->leading_segment_max_frames));
167   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_min_silence_gap_frames", &params->leading_segment_min_silence_gap_frames));
168   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_accept_if_not_found", &params->leading_segment_accept_if_not_found));
169 
170 #if DO_SUBTRACTED_SEGMENTATION
171   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.snr_holdoff", &params->snr_holdoff));
172   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_acceptable_snr", &params->min_acceptable_snr));
173 #endif
174 
175   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.param", &params->param));
176   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.beep_size", &params->beep_size));
177   CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.beep_threshold", &params->beep_threshold));
178 
179   params->is_loaded = ESR_TRUE;
180   return ESR_SUCCESS;
181 
182 CLEANUP:
183   return rc;
184 }
185 
186 /**
187  * Generate legacy AcousticModels parameter structure from ESR_Session.
188  *
189  * @param params Resulting structure
190  */
SR_AcousticModels_GetLegacyParameters(CA_AcoustInputParams * params)191 ESR_ReturnCode SR_AcousticModels_GetLegacyParameters(CA_AcoustInputParams* params)
192 {
193   ESR_ReturnCode rc;
194   size_t maxLabel = MAX_LABEL;
195 
196   passert(params != NULL);
197   params->is_loaded = ESR_FALSE;
198   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.dimen", &params->dimen));
199   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.skip", &params->skip_penalty));
200   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.stay", &params->stay_penalty));
201   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.whole_skip", &params->whole_skip_penalty));
202   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.whole_stay", &params->whole_stay_penalty));
203   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.durscale", &params->dur_scale));
204   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.frame_period", &params->frame_period));
205   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.minvar", &params->min_var));
206   CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.maxvar", &params->max_var));
207   CHKLOG(rc, ESR_SessionGetBool("CREC.Acoustic.load_all_at_once", &params->load_all));
208   CHKLOG(rc, ESR_SessionGetLCHAR("CREC.Acoustic.load_models", params->load_models, &maxLabel));
209   params->is_loaded = ESR_TRUE;
210   return ESR_SUCCESS;
211 CLEANUP:
212   return rc;
213 }
214 
LogArbdataVersion(unsigned int ver)215 int LogArbdataVersion(unsigned int ver)
216 {
217   ESR_ReturnCode rc;
218   SR_EventLog* eventLog;
219   size_t osi_log_level = 0;
220   ESR_BOOL exists = ESR_FALSE;
221 
222   CHKLOG(rc, ESR_SessionExists(&exists));
223   if (exists)
224   {
225     rc = ESR_SessionGetProperty(L("eventlog"), (void **)&eventLog, TYPES_SR_EVENTLOG);
226     if ((rc != ESR_NO_MATCH_ERROR) && (rc != ESR_SUCCESS))
227     {
228       PLogError(ESR_rc2str(rc));
229       goto CLEANUP;
230     }
231     if (eventLog)
232     {
233       rc = ESR_SessionGetSize_t(L("SREC.Recognizer.osi_log_level"), &osi_log_level);
234       if ((rc != ESR_NO_MATCH_ERROR) && (rc != ESR_SUCCESS))
235       {
236         PLogError(ESR_rc2str(rc));
237         goto CLEANUP;
238       }
239       if (osi_log_level > 0)
240       {
241         rc = SR_EventLogTokenSize_t(eventLog, L("VER"), ver);
242         rc = SR_EventLogEvent(eventLog, L("ESRarbd"));
243       }
244     }
245   }
246 CLEANUP:
247   return 0;
248 }
249 
250 
251 
SR_AcousticModelsLoad(const LCHAR * filename,SR_AcousticModels ** self)252 ESR_ReturnCode SR_AcousticModelsLoad(const LCHAR* filename, SR_AcousticModels** self)
253 {
254   int use_image;
255   LCHAR arbfile[P_PATH_MAX];
256   CA_AcoustInputParams* acousticParams;
257   CA_Acoustic* acoustic;
258   LCHAR modelFilename[P_PATH_MAX];
259   SR_AcousticModelsImpl* impl;
260   size_t len;
261   ESR_ReturnCode rc;
262 
263   impl = NEW(SR_AcousticModelsImpl, MTAG);
264   if (impl == NULL)
265   {
266     PLogError(L("ESR_OUT_OF_MEMORY"));
267     return ESR_OUT_OF_MEMORY;
268   }
269   impl->Interface.destroy = &SR_AcousticModels_Destroy;
270   impl->Interface.save = &SR_AcousticModels_Save;
271   impl->Interface.setParameter = &SR_AcousticModels_SetParameter;
272   impl->Interface.getParameter = &SR_AcousticModels_GetParameter;
273   impl->Interface.getCount = &SR_AcousticModels_GetCount;
274   impl->Interface.getID = &SR_AcousticModels_GetID;
275   impl->Interface.setID = &SR_AcousticModels_SetID;
276   impl->Interface.getArbdata = &SR_AcousticModels_GetArbdata;
277   impl->setupPattern = &SR_AcousticModels_SetupPattern;
278   impl->unsetupPattern = &SR_AcousticModels_UnsetupPattern;
279   impl->getLegacyParameters = &SR_AcousticModels_GetLegacyParameters;
280   impl->parameters = NULL;
281   impl->pattern = NULL;
282   impl->acoustic = NULL;
283   impl->arbdata = NULL;
284   impl->contents = NULL;
285   impl->size = 0;
286   acousticParams = NULL;
287   acoustic = NULL;
288 
289   rc = SR_AcousticModels_PatternToSession();
290   if (rc != ESR_SUCCESS)
291   {
292     PLogError(ESR_rc2str(rc));
293     goto CLEANUP;
294   }
295   rc = SR_AcousticModels_ToSession();
296   if (rc != ESR_SUCCESS)
297   {
298     PLogError(ESR_rc2str(rc));
299     goto CLEANUP;
300   }
301   rc = ArrayListCreate(&impl->acoustic);
302   if (rc != ESR_SUCCESS)
303   {
304     PLogError(ESR_rc2str(rc));
305     goto CLEANUP;
306   }
307 
308   acousticParams = CA_AllocateAcousticParameters();
309   if (acousticParams == NULL)
310   {
311     rc = ESR_OUT_OF_MEMORY;
312     PLogError(ESR_rc2str(rc));
313     goto CLEANUP;
314   }
315   rc = impl->getLegacyParameters(acousticParams);
316   if (rc != ESR_SUCCESS)
317   {
318     PLogError(ESR_rc2str(rc));
319     goto CLEANUP;
320   }
321 
322   rc = ESR_SessionGetInt(L("cmdline.use_image"), &use_image);
323   if (rc != ESR_SUCCESS)
324   {
325     PLogError(ESR_rc2str(rc));
326     goto CLEANUP;
327   }
328 
329   while (ESR_TRUE)
330   {
331     int i;
332     // skip space to next relative pathname
333     while (LISSPACE(*filename)) filename++;
334     if (*filename == L('\0')) break;
335     // copy the relative pathname
336     for (i = 0; *filename != L('\0') && !LISSPACE(*filename); i++)
337     {
338       modelFilename[i] = *filename++;
339     }
340     modelFilename[i] = L('\0');
341 
342     if (LSTRLEN(modelFilename) == 0 || modelFilename[0] == '#')
343       continue;
344     rc = lstrtrim(modelFilename);
345     if (rc != ESR_SUCCESS)
346     {
347       PLogError(ESR_rc2str(rc));
348       goto CLEANUP;
349     }
350 
351     len = P_PATH_MAX;
352     CHKLOG(rc, ESR_SessionPrefixWithBaseDirectory(modelFilename, &len));
353     acoustic = CA_AllocateAcoustic();
354     if (acoustic == NULL)
355     {
356       rc = ESR_OUT_OF_MEMORY;
357       PLogError(ESR_rc2str(rc));
358       goto CLEANUP;
359     }
360     if (use_image == 1)
361     {
362       rc = ESR_INVALID_STATE;
363       PLogError(ESR_rc2str(rc));
364       goto CLEANUP;
365     }
366     else if (use_image == 2)
367     {
368       if (!CA_LoadAcousticSub(acoustic, modelFilename, 0))
369       {
370         rc = ESR_INVALID_STATE;
371         PLogError(ESR_rc2str(rc));
372         goto CLEANUP;
373       }
374     }
375     else
376     {
377             /* TODO: Is this being used? */
378       if (!CA_LoadAcousticSub(acoustic, modelFilename, acousticParams))
379       {
380         rc = ESR_INVALID_STATE;
381         PLogError(ESR_rc2str(rc));
382         goto CLEANUP;
383       }
384     }
385     rc = ArrayListAdd(impl->acoustic, acoustic);
386     if (rc != ESR_SUCCESS)
387     {
388       PLogError(ESR_rc2str(rc));
389       goto CLEANUP;
390     }
391 
392   }
393   len = P_PATH_MAX;
394   rc = ESR_SessionGetLCHAR(L("cmdline.arbfile"), (LCHAR*) & arbfile, &len);
395   if (rc != ESR_SUCCESS)
396   {
397     PLogError(ESR_rc2str(rc));
398     goto CLEANUP;
399   }
400   len = P_PATH_MAX;
401   CHKLOG(rc, ESR_SessionPrefixWithBaseDirectory(arbfile, &len));
402   impl->arbdata = CA_LoadArbdata(arbfile);
403   if (impl->arbdata == NULL)
404   {
405     rc = ESR_OUT_OF_MEMORY;
406     goto CLEANUP;
407   }
408   len = CA_ArbdataGetModelVersionID(impl->arbdata);
409   LogArbdataVersion(len);
410 
411   CA_FreeAcousticParameters(acousticParams);
412   *self = (SR_AcousticModels*) impl;
413 
414   return ESR_SUCCESS;
415 CLEANUP:
416   if (acousticParams != NULL)
417     CA_FreeAcousticParameters(acousticParams);
418   impl->Interface.destroy(&impl->Interface);
419   return rc;
420 }
421 
SR_AcousticModels_Destroy(SR_AcousticModels * self)422 ESR_ReturnCode SR_AcousticModels_Destroy(SR_AcousticModels* self)
423 {
424   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
425   CA_Acoustic* acoustic;
426   ESR_ReturnCode rc;
427   size_t size, i;
428 
429   if (impl->pattern != NULL)
430   {
431     CHKLOG(rc, impl->acoustic->getSize(impl->acoustic, &size));
432     for (i = 0; i < size; ++i)
433     {
434       CHKLOG(rc, impl->acoustic->get(impl->acoustic, i, (void **)&acoustic));
435       CA_ClearPatternForAcoustic(impl->pattern, acoustic);
436     }
437     CA_UnloadPattern(impl->pattern);
438     CA_FreePattern(impl->pattern);
439     impl->pattern = NULL;
440   }
441 
442   if (impl->acoustic != NULL)
443   {
444     CHKLOG(rc, impl->acoustic->getSize(impl->acoustic, &size));
445     for (i = 0; i < size; ++i)
446     {
447       CHKLOG(rc, impl->acoustic->get(impl->acoustic, 0, (void **)&acoustic));
448       CHKLOG(rc, impl->acoustic->removeAtIndex(impl->acoustic, 0));
449 
450       /* Free acoustic models */
451       CA_UnloadAcoustic(acoustic);
452       CA_FreeAcoustic(acoustic);
453     }
454 
455     CHKLOG(rc, impl->acoustic->destroy(impl->acoustic));
456     impl->acoustic = NULL;
457   }
458 
459   if (impl->arbdata != NULL)
460   {
461     CA_FreeArbdata(impl->arbdata);
462     impl->arbdata = NULL;
463   }
464 
465   FREE(impl);
466   return ESR_SUCCESS;
467 CLEANUP:
468   return rc;
469 }
470 
SR_AcousticModels_Save(SR_AcousticModels * self,const LCHAR * filename)471 ESR_ReturnCode SR_AcousticModels_Save(SR_AcousticModels* self, const LCHAR* filename)
472 {
473   /*SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;*/
474 
475   /* CA_WriteAcousticImage(impl->acoustic, filename, 0); */
476   return ESR_SUCCESS;
477 }
478 
SR_AcousticModels_SetParameter(SR_AcousticModels * self,const LCHAR * key,LCHAR * value)479 ESR_ReturnCode SR_AcousticModels_SetParameter(SR_AcousticModels* self, const LCHAR* key, LCHAR* value)
480 {
481   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
482   LCHAR* temp;
483   ESR_ReturnCode rc;
484 
485   rc = HashMapGet(impl->parameters, key, (void **)&temp);
486   if (rc == ESR_SUCCESS)
487   {
488     /* Key already exists, remove old value if necessary */
489     if (LSTRCMP(temp, value) == 0)
490       return ESR_SUCCESS;
491     CHKLOG(rc, HashMapRemove(impl->parameters, key));
492     FREE(temp);
493   }
494   else if (rc != ESR_NO_MATCH_ERROR)
495   {
496     PLogError(ESR_rc2str(rc));
497     goto CLEANUP;
498   }
499 
500   /* Allocate and put new key */
501   temp = MALLOC(sizeof(LCHAR) * (LSTRLEN(value) + 1), MTAG);
502   if (temp == NULL)
503   {
504     rc = ESR_OUT_OF_MEMORY;
505     PLogError(ESR_rc2str(rc));
506     goto CLEANUP;
507   }
508   CHKLOG(rc, impl->parameters->put(impl->parameters, key, temp));
509   return ESR_SUCCESS;
510 CLEANUP:
511   FREE(temp);
512   return rc;
513 }
514 
SR_AcousticModels_GetParameter(SR_AcousticModels * self,const LCHAR * key,LCHAR * value,size_t * len)515 ESR_ReturnCode SR_AcousticModels_GetParameter(SR_AcousticModels* self, const LCHAR* key, LCHAR* value, size_t* len)
516 {
517   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
518   LCHAR* temp;
519   ESR_ReturnCode rc;
520 
521   rc = HashMapGet(impl->parameters, key, (void **)&temp);
522   if (rc == ESR_NO_MATCH_ERROR)
523     CHKLOG(rc, ESR_SessionGetLCHAR(key, value, len));
524   if (rc != ESR_SUCCESS)
525   {
526     PLogError(ESR_rc2str(rc));
527     return rc;
528   }
529   if (LSTRLEN(temp) + 1 > *len)
530   {
531     *len = LSTRLEN(temp) + 1;
532     PLogError(L("ESR_BUFFER_OVERFLOW"));
533     return ESR_BUFFER_OVERFLOW;
534   }
535   *len = LSTRLEN(temp) + 1;
536   LSTRCPY(value, temp);
537   return ESR_SUCCESS;
538 CLEANUP:
539   return rc;
540 }
541 
SR_AcousticModels_GetCount(SR_AcousticModels * self,size_t * size)542 ESR_ReturnCode SR_AcousticModels_GetCount(SR_AcousticModels* self, size_t* size)
543 {
544   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
545   ESR_ReturnCode rc;
546 
547   CHKLOG(rc, ArrayListGetSize(impl->acoustic, size));
548   return ESR_SUCCESS;
549 CLEANUP:
550   return rc;
551 }
552 
SR_AcousticModels_GetID(SR_AcousticModels * self,size_t index,SR_AcousticModelID * id,size_t * size)553 ESR_ReturnCode SR_AcousticModels_GetID(SR_AcousticModels* self, size_t index,
554                                        SR_AcousticModelID* id, size_t* size)
555 {
556   /* TODO: complete */
557   return ESR_SUCCESS;
558 }
559 
SR_AcousticModels_SetID(SR_AcousticModels * self,size_t index,SR_AcousticModelID * id)560 ESR_ReturnCode SR_AcousticModels_SetID(SR_AcousticModels* self, size_t index,
561                                        SR_AcousticModelID* id)
562 {
563   /* TODO: complete */
564   return ESR_SUCCESS;
565 }
566 
SR_AcousticModels_GetArbdata(SR_AcousticModels * self)567 void* SR_AcousticModels_GetArbdata(SR_AcousticModels* self)
568 {
569 	SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*)self;
570 	return impl? (void*)impl->arbdata : NULL;
571 }
572 
573 /**
574  * When AcousticModels are associated with a Recognizer, they initialize their
575  * Pattern objects using that Recognizer.
576  *
577  * @param self SR_AcousticModels handle
578  * @param recognizer The recognizer
579  */
SR_AcousticModels_SetupPattern(SR_AcousticModels * self,SR_Recognizer * recognizer)580 ESR_ReturnCode SR_AcousticModels_SetupPattern(SR_AcousticModels* self,
581     SR_Recognizer* recognizer)
582 {
583   CA_PatInputParams* patternParams = NULL;
584   LCHAR mulname[P_PATH_MAX];
585   LCHAR ldaname[P_PATH_MAX];
586   SR_RecognizerImpl* recog;
587   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
588   CA_Acoustic* acoustic;
589   size_t i, size, len;
590   int dimen;
591   ESR_ReturnCode rc;
592   ESR_BOOL isPatternLoaded = ESR_FALSE;
593 
594   if (recognizer == NULL)
595   {
596     PLogError(L("ESR_INVALID_ARGUMENT"));
597     return ESR_INVALID_ARGUMENT;
598   }
599   recog = (SR_RecognizerImpl*) recognizer;
600 
601   impl->pattern = CA_AllocatePattern();
602   if (impl->pattern == NULL)
603   {
604     rc = ESR_OUT_OF_MEMORY;
605     PLogError(ESR_rc2str(rc));
606     goto CLEANUP;
607   }
608   patternParams = CA_AllocatePatternParameters();
609   if (patternParams == NULL)
610   {
611     rc = ESR_OUT_OF_MEMORY;
612     PLogError(ESR_rc2str(rc));
613     goto CLEANUP;
614   }
615 
616   CHKLOG(rc, SR_AcousticModels_LoadLegacyPatternParameters(patternParams));
617   dimen = CA_GetFrontendUtteranceDimension(recog->frontend);
618 
619   LSTRCPY(mulname, L(""));
620 
621   len = P_PATH_MAX;
622   CHKLOG(rc, ESR_SessionGetLCHAR(L("cmdline.lda"), (LCHAR*) &ldaname, &len));
623   len = P_PATH_MAX;
624   CHKLOG(rc, ESR_SessionPrefixWithBaseDirectory(ldaname, &len));
625 
626   CA_LoadPattern(impl->pattern, patternParams, dimen, mulname, ldaname);
627   isPatternLoaded = ESR_TRUE;
628   CHKLOG(rc, impl->acoustic->getSize(impl->acoustic, &size));
629   for (i = 0; i < size; ++i)
630   {
631     CHKLOG(rc, impl->acoustic->get(impl->acoustic, i, (void **)&acoustic));
632     CA_SetupPatternForAcoustic(impl->pattern, acoustic);
633   }
634   CA_FreePatternParameters(patternParams);
635   return ESR_SUCCESS;
636 CLEANUP:
637   if (impl->pattern != NULL)
638   {
639     if (isPatternLoaded == ESR_TRUE)
640       CA_UnloadPattern(impl->pattern);
641     CA_FreePattern(impl->pattern);
642   }
643   if (patternParams != NULL)
644     CA_FreePatternParameters(patternParams);
645   return rc;
646 }
647 
648 /**
649  * When AcousticModels are deassociated with a Recognizer, they deinitialize their
650  * Pattern objects.
651  *
652  * @param self SR_AcousticModels handle
653  */
SR_AcousticModels_UnsetupPattern(SR_AcousticModels * self)654 ESR_ReturnCode SR_AcousticModels_UnsetupPattern(SR_AcousticModels* self)
655 {
656   SR_AcousticModelsImpl* impl = (SR_AcousticModelsImpl*) self;
657   CA_Acoustic* acoustic;
658   size_t i, size;
659   ESR_ReturnCode rc;
660 
661   CHKLOG(rc, impl->acoustic->getSize(impl->acoustic, &size));
662   for (i = 0; i < size; ++i)
663   {
664     CHKLOG(rc, impl->acoustic->get(impl->acoustic, i, (void **)&acoustic));
665     CA_ClearPatternForAcoustic(impl->pattern, acoustic);
666   }
667   CA_UnloadPattern(impl->pattern);
668   CA_FreePattern(impl->pattern);
669   impl->pattern = NULL;
670   return ESR_SUCCESS;
671 CLEANUP:
672   return rc;
673 }
674