00001
00018
00019
00020
00021
00022
00023
00024
00025 #include <julius/julius.h>
00026
00027 #ifdef ENABLE_PLUGIN
00028
00029 #include <dirent.h>
00030 #include <stdarg.h>
00031
00036 static char *plugin_suffix = PLUGIN_SUFFIX;
00037
00042 static char *plugin_function_namelist[] = PLUGIN_FUNCTION_NAMELIST;
00043
00044
00045
00046
00047 #if defined(_WIN32) && !defined(__CYGWIN32__)
00048
00053 static const char* dlerror()
00054 {
00055 static char szMsgBuf[256];
00056 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
00057 NULL,
00058 GetLastError(),
00059 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00060 szMsgBuf,
00061 sizeof szMsgBuf,
00062 NULL);
00063 return szMsgBuf;
00064 }
00065 #endif
00066
00067
00068 static int
00069 plugin_namelist_num()
00070 {
00071 return(sizeof(plugin_function_namelist) / sizeof(char *));
00072 }
00073
00074 static void
00075 plugin_free_all()
00076 {
00077 PLUGIN_ENTRY *p, *ptmp;
00078 int i, num;
00079
00080 num = plugin_namelist_num();
00081 for(i=0;i<num;i++) {
00082 p = global_plugin_list[i];
00083 while(p) {
00084 ptmp = p->next;
00085 free(p);
00086 p = ptmp;
00087 }
00088 }
00089 free(global_plugin_list);
00090 }
00091
00092
00093 int
00094 plugin_get_id(char *name)
00095 {
00096 int i, num;
00097 num = plugin_namelist_num();
00098 for(i=0;i<num;i++) {
00099 if (strmatch(plugin_function_namelist[i], name)) {
00100 return i;
00101 }
00102 }
00103 jlog("InternalError: no plugin entry named %s\n", name);
00104 return -1;
00105 }
00106
00107 void
00108 plugin_init()
00109 {
00110 int i, num;
00111
00112 if (global_plugin_list != NULL) {
00113 plugin_free_all();
00114 }
00115 num = plugin_namelist_num();
00116 global_plugin_list = (PLUGIN_ENTRY **)mymalloc(sizeof(PLUGIN_ENTRY *) * num);
00117 for(i=0;i<num;i++) {
00118 global_plugin_list[i] = NULL;
00119 }
00120 global_plugin_loaded_file_num = 0;
00121 }
00122
00123
00131 static boolean
00132 is_plugin_obj(char *filename)
00133 {
00134 char *p, *x;
00135 x = plugin_suffix + strlen(plugin_suffix) - 1;
00136 p = filename + strlen(filename) - 1;
00137
00138 while (x >= plugin_suffix && p >= filename && *x == *p) {
00139 x--; p--;
00140 }
00141 if (x < plugin_suffix) {
00142 return TRUE;
00143 }
00144
00145 return FALSE;
00146 }
00147
00155 boolean
00156 plugin_load_file(char *file)
00157 {
00158 PLUGIN_MODULE handle;
00159 FUNC_INT func;
00160 FUNC_VOID entfunc;
00161 int ret, number, num;
00162 char buf[256];
00163 int buflen = 256;
00164 PLUGIN_ENTRY *p;
00165 int i;
00166
00167 if (global_plugin_list == NULL) plugin_init();
00168
00169
00170 handle = dlopen(file, RTLD_LAZY);
00171 if (!handle) {
00172 jlog("ERROR: plugin_load: failed to open: %s\n", dlerror());
00173 return(FALSE);
00174 }
00175
00176
00177 func = dlsym(handle, "initialize");
00178 if (func) {
00179 ret = (*func)();
00180 if (ret == -1) {
00181 jlog("WARNING: plugin_load: %s: initialize() returns no, skip this file\n", file);
00182 dlclose(handle);
00183 return(FALSE);
00184 }
00185 }
00186
00187
00188 func = dlsym(handle, "get_plugin_info");
00189 if (func == NULL) {
00190 jlog("ERROR: plugin_load: %s: get_plugin_info(): %s\n", file, dlerror());
00191 dlclose(handle);
00192 return(FALSE);
00193 }
00194 number = 0;
00195 ret = (*func)(number, buf, buflen);
00196 if (ret == -1) {
00197 jlog("ERROR: plugin_load: %s: get_plugin_info(0) returns error\n", file);
00198 dlclose(handle);
00199 return(FALSE);
00200 }
00201 buf[buflen-1] = '\0';
00202 jlog("#%d [%s]\n", global_plugin_loaded_file_num, buf);
00203
00204
00205 num = plugin_namelist_num();
00206 for(i=0;i<num;i++) {
00207 entfunc = dlsym(handle, plugin_function_namelist[i]);
00208 if (entfunc) {
00209 if (debug2_flag) {
00210 jlog(" (%s)\n", plugin_function_namelist[i]);
00211 }
00212 p = (PLUGIN_ENTRY *)mymalloc(sizeof(PLUGIN_ENTRY));
00213 p->id = i;
00214 p->source_id = global_plugin_loaded_file_num;
00215 p->func = entfunc;
00216 p->next = global_plugin_list[i];
00217 global_plugin_list[i] = p;
00218 }
00219 }
00220
00221
00222 global_plugin_loaded_file_num++;
00223
00224 return(TRUE);
00225 }
00226
00234 boolean
00235 plugin_load_dir(char *dir)
00236 {
00237 DIR *d;
00238 struct dirent *f;
00239 static char buf[512];
00240 int cnt;
00241
00242 if ((d = opendir(dir)) == NULL) {
00243 jlog("ERROR: plugin_load: cannot open plugins dir \"%s\"\n", dir);
00244 return FALSE;
00245 }
00246 cnt = 0;
00247 while((f = readdir(d)) != NULL) {
00248 if (is_plugin_obj(f->d_name)) {
00249 snprintf(buf, 512, "%s/%s", dir, f->d_name);
00250 jlog("STAT: file: %-23s ", f->d_name);
00251 if (plugin_load_file(buf)) cnt++;
00252 }
00253 }
00254 closedir(d);
00255 jlog("STAT: %d files loaded\n", cnt);
00256
00257 return TRUE;
00258 }
00259
00267 void
00268 plugin_load_dirs(char *dirent)
00269 {
00270 char *p, *s;
00271 char c;
00272
00273 if (dirent == NULL) return;
00274
00275 if (debug2_flag) {
00276 jlog("DEBUG: loading dirs: %s\n", dirent);
00277 }
00278
00279 p = dirent;
00280 do {
00281 s = p;
00282 while(*p != '\0' && *p != ':') p++;
00283 c = *p;
00284 *p = '\0';
00285 jlog("STAT: loading plugins at \"%s\":\n", dirent);
00286 plugin_load_dir(s);
00287 if (c != '\0') {
00288 *p = c;
00289 p++;
00290 }
00291 } while (*p != '\0');
00292 }
00293
00294
00295
00296
00297 int
00298 plugin_find_optname(char *optfuncname, char *str)
00299 {
00300 char buf[64];
00301 int id;
00302 PLUGIN_ENTRY *p;
00303 FUNC_VOID func;
00304
00305 if ((id = plugin_get_id(optfuncname)) < 0) return -1;
00306
00307 for(p=global_plugin_list[id];p;p=p->next) {
00308 func = (FUNC_VOID) p->func;
00309 (*func)(buf, (int)64);
00310 if (strmatch(buf, str)) {
00311 return p->source_id;
00312 }
00313 }
00314 return -1;
00315 }
00316
00317 FUNC_VOID
00318 plugin_get_func(int sid, char *name)
00319 {
00320 int id;
00321 PLUGIN_ENTRY *p;
00322 FUNC_VOID func;
00323
00324 if ((id = plugin_get_id(name)) < 0) return NULL;
00325
00326 for(p=global_plugin_list[id];p;p=p->next) {
00327 if (p->source_id == sid) return p->func;
00328 }
00329 return NULL;
00330 }
00331
00332
00333 boolean
00334 plugin_exec_engine_startup(Recog *recog)
00335 {
00336 int id;
00337 PLUGIN_ENTRY *p;
00338 FUNC_INT func;
00339 boolean ok_p;
00340
00341 if (global_plugin_list == NULL) return TRUE;
00342
00343 if ((id = plugin_get_id("startup")) < 0) return FALSE;
00344
00345 ok_p = TRUE;
00346 for(p=global_plugin_list[id];p;p=p->next) {
00347 func = (FUNC_INT) p->func;
00348 if ((*func)(recog) != 0) {
00349 jlog("WARNING: plugin #%d: failed in startup()\n", p->source_id);
00350 ok_p = FALSE;
00351 }
00352 }
00353
00354 return ok_p;
00355 }
00356
00357
00358
00359 void
00360 plugin_exec_adin_captured(short *buf, int len)
00361 {
00362 int id;
00363 PLUGIN_ENTRY *p;
00364 FUNC_VOID adfunc;
00365
00366 if (global_plugin_list == NULL) return;
00367
00368 if ((id = plugin_get_id("adin_postprocess")) < 0) return;
00369 for(p=global_plugin_list[id];p;p=p->next) {
00370 adfunc = (FUNC_VOID) p->func;
00371 (*adfunc)(buf, len);
00372 }
00373 }
00374
00375 void
00376 plugin_exec_adin_triggered(short *buf, int len)
00377 {
00378 int id;
00379 PLUGIN_ENTRY *p;
00380 FUNC_VOID adfunc;
00381
00382 if (global_plugin_list == NULL) return;
00383
00384 if ((id = plugin_get_id("adin_postprocess_triggered")) < 0) return;
00385 for(p=global_plugin_list[id];p;p=p->next) {
00386 adfunc = (FUNC_VOID) p->func;
00387 (*adfunc)(buf, len);
00388 }
00389 }
00390
00391 void
00392 plugin_exec_vector_postprocess(VECT *vecbuf, int veclen, int nframe)
00393 {
00394 int id;
00395 PLUGIN_ENTRY *p;
00396 FUNC_INT func;
00397
00398 if (global_plugin_list == NULL) return;
00399
00400 if ((id = plugin_get_id("fvin_postprocess")) < 0) return;
00401 for(p=global_plugin_list[id];p;p=p->next) {
00402 func = (FUNC_INT) p->func;
00403 (*func)(vecbuf, veclen, nframe);
00404 }
00405 }
00406 void
00407 plugin_exec_vector_postprocess_all(HTK_Param *param)
00408 {
00409 int id;
00410 PLUGIN_ENTRY *p;
00411 FUNC_INT func;
00412 int t;
00413
00414 if (global_plugin_list == NULL) return;
00415
00416 if ((id = plugin_get_id("fvin_postprocess")) < 0) return;
00417 for(t=0;t<param->samplenum;t++) {
00418 for(p=global_plugin_list[id];p;p=p->next) {
00419 func = (FUNC_INT) p->func;
00420 (*func)(param->parvec[t], param->veclen, t);
00421 }
00422 }
00423 }
00424
00425 void
00426 plugin_exec_process_result(Recog *recog)
00427 {
00428 int id;
00429 PLUGIN_ENTRY *p;
00430 FUNC_VOID func;
00431
00432 RecogProcess *rtmp, *r;
00433 Sentence *s;
00434 int i;
00435 int len;
00436 char *str;
00437
00438 if (global_plugin_list == NULL) return;
00439
00440
00441 s = NULL;
00442 for(rtmp=recog->process_list;rtmp;rtmp=rtmp->next) {
00443 if (! rtmp->live) continue;
00444 if (rtmp->result.status >= 0 && rtmp->result.sentnum > 0) {
00445 if (s == NULL || rtmp->result.sent[0].score > s->score) {
00446 r = rtmp;
00447 s = &(r->result.sent[0]);
00448 }
00449 }
00450 }
00451 if (s == NULL) {
00452 str = NULL;
00453 } else {
00454 len = 0;
00455 for(i=0;i<s->word_num;i++) len += strlen(r->lm->winfo->woutput[s->word[i]]) + 1;
00456 str = (char *)mymalloc(len);
00457 str[0]='\0';
00458 for(i=0;i<s->word_num;i++) {
00459 if (strlen(r->lm->winfo->woutput[s->word[i]]) == 0) continue;
00460 if (strlen(str) > 0) strcat(str, " ");
00461 strcat(str, r->lm->winfo->woutput[s->word[i]]);
00462 }
00463 }
00464
00465 if ((id = plugin_get_id("result_best_str")) < 0) return;
00466 for(p=global_plugin_list[id];p;p=p->next) {
00467 func = (FUNC_VOID) p->func;
00468 (*func)(str);
00469 }
00470
00471 if (str != NULL) free(str);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480 boolean
00481 mfc_module_init(MFCCCalc *mfcc, Recog *recog)
00482 {
00483 mfcc->plugin_source = recog->jconf->input.plugin_source;
00484 if (mfcc->plugin_source < 0) {
00485 jlog("ERROR: SP_MDCMODULE selected but plugin is missing?\n");
00486 return FALSE;
00487 }
00488 mfcc->func.fv_standby = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_standby");
00489 mfcc->func.fv_begin = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_open");
00490 mfcc->func.fv_read = (int (*)(VECT *, int)) plugin_get_func(mfcc->plugin_source, "fvin_read");
00491 mfcc->func.fv_end = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_close");
00492 mfcc->func.fv_resume = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_resume");
00493 mfcc->func.fv_pause = (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_pause");
00494 mfcc->func.fv_terminate= (boolean (*)()) plugin_get_func(mfcc->plugin_source, "fvin_terminate");
00495
00496 if (mfcc->func.fv_read == NULL) {
00497 jlog("ERROR: FEATURE_INPUT plugin: fvin_read() not found!\n");
00498 return FALSE;
00499 }
00500
00501 return TRUE;
00502 }
00503
00504 boolean
00505 mfc_module_set_header(MFCCCalc *mfcc, Recog *recog)
00506 {
00507 FUNC_INT func;
00508 unsigned int ret;
00509
00510 func = (FUNC_INT) plugin_get_func(mfcc->plugin_source, "fvin_get_configuration");
00511 if (func == NULL) {
00512 jlog("ERROR: feature vector input plugin: fvin_get_configuration() not found\n");
00513 return FALSE;
00514 }
00515
00516
00517 mfcc->param->veclen = (*func)(0);
00518 mfcc->param->header.sampsize = mfcc->param->veclen * sizeof(VECT);
00519
00520 mfcc->param->header.wshift = (*func)(1) * 10000.0;
00521
00522 ret = (*func)(2);
00523 if (ret == 0xffff) {
00524
00525 recog->jconf->input.paramtype_check_flag = FALSE;
00526 } else {
00527 mfcc->param->header.samptype = ret;
00528 }
00529
00530 return TRUE;
00531 }
00532
00533 boolean
00534 mfc_module_standby(MFCCCalc *mfcc)
00535 {
00536 FUNC_INT func;
00537 int ret;
00538
00539 if (mfcc->func.fv_standby) ret = mfcc->func.fv_standby();
00540 else ret = TRUE;
00541 mfcc->segmented_by_input = FALSE;
00542 return ret;
00543 }
00544
00545 boolean
00546 mfc_module_begin(MFCCCalc *mfcc)
00547 {
00548 FUNC_INT func;
00549 int ret;
00550
00551 if (mfcc->segmented_by_input) return TRUE;
00552
00553 if (mfcc->func.fv_begin) ret = mfcc->func.fv_begin();
00554 else ret = TRUE;
00555 return ret;
00556 }
00557
00558 boolean
00559 mfc_module_end(MFCCCalc *mfcc)
00560 {
00561 FUNC_INT func;
00562 int ret;
00563
00564 if (mfcc->segmented_by_input) return TRUE;
00565
00566 if (mfcc->func.fv_end) ret = mfcc->func.fv_end();
00567 else ret = TRUE;
00568 return ret;
00569 }
00570
00571 int
00572 mfc_module_read(MFCCCalc *mfcc, int *new_t)
00573 {
00574 FUNC_INT func;
00575 int ret;
00576
00577
00578 if (param_alloc(mfcc->param, mfcc->f + 1, mfcc->param->veclen) == FALSE) {
00579 jlog("ERROR: FEATURE_INPUT plugin: failed to allocate memory\n");
00580 return -2;
00581 }
00582
00583 ret = mfcc->func.fv_read(mfcc->param->parvec[mfcc->f], mfcc->param->veclen);
00584 if (ret == -3) {
00585
00586 mfcc->segmented_by_input = TRUE;
00587 *new_t = mfcc->f;
00588 return -3;
00589 } else if (ret == -1) {
00590
00591 mfcc->segmented_by_input = FALSE;
00592 *new_t = mfcc->f;
00593 return -1;
00594 } else if (ret == -2) {
00595
00596 jlog("ERROR: FEATURE_INPUT plugin: fvin_read() returns error (-2)\n");
00597 return -2;
00598 }
00599
00600 *new_t = mfcc->f + 1;
00601
00602 return 0;
00603 }
00604
00605 #endif
00606
00607