43 #include <sphinxbase/err.h>
44 #include <sphinxbase/ckd_alloc.h>
45 #include <sphinxbase/strfuncs.h>
46 #include <sphinxbase/pio.h>
47 #include <sphinxbase/cmd_ln.h>
50 #include "kws_search.h"
53 #define hmm_is_active(hmm) ((hmm)->frame > 0)
54 #define kws_nth_hmm(keyword,n) (&((keyword)->hmms[n]))
80 itor->
base.
word = detection->keyphrase;
81 itor->
base.
sf = detection->sf;
82 itor->
base.
ef = detection->ef;
93 gnode_t *detect_head = gnode_next(itor->
detection);
95 detect_head = gnode_next(detect_head);
114 kws_search_seg_iter(
ps_search_t * search, int32 * out_score)
118 gnode_t *detect_head = kwss->
detections->detect_list;
121 detect_head = gnode_next(detect_head);
129 itor = (
kws_seg_t *)ckd_calloc(1,
sizeof(*itor));
130 itor->
base.
vt = &kws_segfuncs;
163 dict = ps_search_dict(kwss);
165 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
166 tmp_keyphrase = (
char *) ckd_salloc(kwss->
keyphrases[keyword_iter].word);
167 nwrds = str2words(tmp_keyphrase, NULL, 0);
168 wrdptr = (
char **) ckd_calloc(nwrds,
sizeof(*wrdptr));
169 str2words(tmp_keyphrase, wrdptr, nwrds);
170 for (i = 0; i < nwrds; i++) {
173 E_ERROR(
"The word '%s' is missing in the dictionary\n",
180 ckd_free(tmp_keyphrase);
194 for (i = 0; i < kwss->
n_pl; i++)
198 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
200 for (i = 0; i < keyword->n_hmms; i++) {
201 if (hmm_is_active(kws_nth_hmm(keyword, i)))
212 kws_search_hmm_eval(
kws_search_t * kwss, int16
const *senscr)
214 int32 i, keyword_iter;
220 for (i = 0; i < kwss->
n_pl; ++i) {
229 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
231 for (i = 0; i < keyword->n_hmms; i++) {
232 hmm_t *hmm = kws_nth_hmm(keyword, i);
234 if (hmm_is_active(hmm)) {
253 int32 thresh, i, keyword_iter;
257 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
259 for (i = 0; i < keyword->n_hmms; i++) {
260 hmm_t *hmm = kws_nth_hmm(keyword, i);
261 if (hmm_is_active(hmm) && hmm_bestscore(hmm) < thresh)
274 hmm_t *pl_best_hmm = NULL;
279 for (i = 0; i < kwss->
n_pl; i++)
281 best_out_score = hmm_out_score(&kwss->
pl_hmms[i]);
282 pl_best_hmm = &kwss->
pl_hmms[i];
290 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
295 last_hmm = kws_nth_hmm(keyword, keyword->n_hmms - 1);
296 if (hmm_is_active(last_hmm)
299 if (hmm_out_score(last_hmm) - hmm_out_score(pl_best_hmm)
300 >= keyword->threshold) {
302 int32 prob = hmm_out_score(last_hmm) - hmm_out_score(pl_best_hmm);
303 kws_detections_add(kwss->
detections, keyword->word,
304 hmm_out_history(last_hmm),
306 hmm_out_score(last_hmm));
312 for (i = 0; i < kwss->
n_pl; i++) {
314 hmm_in_score(&kwss->
pl_hmms[i])) {
316 hmm_out_score(pl_best_hmm) + kwss->
plp,
317 hmm_out_history(pl_best_hmm), kwss->
frame + 1);
322 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
324 for (i = keyword->n_hmms - 1; i > 0; i--) {
325 hmm_t *pred_hmm = kws_nth_hmm(keyword, i - 1);
326 hmm_t *hmm = kws_nth_hmm(keyword, i);
328 if (hmm_is_active(pred_hmm)) {
329 if (!hmm_is_active(hmm)
333 hmm_out_history(pred_hmm), kwss->
frame + 1);
339 hmm_in_score(kws_nth_hmm(keyword, 0)))
340 hmm_enter(kws_nth_hmm(keyword, 0), hmm_out_score(pl_best_hmm),
346 kws_search_read_list(
kws_search_t *kwss,
const char* keyfile)
353 if ((list_file = fopen(keyfile,
"r")) == NULL) {
354 E_ERROR_SYSTEM(
"Failed to open keyword file '%s'", keyfile);
360 for (li = lineiter_start(list_file); li; li = lineiter_next(li))
365 fseek(list_file, 0L, SEEK_SET);
368 for (li = lineiter_start(list_file), i=0; li; li = lineiter_next(li), i++) {
371 line = string_trim(li->buf, STRING_BOTH);
372 end = strlen(line) - 1;
375 if (line[end] ==
'/') {
376 while (line[begin] !=
'/' && begin > 0)
380 kwss->
keyphrases[i].threshold = (int32) logmath_log(kwss->base.
acmod->
lmath, atof_c(line + begin + 1))
391 kws_search_init(
const char *name,
392 const char *keyphrase,
398 ps_search_init(ps_search_base(kwss), &kws_funcs, PS_SEARCH_TYPE_KWS, name, config, acmod, dict,
404 (int32) logmath_log(acmod->
lmath,
405 cmd_ln_float64_r(config,
409 (int32) logmath_log(acmod->
lmath,
410 cmd_ln_float32_r(config,
415 (int32) logmath_log(acmod->
lmath,
416 cmd_ln_float64_r(config,
417 "-kws_threshold")) >>
420 kwss->
delay = (int32) cmd_ln_int32_r(config,
"-kws_delay");
422 E_INFO(
"KWS(beam: %d, plp: %d, default threshold %d, delay %d)\n",
426 if (kws_search_read_list(kwss, keyfile) < 0) {
427 E_ERROR(
"Failed to create kws search\n");
428 kws_search_free(ps_search_base(kwss));
435 kwss->
keyphrases[0].word = ckd_salloc(keyphrase);
439 if (!kws_search_check_dict(kwss)) {
440 kws_search_free(ps_search_base(kwss));
445 if (kws_search_reinit(ps_search_base(kwss),
446 ps_search_dict(kwss),
447 ps_search_dict2pid(kwss)) < 0) {
448 ps_search_free(ps_search_base(kwss));
452 return ps_search_base(kwss);
482 int32 n_hmms, n_wrds;
484 int i, j, p, keyword_iter;
487 int32 silcipid = bin_mdef_silphone(mdef);
504 for (i = 0; i < kwss->
n_pl; ++i)
511 for (i = 0; i < kwss->
n_pl; ++i) {
514 bin_mdef_pid2ssid(search->
acmod->
mdef, i),
515 bin_mdef_pid2tmatid(search->
acmod->
mdef, i));
518 for (keyword_iter = 0; keyword_iter < kwss->
n_keyphrases; keyword_iter++) {
522 tmp_keyphrase = (
char *) ckd_salloc(keyword->word);
523 n_wrds = str2words(tmp_keyphrase, NULL, 0);
524 wrdptr = (
char **) ckd_calloc(n_wrds,
sizeof(*wrdptr));
525 str2words(tmp_keyphrase, wrdptr, n_wrds);
529 for (i = 0; i < n_wrds; i++) {
531 pronlen = dict_pronlen(dict, wid);
537 ckd_free(keyword->hmms);
538 keyword->hmms = (
hmm_t *) ckd_calloc(n_hmms,
sizeof(
hmm_t));
539 keyword->n_hmms = n_hmms;
543 for (i = 0; i < n_wrds; i++) {
545 pronlen = dict_pronlen(dict, wid);
546 for (p = 0; p < pronlen; p++) {
551 pronlen > 1 ?
dict_pron(dict, wid, 1) : silcipid;
552 ssid = dict2pid_ldiph_lc(d2p, ci, rc, silcipid);
554 else if (p == pronlen - 1) {
558 int j = rssid->
cimap[silcipid];
559 ssid = rssid->
ssid[j];
565 tmatid = bin_mdef_pid2tmatid(mdef, ci);
573 ckd_free(tmp_keyphrase);
590 for (i = 0; i < kwss->
n_pl; ++i) {
599 kws_search_step(
ps_search_t * search,
int frame_idx)
607 kws_search_sen_active(kwss);
613 kws_search_hmm_eval(kwss, senscr);
616 kws_search_hmm_prune(kwss);
619 kws_search_trans(kwss);
633 kws_search_hyp(
ps_search_t * search, int32 * out_score,
634 int32 * out_is_final)
662 line = (
char *)ckd_calloc(len,
sizeof(*line));
665 memcpy(&line[c], keyword_str, strlen(keyword_str));
666 c += strlen(keyword_str);