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", ¶ms->dimen));
146 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.whole_dimen", ¶ms->whole_dimen));
147 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.start", ¶ms->feat_start));
148 CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.mix_score_scale", ¶ms->mix_score_scale));
149 CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.imelda_scale", ¶ms->imelda_scale));
150 CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.uni_score_scale", ¶ms->uni_score_scale));
151 CHKLOG(rc, ESR_SessionGetFloat("CREC.Pattern.uni_score_offset", ¶ms->uni_score_offset));
152 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.forget_speech", ¶ms->forget_speech));
153 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.forget_background", ¶ms->forget_background));
154 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.rel_low", ¶ms->rel_low));
155 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.rel_high", ¶ms->rel_high));
156 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.gap_period", ¶ms->gap_period));
157 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.click_period", ¶ms->click_period));
158 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.breath_period", ¶ms->breath_period));
159 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.extend_annotation", ¶ms->extend_annotation));
160 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_initial_quiet_frames", ¶ms->min_initial_quiet_frames));
161 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_annotation_frames", ¶ms->min_annotation_frames));
162 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.max_annotation_frames", ¶ms->max_annotation_frames));
163 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_segment_rel_c0", ¶ms->min_segment_rel_c0));
164 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.delete_leading_segments", ¶ms->delete_leading_segments));
165 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_min_frames", ¶ms->leading_segment_min_frames));
166 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_max_frames", ¶ms->leading_segment_max_frames));
167 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_min_silence_gap_frames", ¶ms->leading_segment_min_silence_gap_frames));
168 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.leading_segment_accept_if_not_found", ¶ms->leading_segment_accept_if_not_found));
169
170 #if DO_SUBTRACTED_SEGMENTATION
171 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.snr_holdoff", ¶ms->snr_holdoff));
172 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.min_acceptable_snr", ¶ms->min_acceptable_snr));
173 #endif
174
175 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.param", ¶ms->param));
176 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.beep_size", ¶ms->beep_size));
177 CHKLOG(rc, ESR_SessionGetInt("CREC.Pattern.beep_threshold", ¶ms->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", ¶ms->dimen));
199 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.skip", ¶ms->skip_penalty));
200 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.stay", ¶ms->stay_penalty));
201 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.whole_skip", ¶ms->whole_skip_penalty));
202 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.whole_stay", ¶ms->whole_stay_penalty));
203 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.durscale", ¶ms->dur_scale));
204 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.frame_period", ¶ms->frame_period));
205 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.minvar", ¶ms->min_var));
206 CHKLOG(rc, ESR_SessionGetInt("CREC.Acoustic.maxvar", ¶ms->max_var));
207 CHKLOG(rc, ESR_SessionGetBool("CREC.Acoustic.load_all_at_once", ¶ms->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