Julius 4.2
|
00001 00018 /* 00019 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00020 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00021 * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology 00022 * All rights reserved 00023 */ 00024 00025 #include <julius/julius.h> 00026 00027 #ifdef ENABLE_PLUGIN 00028 00029 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__MINGW32__) 00030 #include <windows.h> 00031 #else 00032 #include <dirent.h> 00033 #endif 00034 #include <stdarg.h> 00035 00040 static char *plugin_suffix = PLUGIN_SUFFIX; 00041 00046 static char *plugin_function_namelist[] = PLUGIN_FUNCTION_NAMELIST; 00047 00048 00049 /**************************************************************/ 00050 00051 #if defined(_WIN32) && !defined(__CYGWIN32__) 00052 00057 static const char* dlerror() 00058 { 00059 static char szMsgBuf[256]; 00060 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 00061 NULL, 00062 GetLastError(), 00063 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00064 szMsgBuf, 00065 sizeof szMsgBuf, 00066 NULL); 00067 return szMsgBuf; 00068 } 00069 #endif 00070 00071 /**************************************************************/ 00072 static int 00073 plugin_namelist_num() 00074 { 00075 return(sizeof(plugin_function_namelist) / sizeof(char *)); 00076 } 00077 00078 static void 00079 plugin_free_all() 00080 { 00081 PLUGIN_ENTRY *p, *ptmp; 00082 int i, num; 00083 00084 num = plugin_namelist_num(); 00085 for(i=0;i<num;i++) { 00086 p = global_plugin_list[i]; 00087 while(p) { 00088 ptmp = p->next; 00089 free(p); 00090 p = ptmp; 00091 } 00092 } 00093 free(global_plugin_list); 00094 } 00095 00096 00097 int 00098 plugin_get_id(char *name) 00099 { 00100 int i, num; 00101 num = plugin_namelist_num(); 00102 for(i=0;i<num;i++) { 00103 if (strmatch(plugin_function_namelist[i], name)) { 00104 return i; 00105 } 00106 } 00107 jlog("InternalError: no plugin entry named %s\n", name); 00108 return -1; 00109 } 00110 00111 void 00112 plugin_init() 00113 { 00114 int i, num; 00115 00116 if (global_plugin_list != NULL) { 00117 plugin_free_all(); 00118 } 00119 num = plugin_namelist_num(); 00120 global_plugin_list = (PLUGIN_ENTRY **)mymalloc(sizeof(PLUGIN_ENTRY *) * num); 00121 for(i=0;i<num;i++) { 00122 global_plugin_list[i] = NULL; 00123 } 00124 global_plugin_loaded_file_num = 0; 00125 } 00126 00127 /**************************************************************/ 00135 static boolean 00136 is_plugin_obj(char *filename) 00137 { 00138 char *p, *x; 00139 x = plugin_suffix + strlen(plugin_suffix) - 1; 00140 p = filename + strlen(filename) - 1; 00141 00142 while (x >= plugin_suffix && p >= filename && *x == *p) { 00143 x--; p--; 00144 } 00145 if (x < plugin_suffix) { 00146 return TRUE; 00147 } 00148 00149 return FALSE; 00150 } 00151 00159 boolean 00160 plugin_load_file(char *file) 00161 { 00162 PLUGIN_MODULE handle; 00163 FUNC_INT func; 00164 FUNC_VOID entfunc; 00165 int ret, number, num; 00166 char buf[256]; 00167 int buflen = 256; 00168 PLUGIN_ENTRY *p; 00169 int i; 00170 00171 if (global_plugin_list == NULL) plugin_init(); 00172 00173 /* open file */ 00174 handle = dlopen(file, RTLD_LAZY); 00175 if (!handle) { 00176 jlog("ERROR: plugin_load: failed to open: %s\n", dlerror()); 00177 return(FALSE); 00178 } 00179 00180 /* call initialization function */ 00181 func = dlsym(handle, "initialize"); 00182 if (func) { 00183 ret = (*func)(); 00184 if (ret == -1) { 00185 jlog("WARNING: plugin_load: %s: initialize() returns no, skip this file\n", file); 00186 dlclose(handle); 00187 return(FALSE); 00188 } 00189 } 00190 00191 /* call information function */ 00192 func = dlsym(handle, "get_plugin_info"); 00193 if (func == NULL) { 00194 jlog("ERROR: plugin_load: %s: get_plugin_info(): %s\n", file, dlerror()); 00195 dlclose(handle); 00196 return(FALSE); 00197 } 00198 number = 0; 00199 ret = (*func)(number, buf, buflen); 00200 if (ret == -1) { 00201 jlog("ERROR: plugin_load: %s: get_plugin_info(0) returns error\n", file); 00202 dlclose(handle); 00203 return(FALSE); 00204 } 00205 buf[buflen-1] = '\0'; 00206 jlog("#%d [%s]\n", global_plugin_loaded_file_num, buf); 00207 00208 /* register plugin functions */ 00209 num = plugin_namelist_num(); 00210 for(i=0;i<num;i++) { 00211 entfunc = dlsym(handle, plugin_function_namelist[i]); 00212 if (entfunc) { 00213 if (debug2_flag) { 00214 jlog(" (%s)\n", plugin_function_namelist[i]); 00215 } 00216 p = (PLUGIN_ENTRY *)mymalloc(sizeof(PLUGIN_ENTRY)); 00217 p->id = i; 00218 p->source_id = global_plugin_loaded_file_num; 00219 p->func = entfunc; 00220 p->next = global_plugin_list[i]; 00221 global_plugin_list[i] = p; 00222 } 00223 } 00224 00225 /* increment file counter */ 00226 global_plugin_loaded_file_num++; 00227 00228 return(TRUE); 00229 } 00230 00238 boolean 00239 plugin_load_dir(char *dir) 00240 { 00241 #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__MINGW32__) 00242 00243 WIN32_FIND_DATA FindFileData; 00244 HANDLE hFind; 00245 static char buf[512]; 00246 int cnt; 00247 00248 strncpy(buf, dir, 505); 00249 strcat(buf, "\\*.dll"); 00250 if ((hFind = FindFirstFile(buf, &FindFileData)) == INVALID_HANDLE_VALUE) { 00251 jlog("ERROR: plugin_load: cannot open plugins dir \"%s\"\n", dir); 00252 return FALSE; 00253 } 00254 00255 cnt = 0; 00256 do { 00257 jlog("STAT: file: %-23s ", FindFileData.cFileName); 00258 sprintf_s(buf, 512, "%s\\%s", dir, FindFileData.cFileName); 00259 if (plugin_load_file(buf)) cnt++; 00260 } while (FindNextFile(hFind, &FindFileData)); 00261 00262 FindClose(hFind); 00263 jlog("STAT: %d files loaded\n", cnt); 00264 00265 return TRUE; 00266 00267 #else 00268 00269 DIR *d; 00270 struct dirent *f; 00271 static char buf[512]; 00272 int cnt; 00273 00274 if ((d = opendir(dir)) == NULL) { 00275 jlog("ERROR: plugin_load: cannot open plugins dir \"%s\"\n", dir); 00276 return FALSE; 00277 } 00278 cnt = 0; 00279 while((f = readdir(d)) != NULL) { 00280 if (is_plugin_obj(f->d_name)) { 00281 snprintf(buf, 512, "%s/%s", dir, f->d_name); 00282 jlog("STAT: file: %-23s ", f->d_name); 00283 if (plugin_load_file(buf)) cnt++; 00284 } 00285 } 00286 closedir(d); 00287 jlog("STAT: %d files loaded\n", cnt); 00288 00289 return TRUE; 00290 00291 #endif 00292 } 00293 00301 void 00302 plugin_load_dirs(char *dirent) 00303 { 00304 char *p, *s; 00305 char c; 00306 00307 if (dirent == NULL) return; 00308 00309 if (debug2_flag) { 00310 jlog("DEBUG: loading dirs: %s\n", dirent); 00311 } 00312 00313 p = dirent; 00314 do { 00315 s = p; 00316 while(*p != '\0' && *p != ':') p++; 00317 c = *p; 00318 *p = '\0'; 00319 jlog("STAT: loading plugins at \"%s\":\n", dirent); 00320 plugin_load_dir(s); 00321 if (c != '\0') { 00322 *p = c; 00323 p++; 00324 } 00325 } while (*p != '\0'); 00326 } 00327 00328 00329 /************************************************************************/ 00330 00331 int 00332 plugin_find_optname(char *optfuncname, char *str) 00333 { 00334 char buf[64]; 00335 int id; 00336 PLUGIN_ENTRY *p; 00337 FUNC_VOID func; 00338 00339 if ((id = plugin_get_id(optfuncname)) < 0) return -1; 00340 00341 for(p=global_plugin_list[id];p;p=p->next) { 00342 func = (FUNC_VOID) p->func; 00343 (*func)(buf, (int)64); 00344 if (strmatch(buf, str)) { 00345 return p->source_id; 00346 } 00347 } 00348 return -1; 00349 } 00350 00351 FUNC_VOID 00352 plugin_get_func(int sid, char *name) 00353 { 00354 int id; 00355 PLUGIN_ENTRY *p; 00356 FUNC_VOID func; 00357 00358 if ((id = plugin_get_id(name)) < 0) return NULL; 00359 00360 for(p=global_plugin_list[id];p;p=p->next) { 00361 if (p->source_id == sid) return p->func; 00362 } 00363 return NULL; 00364 } 00365 00366 /************************************************************************/ 00367 boolean 00368 plugin_exec_engine_startup(Recog *recog) 00369 { 00370 int id; 00371 PLUGIN_ENTRY *p; 00372 FUNC_INT func; 00373 boolean ok_p; 00374 00375 if (global_plugin_list == NULL) return TRUE; 00376 00377 if ((id = plugin_get_id("startup")) < 0) return FALSE; 00378 00379 ok_p = TRUE; 00380 for(p=global_plugin_list[id];p;p=p->next) { 00381 func = (FUNC_INT) p->func; 00382 if ((*func)(recog) != 0) { 00383 jlog("WARNING: plugin #%d: failed in startup()\n", p->source_id); 00384 ok_p = FALSE; 00385 } 00386 } 00387 00388 return ok_p; 00389 } 00390 00391 00392 /************************************************************************/ 00393 void 00394 plugin_exec_adin_captured(short *buf, int len) 00395 { 00396 int id; 00397 PLUGIN_ENTRY *p; 00398 FUNC_VOID adfunc; 00399 00400 if (global_plugin_list == NULL) return; 00401 00402 if ((id = plugin_get_id("adin_postprocess")) < 0) return; 00403 for(p=global_plugin_list[id];p;p=p->next) { 00404 adfunc = (FUNC_VOID) p->func; 00405 (*adfunc)(buf, len); 00406 } 00407 } 00408 00409 void 00410 plugin_exec_adin_triggered(short *buf, int len) 00411 { 00412 int id; 00413 PLUGIN_ENTRY *p; 00414 FUNC_VOID adfunc; 00415 00416 if (global_plugin_list == NULL) return; 00417 00418 if ((id = plugin_get_id("adin_postprocess_triggered")) < 0) return; 00419 for(p=global_plugin_list[id];p;p=p->next) { 00420 adfunc = (FUNC_VOID) p->func; 00421 (*adfunc)(buf, len); 00422 } 00423 } 00424 00425 void 00426 plugin_exec_vector_postprocess(VECT *vecbuf, int veclen, int nframe) 00427 { 00428 int id; 00429 PLUGIN_ENTRY *p; 00430 FUNC_INT func; 00431 00432 if (global_plugin_list == NULL) return; 00433 00434 if ((id = plugin_get_id("fvin_postprocess")) < 0) return; 00435 for(p=global_plugin_list[id];p;p=p->next) { 00436 func = (FUNC_INT) p->func; 00437 (*func)(vecbuf, veclen, nframe); 00438 } 00439 } 00440 void 00441 plugin_exec_vector_postprocess_all(HTK_Param *param) 00442 { 00443 int id; 00444 PLUGIN_ENTRY *p; 00445 FUNC_INT func; 00446 int t; 00447 00448 if (global_plugin_list == NULL) return; 00449 00450 if ((id = plugin_get_id("fvin_postprocess")) < 0) return; 00451 for(t=0;t<param->samplenum;t++) { 00452 for(p=global_plugin_list[id];p;p=p->next) { 00453 func = (FUNC_INT) p->func; 00454 (*func)(param->parvec[t], param->veclen, t); 00455 } 00456 } 00457 } 00458 00459 void 00460 plugin_exec_process_result(Recog *recog) 00461 { 00462 int id; 00463 PLUGIN_ENTRY *p; 00464 FUNC_VOID func; 00465 00466 RecogProcess *rtmp, *r; 00467 Sentence *s; 00468 int i; 00469 int len; 00470 char *str; 00471 00472 if (global_plugin_list == NULL) return; 00473 00474 /* for result_str(), return the best sentence string among processes */ 00475 s = NULL; 00476 for(rtmp=recog->process_list;rtmp;rtmp=rtmp->next) { 00477 if (! rtmp->live) continue; 00478 if (rtmp->result.status >= 0 && rtmp->result.sentnum > 0) { /* recognition succeeded */ 00479 if (s == NULL || rtmp->result.sent[0].score > s->score) { 00480 r = rtmp; 00481 s = &(r->result.sent[0]); 00482 } 00483 } 00484 } 00485 if (s == NULL) { 00486 str = NULL; 00487 } else { 00488 len = 0; 00489 for(i=0;i<s->word_num;i++) len += strlen(r->lm->winfo->woutput[s->word[i]]) + 1; 00490 str = (char *)mymalloc(len); 00491 str[0]='\0'; 00492 for(i=0;i<s->word_num;i++) { 00493 if (strlen(r->lm->winfo->woutput[s->word[i]]) == 0) continue; 00494 if (strlen(str) > 0) strcat(str, " "); 00495 strcat(str, r->lm->winfo->woutput[s->word[i]]); 00496 } 00497 } 00498 00499 if ((id = plugin_get_id("result_best_str")) < 0) return; 00500 for(p=global_plugin_list[id];p;p=p->next) { 00501 func = (FUNC_VOID) p->func; 00502 (*func)(str); 00503 } 00504 00505 if (str != NULL) free(str); 00506 } 00507 00508 00509 #endif /* ENABLE_PLUGIN */ 00510 00511 /************************************************************************/ 00512 /* assume only one MFCC module! */ 00513 00514 /************************************************************************/ 00515 00516 boolean 00517 mfc_module_init(MFCCCalc *mfcc, Recog *recog) 00518 { 00519 #ifdef ENABLE_PLUGIN 00520 mfcc->plugin_source = recog->jconf->input.plugin_source; 00521 if (mfcc->plugin_source < 0) { 00522 jlog("ERROR: SP_MDCMODULE selected but plugin is missing?\n"); 00523 return FALSE; 00524 } 00525 mfcc->func.fv_standby = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_standby"); 00526 mfcc->func.fv_begin = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_open"); 00527 mfcc->func.fv_read = (int (*)(VECT *, int)) plugin_get_func(mfcc->plugin_source, "fvin_read"); 00528 mfcc->func.fv_end = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_close"); 00529 mfcc->func.fv_resume = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_resume"); 00530 mfcc->func.fv_pause = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_pause"); 00531 mfcc->func.fv_terminate= (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_terminate"); 00532 mfcc->func.fv_input_name= (char * (*)()) plugin_get_func(mfcc->plugin_source, "fvin_input_name"); 00533 00534 if (mfcc->func.fv_read == NULL) { 00535 jlog("ERROR: FEATURE_INPUT plugin: fvin_read() not found!\n"); 00536 return FALSE; 00537 } 00538 #endif 00539 00540 return TRUE; 00541 } 00542 00543 boolean 00544 mfc_module_set_header(MFCCCalc *mfcc, Recog *recog) 00545 { 00546 FUNC_INT func; 00547 unsigned int ret; 00548 00549 #ifdef ENABLE_PLUGIN 00550 func = (FUNC_INT) plugin_get_func(mfcc->plugin_source, "fvin_get_configuration"); 00551 if (func == NULL) { 00552 jlog("ERROR: feature vector input plugin: fvin_get_configuration() not found\n"); 00553 return FALSE; 00554 } 00555 00556 /* vector length in unit */ 00557 mfcc->param->veclen = (*func)(0); 00558 mfcc->param->header.sampsize = mfcc->param->veclen * sizeof(VECT); 00559 /* frame shift in msec */ 00560 mfcc->param->header.wshift = (*func)(1) * 10000.0; 00561 /* parameter type for checking (return 0xffff to disable the check) */ 00562 ret = (*func)(2); 00563 if (ret == 0xffff) { 00564 /* disable type checking */ 00565 recog->jconf->input.paramtype_check_flag = FALSE; 00566 } else { 00567 mfcc->param->header.samptype = ret; 00568 } 00569 #endif 00570 00571 return TRUE; 00572 } 00573 00574 boolean 00575 mfc_module_standby(MFCCCalc *mfcc) 00576 { 00577 #ifdef ENABLE_PLUGIN 00578 FUNC_INT func; 00579 int ret; 00580 00581 if (mfcc->func.fv_standby) ret = mfcc->func.fv_standby(); 00582 else ret = TRUE; 00583 mfcc->segmented_by_input = FALSE; 00584 return ret; 00585 #else 00586 return TRUE; 00587 #endif 00588 } 00589 00590 boolean 00591 mfc_module_begin(MFCCCalc *mfcc) 00592 { 00593 #ifdef ENABLE_PLUGIN 00594 FUNC_INT func; 00595 int ret; 00596 00597 if (mfcc->segmented_by_input) return TRUE; /* do nothing if last was segmented */ 00598 00599 if (mfcc->func.fv_begin) ret = mfcc->func.fv_begin(); 00600 else ret = TRUE; 00601 return ret; 00602 #else 00603 return TRUE; 00604 #endif 00605 } 00606 00607 boolean 00608 mfc_module_end(MFCCCalc *mfcc) 00609 { 00610 #ifdef ENABLE_PLUGIN 00611 FUNC_INT func; 00612 int ret; 00613 00614 if (mfcc->segmented_by_input) return TRUE; /* do nothing if last was segmented */ 00615 00616 if (mfcc->func.fv_end) ret = mfcc->func.fv_end(); 00617 else ret = TRUE; 00618 return ret; 00619 #else 00620 return TRUE; 00621 #endif 00622 } 00623 00624 int 00625 mfc_module_read(MFCCCalc *mfcc, int *new_t) 00626 { 00627 #ifdef ENABLE_PLUGIN 00628 FUNC_INT func; 00629 int ret; 00630 00631 /* expand area if needed */ 00632 if (param_alloc(mfcc->param, mfcc->f + 1, mfcc->param->veclen) == FALSE) { 00633 jlog("ERROR: FEATURE_INPUT plugin: failed to allocate memory\n"); 00634 return -2; 00635 } 00636 /* get data */ 00637 ret = mfcc->func.fv_read(mfcc->param->parvec[mfcc->f], mfcc->param->veclen); 00638 if (ret == -3) { 00639 /* function requests segmentation of the current recognition */ 00640 mfcc->segmented_by_input = TRUE; 00641 *new_t = mfcc->f; 00642 return -3; 00643 } else if (ret == -1) { 00644 /* end of input */ 00645 mfcc->segmented_by_input = FALSE; 00646 *new_t = mfcc->f; 00647 return -1; 00648 } else if (ret == -2) { 00649 /* error */ 00650 jlog("ERROR: FEATURE_INPUT plugin: fvin_read() returns error (-2)\n"); 00651 return -2; 00652 } 00653 00654 *new_t = mfcc->f + 1; 00655 #endif 00656 00657 return 0; 00658 } 00659 00660 char * 00661 mfc_module_input_name(MFCCCalc *mfcc) 00662 { 00663 #ifdef ENABLE_PLUGIN 00664 int ret; 00665 00666 if (mfcc->func.fv_input_name) return(mfcc->func.fv_input_name()); 00667 #endif 00668 return NULL; 00669 } 00670 00671 /* end of file */