libjulius/src/plugin.c

説明を見る。
00001 
00018 /*
00019  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00020  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00021  * Copyright (c) 2005-2007 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 #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   /* open file */
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   /* call initialization function */
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   /* call information function */
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   /* register plugin functions */
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   /* increment file counter */
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   /* for result_str(), return the best sentence string among processes */
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) { /* recognition succeeded */
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 /* assume only one MFCC module! */
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   /* vector length in unit */
00517   mfcc->param->veclen = (*func)(0);
00518   mfcc->param->header.sampsize = mfcc->param->veclen * sizeof(VECT);
00519   /* frame shift in msec */
00520   mfcc->param->header.wshift = (*func)(1) * 10000.0;
00521   /* parameter type for checking (return 0xffff to disable the check) */
00522   ret = (*func)(2);
00523   if (ret == 0xffff) {
00524     /* disable type checking */
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; /* do nothing if last was segmented */
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; /* do nothing if last was segmented */
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   /* expand area if needed */
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   /* get data */
00583   ret = mfcc->func.fv_read(mfcc->param->parvec[mfcc->f], mfcc->param->veclen);
00584   if (ret == -3) {
00585     /* function requests segmentation of the current recognition */
00586     mfcc->segmented_by_input = TRUE;
00587     *new_t = mfcc->f;
00588     return -3;
00589   } else if (ret == -1) {
00590     /* end of input */
00591     mfcc->segmented_by_input = FALSE;
00592     *new_t = mfcc->f;
00593     return -1;
00594   } else if (ret == -2) {
00595     /* error */
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 /* ENABLE_PLUGIN */
00606 
00607 /* end of file */

Juliusに対してThu Jul 23 12:16:22 2009に生成されました。  doxygen 1.5.1