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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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