| #include <unistd.h> |
| #include "sctk.h" |
|
|
|
|
| void remove_id(TEXT *utt, TEXT **id, int *len); |
| int extract_speaker(TEXT *hyp_id, TEXT *sname, enum id_types id); |
| void load_refs(SCORES *sc, char *hyp_file, char *ref_file, TEXT ***rset, TEXT ***refid, int *refcnt, int case_sense); |
| void free_refs(TEXT ***rset, TEXT ***ref_id, int refcnt); |
| void convert_text_to_word_list(char *file, char *words,int case_sense); |
| void expand_words_to_chars(ARC *arc, void *ptr); |
| void decode_opt_del(ARC *arc, void *ptr); |
| void decode_fragment(ARC *arc, void *ptr); |
| void lookup_word_weight(ARC *arc, void *ptr); |
| void set_word_duration(ARC *arc, void *ptr); |
| void set_word_start(ARC *arc, void *ptr); |
| void set_word_conf(ARC *arc, void *ptr); |
| void set_word_opt_del(ARC *arc, void *ptr); |
|
|
|
|
| #define LOAD_BUFF_LEN 1000 |
|
|
| void remove_id(TEXT *utt, TEXT **id, int *id_len){ |
| TEXT *L_paren, *R_paren; |
| |
| R_paren = TEXT_strrchr(utt,')'); |
| L_paren = TEXT_strrchr(utt,'('); |
|
|
| **id = NULL_TEXT; |
|
|
| if (R_paren == NULL && L_paren == NULL) |
| return; |
|
|
| if (R_paren == NULL || L_paren == NULL){ |
| fprintf(stderr,"Error: Unparsable utterance id %s\n",utt); |
| exit(1); |
| } |
|
|
| |
| if (R_paren - L_paren + 1 + 1 > *id_len){ |
| *id_len = R_paren - L_paren + 1 + 1 + 10; |
| free_singarr(*id,TEXT); |
| alloc_singZ((*id),*id_len,TEXT,'\0'); |
| } |
| TEXT_strBcpy(*id,L_paren,R_paren - L_paren + 1); |
| *(*id + (R_paren - L_paren + 1)) = NULL_TEXT; |
| *L_paren = NULL_TEXT; |
| } |
|
|
| int extract_speaker(TEXT *id, TEXT *sname, enum id_types idt){ |
| char *proc = "extract_speaker"; |
| TEXT *p; |
| switch (idt){ |
| case SP: |
| TEXT_strcpy(sname, id); |
| return(0); |
| case ATIS: |
| case WSJ: |
| TEXT_strBcpy(sname, id + 1, 3); |
| sname[3] = NULL_TEXT; |
| return(0); |
| case RM: |
| case SPUID: |
| case SWB: |
| if (((p = TEXT_strchr(id,'-')) == NULL) && |
| ((p = TEXT_strchr(id,'_')) == NULL)){ |
| fprintf(stderr,"Error: %s can't locate ",proc); |
| switch (idt){ |
| case RM: fprintf(stderr,"%s id %s\n","RM",id); break; |
| case SPUID: fprintf(stderr,"%s id %s\n","SPU_ID",id); break; |
| case SWB: fprintf(stderr,"%s id %s\n","SWB",id); break; |
| case WSJ: |
| case ATIS: |
| default: fprintf(stderr,"*** internal error\n"); |
| } |
| return(1); |
| } |
| TEXT_strBcpy(sname, id + 1, p - (id+1)); |
| sname[p - (id+1)] = NULL_TEXT; |
| return(0); |
| default: |
| fprintf(stderr,"Error: %s unknown id type\n",proc); |
| return(1); |
| } |
| } |
|
|
| |
| void free_refs(TEXT ***rset, TEXT ***ref_id, int refcnt){ |
| free_2dimarr((*rset),refcnt,TEXT); |
| free_2dimarr((*ref_id),refcnt,TEXT); |
| } |
|
|
| void load_refs(SCORES *sc, char *hyp_file, char *ref_file, TEXT ***rset, TEXT ***refid, int *refcnt, int case_sense){ |
| TEXT *in_buf, *id_buf; |
| int in_buf_len=LOAD_BUFF_LEN, id_buf_len=LOAD_BUFF_LEN; |
| FILE *fp; |
| TEXT **idset, **tidset, **refset, **refids; |
| int max_ids, num_ids, i, num_ref, failure=0; |
|
|
| max_ids = 3; num_ids = 0; num_ref = 0; |
| alloc_singZ(idset,max_ids,TEXT *,(TEXT *)0); |
| alloc_singZ(in_buf,in_buf_len,TEXT,'\0'); |
| alloc_singZ(id_buf,id_buf_len,TEXT,'\0'); |
|
|
| |
| if ((hyp_file == NULL) || (*hyp_file == '\0') || |
| ((fp = fopen(hyp_file,"r")) == NULL)){ |
| fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file); |
| exit(1); |
| } |
| while (!feof(fp)){ |
| *in_buf = *(in_buf+1) = COMMENT_CHAR; |
| *(in_buf+2) = NULL_TEXT; |
| while (!feof(fp) && (parse_input_comment_line(sc,in_buf) || |
| TEXT_is_comment_info(in_buf) || |
| TEXT_is_empty(in_buf))){ |
| if (TEXT_ensure_fgets(&in_buf,&in_buf_len,fp) == NULL) |
| *in_buf = NULL_TEXT; |
| } |
| if (!feof(fp)){ |
| if (!case_sense) |
| TEXT_str_case_change_with_mem_expand(&in_buf, &in_buf_len, 1); |
| remove_id(in_buf,&id_buf,&id_buf_len); |
| if (num_ids + 1 >= max_ids) { |
| |
| alloc_singZ(tidset,max_ids*2,TEXT *, (TEXT *)0); |
| memcpy(tidset,idset,sizeof(TEXT *) * num_ids); |
| free_singarr(idset,TEXT *); |
| idset = tidset; |
| max_ids *= 2; |
| } |
| idset[num_ids++] = TEXT_strdup(id_buf); |
| } |
| } |
| fclose(fp); |
|
|
| |
| qsort((void *)idset,num_ids,sizeof(TEXT *),qsort_TEXT_strcmp); |
|
|
| |
| alloc_singZ(refset,num_ids,TEXT *,(TEXT *)0); |
| |
| |
| if ((ref_file == NULL) || (*ref_file == '\0') || |
| ((fp = fopen(ref_file,"r")) == NULL)){ |
| fprintf(stderr,"Can't open input Reference file %s\n",ref_file); |
| exit(1); |
| } |
| while (!feof(fp)){ |
| TEXT **ind; |
| int rind; |
|
|
| *in_buf = *(in_buf+1) = COMMENT_CHAR; |
| *(in_buf+2) = NULL_TEXT; |
| while (!feof(fp) && (parse_input_comment_line(sc,in_buf) || |
| TEXT_is_comment_info(in_buf) || |
| TEXT_is_empty(in_buf))){ |
| if (TEXT_ensure_fgets(&in_buf,&in_buf_len,fp) == NULL) |
| *in_buf = '\0'; |
| } |
| if (feof(fp)) |
| break; |
|
|
| if (!case_sense) |
| TEXT_str_case_change_with_mem_expand(&in_buf, &in_buf_len, 1); |
|
|
| remove_id(in_buf,&id_buf,&id_buf_len); |
| |
| if ((ind = (TEXT **)bsearch(id_buf,idset,num_ids,sizeof(TEXT *), |
| bsearch_TEXT_strcmp)) != NULL){ |
| rind = ind - idset; |
| if (refset[rind] != (TEXT *)0){ |
| if (TEXT_strBcmp(in_buf,refset[rind],TEXT_strlen(in_buf))!= 0){ |
| fprintf(stderr,"Error: double reference text for id '%s'\n", |
| id_buf); |
| failure=1; |
| } |
| } else { |
| refset[rind] = TEXT_strdup(in_buf); |
| num_ref++; |
| } |
| } |
| } |
| fclose(fp); |
| |
| if (num_ref != num_ids){ |
| failure=1; |
| fprintf(stderr,"Error: Not enough Reference files loaded\nMissing:\n"); |
| for (i=0; i<num_ref; i++) |
| if (refset[i] == (TEXT *)0) |
| fprintf(stderr," %s\n",idset[i]); |
| } |
|
|
| |
| alloc_singZ(refids,num_ref,TEXT *,(TEXT *)0); |
| |
| memcpy(refids,idset,sizeof(TEXT *) * num_ref); |
| |
| free_singarr(idset, TEXT *) |
|
|
| free_singarr(in_buf,TEXT); |
| free_singarr(id_buf,TEXT); |
|
|
| *rset = refset; |
| *refcnt = num_ref; |
| *refid = refids; |
|
|
| if (failure) |
| exit(1); |
| } |
|
|
| PATH *infer_word_seg_algo2(TEXT *ref, TEXT *hyp, NETWORK *hnet, int case_sense,char *id, char *lex_fname, int fcorr, int opt_del, int flags) |
| { |
| char *proc="infer_word_seg_algo2"; |
| NETWORK *refnet, *hypnet; |
| PATH *path; |
| static TEXT_LIST *tl = (TEXT_LIST *)0; |
| static int max_word_len=1; |
| int char_align = (flags == INF_ASCII_TOO) ? CALI_ON : CALI_ON+CALI_NOASCII; |
|
|
| if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){ |
| fprintf(scfp,"Error: %s passed ambiguous arguments " |
| "for 'hyp' and 'hnet'\n",proc); |
| exit(1); |
| } |
|
|
| if (tl == (TEXT_LIST *)0){ |
| int i, s; |
| if ((tl = load_TEXT_LIST(lex_fname,0)) == (TEXT_LIST *)0) { |
| fprintf(scfp,"Error: Can't load lexicon file '%s'\n",lex_fname); |
| exit(0); |
| } |
| |
| for (i=0; i<tl->num; i++) |
| if ((s = TEXT_chrlen(tl->elem[i])) > max_word_len) |
| max_word_len = s; |
| } |
|
|
| { |
| TEXT *refCC = (case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref); |
| if ((refnet = Network_create_from_TEXT(ref, "Reference Net", |
| print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
| if (case_sense){ |
| free_singarr(refCC, TEXT); |
| } |
| } |
| |
| if (hyp != (TEXT *)0){ |
| TEXT *hypCC = (case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp); |
| if ((hypnet = Network_create_from_TEXT(hyp,"Hypothesis Net", |
| print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
| if (case_sense){ |
| free_singarr(hypCC, TEXT); |
| } |
| } else |
| hypnet = hnet; |
|
|
| if (opt_del){ |
| Network_traverse(hypnet,NULL,0,decode_opt_del,0,0); |
| Network_traverse(refnet,NULL,0,decode_opt_del,0,0); |
| } |
|
|
| if (fcorr){ |
| Network_traverse(hypnet,NULL,0,decode_fragment,0,0); |
| Network_traverse(refnet,NULL,0,decode_fragment,0,0); |
| } |
|
|
| Network_traverse(refnet,NULL,0,expand_words_to_chars,&char_align,0); |
|
|
| Network_fully_connect_cond(refnet, max_word_len, append_WORD_no_NULL, |
| WORD_in_TEXT_LIST, tl); |
|
|
| |
| |
| |
|
|
| Network_dpalign(refnet,hypnet,wwd_WORD,&path,FALSE); |
| PATH_add_utt_id(path,(char *)id); |
| PATH_set_sequence(path); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| |
| Network_destroy(refnet); |
| Network_destroy(hypnet); |
| |
| |
| return(path); |
| } |
|
|
| PATH *infer_word_seg_algo1(TEXT *ref, TEXT *hyp, NETWORK *hnet, int case_sense,char *id, char *lex_fname, int fcorr, int opt_del, int flags) |
| { |
| char *proc="infer_word_seg_algo1"; |
| NETWORK *refnet, *hypnet; |
| PATH *path; |
| static TEXT_LIST *tl = (TEXT_LIST *)0; |
| static int max_word_len=1; |
| int char_align = (flags == INF_ASCII_TOO) ? CALI_ON : CALI_ON+CALI_NOASCII; |
|
|
| if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){ |
| fprintf(scfp,"Error: %s passed ambiguous arguments " |
| "for 'hyp' and 'hnet'\n",proc); |
| exit(1); |
| } |
|
|
| if (tl == (TEXT_LIST *)0){ |
| int i, s; |
| if ((tl = load_TEXT_LIST(lex_fname,0)) == (TEXT_LIST *)0) { |
| fprintf(scfp,"Error: Can't load lexicon file '%s'\n",lex_fname); |
| exit(0); |
| } |
| |
| for (i=0; i<tl->num; i++) |
| if ((s = TEXT_chrlen(tl->elem[i])) > max_word_len) |
| max_word_len = s; |
| } |
|
|
| TEXT *refCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref); |
| |
| if ((refnet = Network_create_from_TEXT(refCC, "Reference Net", |
| print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
|
|
| if (! case_sense){ |
| free_singarr(refCC, TEXT); |
| } |
| if (hyp != (TEXT *)0){ |
| TEXT *hypCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp); |
| if ((hypnet = Network_create_from_TEXT(hypCC,"Hypothesis Net", |
| print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
| if (! case_sense){ |
| free_singarr(hypCC, TEXT); |
| } |
| } else |
| hypnet = hnet; |
|
|
| |
|
|
| if (opt_del){ |
| Network_traverse(hypnet,NULL,0,decode_opt_del,0,0); |
| Network_traverse(refnet,NULL,0,decode_opt_del,0,0); |
| } |
|
|
| if (fcorr){ |
| Network_traverse(hypnet,NULL,0,decode_fragment,0,0); |
| Network_traverse(refnet,NULL,0,decode_fragment,0,0); |
| } |
|
|
| |
| Network_traverse(hypnet,NULL,0,expand_words_to_chars,&char_align,0); |
| |
|
|
| Network_fully_connect_cond(hypnet, max_word_len, append_WORD_no_NULL, |
| WORD_in_TEXT_LIST, tl); |
|
|
| |
| |
| |
|
|
| Network_dpalign(refnet,hypnet,wwd_WORD,&path,FALSE); |
| PATH_add_utt_id(path,(char *)id); |
| PATH_set_sequence(path); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| |
| Network_destroy(refnet); |
| Network_destroy(hypnet); |
| |
| |
| return(path); |
| } |
|
|
| PATH *network_dp_align_texts(TEXT *ref, NETWORK *rnet, TEXT *hyp, NETWORK *hnet, int char_align, int case_sense, char *id, int fcorr, int opt_del, int time_align, WWL *wwl, char *lm_file) |
| { |
| char *proc="network_dp_align_texts"; |
| NETWORK *refnet, *hypnet; |
| PATH *path; |
|
|
| if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){ |
| fprintf(scfp,"Error: %s passed ambiguous arguments " |
| "for 'hyp' and 'hnet'\n",proc); |
| exit(1); |
| } |
|
|
| if (ref != (TEXT *)0 && rnet != (NETWORK *)0){ |
| fprintf(scfp,"Error: %s passed ambiguous arguments " |
| "for 'ref' and 'rnet'\n",proc); |
| exit(1); |
| } |
| |
| |
| if (ref != (TEXT *)0){ |
| TEXT *refCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref); |
| |
| if ((refnet = Network_create_from_TEXT(refCC, "Reference Net",print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
| if (! case_sense){ |
| free_singarr(refCC, TEXT); |
| } |
| } else { |
| refnet = rnet; |
| } |
|
|
| if (hyp != (TEXT *)0){ |
| TEXT *hypCC = (!case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp); |
|
|
| if ((hypnet = Network_create_from_TEXT(hypCC,"Hypothesis Net", |
| print_WORD, |
| equal_WORD2, |
| release_WORD, null_alt_WORD, |
| opt_del_WORD, |
| copy_WORD, make_empty_WORD, |
| use_count_WORD)) |
| == NULL_NETWORK){ |
| fprintf(stderr,"Network_create_from_TEXT failed\n"); |
| exit(1); |
| } |
| if (! case_sense){ |
| free_singarr(hypCC, TEXT); |
| } |
| } else |
| hypnet = hnet; |
|
|
| if (opt_del){ |
| Network_traverse(hypnet,NULL,0,decode_opt_del,0,0); |
| Network_traverse(refnet,NULL,0,decode_opt_del,0,0); |
| } |
|
|
| if (fcorr){ |
| Network_traverse(hypnet,NULL,0,decode_fragment,0,0); |
| Network_traverse(refnet,NULL,0,decode_fragment,0,0); |
| } |
|
|
| if (char_align){ |
| Network_traverse(hypnet,NULL,0,expand_words_to_chars,&char_align,0); |
| Network_traverse(refnet,NULL,0,expand_words_to_chars,&char_align,0); |
| } |
|
|
| if (wwl != (WWL *)0){ |
| Network_traverse(hypnet,NULL,0,lookup_word_weight,wwl,0); |
| Network_traverse(refnet,NULL,0,lookup_word_weight,wwl,0); |
| } |
|
|
| if (lm_file != (char *)0){ |
| Network_traverse(hypnet,NULL,0,lookup_lm_word_weight,lm_file,0); |
| Network_traverse(refnet,NULL,0,lookup_lm_word_weight,lm_file,0); |
| } |
|
|
| |
| |
| Network_dpalign(refnet,hypnet, |
| ( (time_align) ? wwd_time_WORD : |
| ( ((wwl != (WWL *)0) || (lm_file != (char *)0)) ? |
| wwd_weight_WORD : wwd_WORD) ), |
| &path,FALSE); |
| PATH_add_utt_id(path,(char *)id); |
| PATH_set_sequence(path); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| if (char_align) BF_SET(path->attrib,PA_CHAR_ALIGN); |
| if ((wwl != (WWL *)0) || (lm_file != (char *)0)) { |
| BF_SET(path->attrib,PA_HYP_WEIGHT); |
| BF_SET(path->attrib,PA_REF_WEIGHT); |
| } |
|
|
| Network_destroy(refnet); |
| Network_destroy(hypnet); |
| |
| return(path); |
| } |
|
|
| SCORES *align_trans_mode_dp(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, int char_align, enum id_types idt, int infer_word_seg, char *lexicon, int fcorr, int opt_del, int inf_no_ascii, WWL *wwl, char *lm_file){ |
| FILE *fp_hyp; |
| TEXT *hyp_buff, *hyp_id, *spkr_id; |
| int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN; |
| int spkr_id_len=LOAD_BUFF_LEN; |
| PATH *path; |
| SCORES *scor; |
| int spk, rind, last_spk=0; |
| TEXT **reftran, **refid, **ind; |
| int refcnt; |
|
|
| alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0'); |
| alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0'); |
| alloc_singZ(spkr_id,spkr_id_len,TEXT,'\0'); |
|
|
| if ((hyp_file == NULL) || (*hyp_file == '\0') || |
| ((fp_hyp = fopen(hyp_file,"r")) == NULL)){ |
| fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file); |
| exit(1); |
| } |
|
|
| scor = SCORES_init(set_title,20); |
| scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file); |
| scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file); |
| scor->creation_date = get_date(); |
| scor->frag_corr = fcorr; |
| scor->opt_del = opt_del; |
| if (wwl != (WWL*)0) { |
| scor->weight_ali = 1; |
| scor->weight_file = |
| (char *)TEXT_strdup((TEXT*)rsprintf("%s Column \"%s\"",wwl->filename, |
| wwl->weight_desc[0])); |
| } else if (lm_file != (char *)0) { |
| scor->weight_ali = 1; |
| scor->weight_file = (char *)TEXT_strdup((TEXT*)lm_file); |
| } else |
| scor->weight_ali = 0; |
|
|
| load_refs(scor, hyp_file, ref_file, &reftran, &refid, &refcnt, case_sense); |
|
|
| while (!feof(fp_hyp)){ |
| *hyp_buff = *(hyp_buff+1) = COMMENT_CHAR; |
| *(hyp_buff+2) = NULL_TEXT; |
| while (!feof(fp_hyp) && (parse_input_comment_line(scor,hyp_buff) || |
| TEXT_is_comment_info(hyp_buff) || |
| TEXT_is_empty(hyp_buff))) |
| if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL) |
| *hyp_buff = '\0'; |
| if (feof(fp_hyp)) |
| break; |
|
|
| remove_id(hyp_buff,&hyp_id,&hyp_id_len); |
| if (!case_sense) TEXT_str_case_change_with_mem_expand(&hyp_id, &hyp_id_len, 1); |
|
|
| extract_speaker(hyp_id,spkr_id,idt); |
| spk = SCORES_get_grp(scor,(char *)spkr_id); |
| |
| if (feedback >= 1){ |
| if (spk != last_spk) { printf("\n"); last_spk = spk; } |
| printf("\r Alignment# %d for speaker %s ", |
| scor->grp[spk].nsent+1,spkr_id); |
| fflush(stdout); |
| } |
|
|
| if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *), |
| bsearch_TEXT_strcmp)) == NULL){ |
| fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n", |
| hyp_id); |
| exit(1); |
| } |
| rind = ind - refid; |
|
|
| if (feedback >= 100){ |
| printf("\n HYP -> %s\n",hyp_buff); |
| printf(" REF -> %s\n",reftran[rind]); |
| fflush(stdout); |
| } |
| if (infer_word_seg == 0) |
| path = network_dp_align_texts(reftran[rind], (NETWORK *)0, |
| hyp_buff, (NETWORK *)0, |
| char_align, case_sense, |
| (char *)hyp_id, fcorr, opt_del, FALSE, wwl, lm_file); |
| else if (infer_word_seg == INF_SEG_ALGO1) |
| path = infer_word_seg_algo1(reftran[rind], hyp_buff, (NETWORK *)0, |
| case_sense, (char *)hyp_id, lexicon, |
| fcorr, opt_del, inf_no_ascii); |
| else if (infer_word_seg == INF_SEG_ALGO2) |
| path = infer_word_seg_algo2(reftran[rind], hyp_buff, (NETWORK *)0, |
| case_sense, (char *)hyp_id, lexicon, |
| fcorr, opt_del, inf_no_ascii); |
| else{ |
| fprintf(scfp,"Error: unknown alignment procedure\n"); |
| exit(1); |
| } |
|
|
| if (feedback >= 2){ |
| printf("\n"); |
| PATH_print(path,stdout,199); |
| printf("\n"); |
| } |
|
|
| add_PATH_score(scor,path,spk, keep_path); |
|
|
| if (!keep_path) |
| PATH_free(path); |
| } |
| if (feedback >= 1) |
| printf("\n\n"); |
|
|
| free_singarr(hyp_buff,TEXT); |
| free_singarr(hyp_id,TEXT); |
| free_singarr(spkr_id,TEXT); |
| free_refs(&reftran, &refid, refcnt); |
| fclose(fp_hyp); |
|
|
| return(scor); |
| } |
|
|
|
|
| |
| |
| void set_word_duration(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| tw->T_dur = *(double *)ptr; |
| } |
|
|
| |
| |
| |
| void set_word_start(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| tw->T1 = *(double *)ptr; |
| tw->T2 = tw->T_dur + tw->T1; |
| *(double *)ptr += tw->T_dur; |
| } |
|
|
| |
| |
| void set_word_conf(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| tw->conf = *(double *)ptr; |
| } |
|
|
| |
| |
| void set_word_opt_del(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| TEXT *ot; |
|
|
| if (*(int *)ptr){ |
| |
| ot = tw->value; |
| tw->value = TEXT_strdup((TEXT *)rsprintf(WORD_OPT_DEL_PRE_STR "%s" |
| WORD_OPT_DEL_POST_STR,ot)); |
| TEXT_free(ot); |
| } |
| } |
|
|
| void expand_words_to_chars(ARC *arc, void *ptr){ |
| char *proc = "expand_words_to_chars"; |
| WORD *tw = (WORD *)(arc->data); |
| static TEXT *chars=(TEXT *)0, *charsEsc; |
| static int chars_len=100; |
| NETWORK *subnet; |
| char buf[20]; |
| static int alt=1; |
|
|
| if (chars == (TEXT *)0) alloc_singZ(chars,chars_len,TEXT,'\0'); |
| |
| if (TEXT_strlen(tw->value) <= 1) |
| return; |
|
|
| if (db >= 5) { |
| printf("%s: String length > 1\n",proc); |
| arc->net->arc_func.print(arc->data); |
| } |
| |
| sprintf(buf,"expand-net %d",alt); |
| TEXT_separate_chars((!tw->opt_del) ? tw->value : tw->intern_value, |
| &chars,&chars_len,*((int *)ptr)); |
| |
| |
| |
| |
| alloc_singZ(charsEsc, chars_len*2+1, TEXT, NULL_TEXT); |
| TEXT_strcpy_escaped(charsEsc, chars, ';'); |
| |
| |
| |
| if (TEXT_strcmp(chars,tw->value) != 0){ |
| subnet = Network_create_from_TEXT(charsEsc, buf, arc->net->arc_func.print, |
| arc->net->arc_func.equal, |
| arc->net->arc_func.destroy, |
| arc->net->arc_func.is_null_alt, |
| arc->net->arc_func.is_opt_del, |
| arc->net->arc_func.copy, |
| arc->net->arc_func.make_empty, |
| arc->net->arc_func.use_count); |
| if (subnet == NULL_NETWORK){ |
| fprintf(scfp,"proc %s: Internal error. Unable to expand words" |
| " to characters\n",proc); |
| return; |
| } |
| |
| |
| { |
| double dur = tw->T_dur/subnet->arc_count, t1 = tw->T1, conf = tw->conf; |
| int od = tw->opt_del; |
| Network_traverse(subnet,NULL,0,set_word_duration,&dur,0); |
| Network_traverse(subnet,NULL,0,set_word_start,&t1,0); |
| Network_traverse(subnet,NULL,0,set_word_conf,&conf,0); |
| if (od){ |
| Network_traverse(subnet,NULL,0,set_word_opt_del,&od,0); |
| Network_traverse(subnet,NULL,0,decode_opt_del,0,0); |
| } |
| } |
| Network_merge_network(arc->from_node,arc->to_node,subnet); |
| Network_delete_arc(arc); |
| alt++; |
| } |
| free_singarr(charsEsc, TEXT); |
| } |
|
|
|
|
| |
| void lookup_word_weight(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| WWL *wwl = (WWL *)ptr; |
|
|
| if (tw->value == (TEXT *)0) |
| tw->weight = 0.0; |
| else if (TEXT_strcmp(tw->value,(TEXT *)"@") == 0) |
| tw->weight = 0.0; |
| else if (tw->opt_del) |
| tw->weight = 0.0; |
| else |
| tw->weight = Weight_wwl((tw->opt_del ? tw->intern_value : tw->value), wwl); |
|
|
| return; |
| } |
|
|
|
|
| void decode_opt_del(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| int len; |
|
|
| if (tw->value == (TEXT *)0) return; |
| len = TEXT_strlen(tw->value); |
|
|
| if ((*(tw->value + len - 1) == WORD_OPT_DEL_POST_CHAR) && |
| (*(tw->value) == WORD_OPT_DEL_PRE_CHAR)){ |
| tw->opt_del = TRUE; |
| tw->intern_value = TEXT_strBdup(tw->value + 1,len - 2); |
| } |
| return; |
| } |
|
|
| void decode_fragment(ARC *arc, void *ptr){ |
| WORD *tw = (WORD *)(arc->data); |
| int len; |
|
|
| if (tw->value == (TEXT *)0) return; |
| len = TEXT_strlen(tw->value); |
| if (((*(tw->value + len - 1) == WORD_FRAG_CHAR) || |
| (*(tw->value ) == WORD_FRAG_CHAR)) || |
| (tw->opt_del && |
| (*(tw->value + len - 2) == WORD_FRAG_CHAR))) |
| tw->frag_corr = TRUE; |
|
|
| return; |
| } |
|
|
| |
| |
| |
| |
|
|
| void create_word_lists(SCORES *sc, TEXT **reftran, TEXT **refid, int refcnt, char *hyp_file, char *out_ref, char *out_hyp, int *num_hyp, int case_sense); |
| void process_diff_line(TEXT *diff_out, PATH *path, TEXT **firsttoken); |
| void set_temp_files(char *refwords, char *hypwords); |
|
|
| void create_word_lists(SCORES *sc, TEXT **reftran, TEXT **refid, int refcnt, char *hyp_file, char *out_ref, char *out_hyp, int *num_hyp, int case_sense){ |
| FILE *fp_hyp, *fp_out_ref, *fp_out_hyp; |
| TEXT *hyp_buff, *hyp_id, *ctext, *tbuf; |
| int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN; |
| int tbuf_len=100; |
| int rind; |
| TEXT **ind; |
|
|
| alloc_singZ(tbuf,tbuf_len,TEXT,'\0'); |
| alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0'); |
| alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0'); |
|
|
| if ((fp_hyp = fopen(hyp_file,"r")) == NULL){ |
| fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file); |
| exit(1); |
| } |
|
|
| if ((fp_out_hyp=fopen(out_hyp,"w")) == NULL){ |
| fprintf(stderr,"Error: Unable to open Hypothesis word file '%s'\n", |
| out_hyp); |
| exit(1); |
| } |
| if ((fp_out_ref=fopen(out_ref,"w")) == NULL){ |
| fprintf(stderr,"Error: Unable to open Reference word file '%s'\n", |
| out_ref); |
| exit(1); |
| } |
|
|
| while (!feof(fp_hyp)){ |
| *hyp_buff = *(hyp_buff+1) = COMMENT_CHAR; |
| *(hyp_buff+2) = NULL_TEXT; |
| |
| while (!feof(fp_hyp) && (parse_input_comment_line(sc,hyp_buff) || |
| TEXT_is_comment_info(hyp_buff) || |
| TEXT_is_empty(hyp_buff))) |
| if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL) |
| *hyp_buff = '\0'; |
|
|
| if (feof(fp_hyp)) |
| break; |
|
|
| (*num_hyp) ++; |
|
|
| if (!case_sense) |
| TEXT_str_case_change_with_mem_expand(&hyp_buff, &hyp_buff_len, 1); |
|
|
| remove_id(hyp_buff,&hyp_id,&hyp_id_len); |
| if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *), |
| bsearch_TEXT_strcmp)) == NULL){ |
| fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n", |
| hyp_id); |
| exit(1); |
| } |
| rind = ind - refid; |
|
|
| |
| if (TEXT_strlen(reftran[rind]) > tbuf_len+1){ |
| free_singarr(tbuf,TEXT); |
| tbuf = TEXT_strdup(reftran[rind]); |
| tbuf_len = TEXT_strlen(tbuf); |
| } else |
| TEXT_strcpy(tbuf,reftran[rind]); |
|
|
| ctext = tokenize_TEXT_first_alt(tbuf,(TEXT *)" \t\n"); |
| while (ctext != NULL) { |
| fprintf(fp_out_ref,"%s\n",ctext); |
| ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n"); |
| } |
| |
| ctext = TEXT_strtok(hyp_buff,(TEXT *)" \t\n"); |
| while (ctext != NULL) { |
| fprintf(fp_out_hyp,"%s\n",ctext); |
| ctext = TEXT_strtok(NULL,(TEXT *)" \t\n"); |
| } |
| } |
|
|
| fclose(fp_out_ref); |
| fclose(fp_out_hyp); |
| fclose(fp_hyp); |
| free_singarr(hyp_buff,TEXT); |
| free_singarr(hyp_id,TEXT); |
| free_singarr(tbuf,TEXT); |
| } |
|
|
| void process_diff_line(TEXT *diff_out, PATH *path, TEXT **firsttoken){ |
| static TEXT s1[100],s2[100],s3[100]; |
| int iret; |
| WORD *rwd, *hwd; |
|
|
| check_space_in_PATH(path); |
| *s1 = *s2 = *s3 = '\0'; |
| iret = sscanf((char *)diff_out, |
| "%s %s %s",(char *)s1,(char *)s2,(char *)s3); |
| *firsttoken = s1; |
|
|
| if (iret == 2 && TEXT_strcmp(s1,s2) == 0) |
| path->pset[path->num].eval = P_CORR; |
| else if (iret == 2 && TEXT_strcmp(s1,(TEXT *)">") == 0) |
| path->pset[path->num].eval = P_INS; |
| else if (iret == 3) |
| path->pset[path->num].eval = P_SUB; |
| else |
| path->pset[path->num].eval = P_DEL; |
|
|
| path->pset[path->num].b_ptr = path->pset[path->num].a_ptr = (void *)0; |
|
|
| switch (path->pset[path->num].eval){ |
| case P_CORR: |
| case P_DEL: |
| case P_SUB: |
| rwd = new_WORD(s1, -1, 0.0, 0.0, 0.0, (TEXT *)0, (TEXT *)0, 0, 0, -1.0); |
| path->pset[path->num].a_ptr = rwd; |
| case P_INS: |
| ; |
| } |
| switch (path->pset[path->num].eval){ |
| case P_CORR: |
| case P_INS: |
| case P_SUB: |
| hwd = (WORD *)0; |
| switch (path->pset[path->num].eval){ |
| case P_CORR: |
| case P_INS: |
| hwd = new_WORD(s2, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0); break; |
| case P_SUB: |
| hwd = new_WORD(s3, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0); break; |
| case P_DEL: |
| hwd = new_WORD((TEXT *)0, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0); |
| break; |
| } |
| if (hwd == (WORD *)0){ |
| fprintf(stderr,"Error: Failed to alloc word in process_diff_line\n"); |
| exit(1); |
| } |
| path->pset[path->num].b_ptr = hwd; |
| case P_DEL: |
| ; |
| } |
|
|
| path->num++; |
| } |
|
|
| void set_temp_files(char *refwords, char *hypwords){ |
| int pid = getpid(); |
| int max=30, n=0, fail; |
| struct stat fileinfo; |
|
|
| do { |
| sprintf(refwords,"/tmp/ref.%d",pid+n); |
| sprintf(hypwords,"/tmp/hyp.%d",pid+n); |
| n++; |
| fail = (stat(refwords,&fileinfo) == 0) || |
| (stat(hypwords,&fileinfo) == 0); |
| } while (fail && (n < max)); |
| if (fail){ |
| fprintf(stderr,"Can't locate temp file names. Searched /tmp/ref.[%d-%d]\n", |
| pid,pid+n); |
| exit(1); |
| } |
| } |
|
|
| SCORES *align_trans_mode_diff(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){ |
| FILE *fp_hyp, *fp_diff; |
| TEXT *hyp_buff, *hyp_id, *spkr_id, *diff_out; |
| int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN; |
| int spkr_id_len=LOAD_BUFF_LEN, diff_out_len=LOAD_BUFF_LEN; |
| PATH *path; |
| SCORES *scor; |
| int spk, rind; |
| TEXT **reftran, **refid, **ind; |
| TEXT *firsttoken; |
| int refcnt, num_hyp=0; |
| TEXT *ctext = hyp_buff; |
| char refwords[100], hypwords[100]; |
|
|
| alloc_singZ(diff_out,diff_out_len,TEXT,'\0'); |
| alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0'); |
| alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0'); |
| alloc_singZ(spkr_id,spkr_id_len,TEXT,'\0'); |
|
|
| set_temp_files(refwords, hypwords); |
|
|
| |
| scor = SCORES_init(set_title,20); |
| scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file); |
| scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file); |
| scor->creation_date = get_date(); |
|
|
| |
| if (feedback >= 1) printf(" Loading transcripts\n"); |
| load_refs(scor, hyp_file, ref_file, &reftran, &refid, &refcnt, case_sense); |
|
|
| |
| create_word_lists(scor, reftran, refid, refcnt, hyp_file, |
| refwords, hypwords, &num_hyp, case_sense); |
|
|
| |
| if (feedback >= 1) printf(" Executing diff\n"); |
| if ((fp_diff = readpipe (DIFF_PROGRAM, "-y",refwords, |
| hypwords, NULL)) ==NULL){ |
| fprintf(stderr,"Error: Execution of 'diff' failed\n"); |
| exit(1); |
| } |
| |
| if ((fp_hyp = fopen(hyp_file,"r")) == NULL){ |
| fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file); |
| exit(1); |
| } |
| while (!feof(fp_hyp)){ |
| *hyp_buff = *(hyp_buff+1) = COMMENT_CHAR; |
| *(hyp_buff+2) = NULL_TEXT; |
| |
| while (!feof(fp_hyp) && (parse_input_comment_line(scor,hyp_buff) || |
| TEXT_is_comment_info(hyp_buff) || |
| TEXT_is_empty(hyp_buff))) |
| if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL) |
| *hyp_buff = '\0'; |
|
|
| if (feof(fp_hyp)) break; |
| if (!case_sense) TEXT_str_case_change_with_mem_expand(&hyp_buff, &hyp_buff_len, 1); |
| remove_id(hyp_buff,&hyp_id,&hyp_id_len); |
| extract_speaker(hyp_id,spkr_id,idt); |
| spk = SCORES_get_grp(scor,(char *)spkr_id); |
|
|
| if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *), |
| bsearch_TEXT_strcmp)) == NULL){ |
| fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n", |
| hyp_id); |
| exit(1); |
| } |
| rind = ind - refid; |
| --num_hyp; |
|
|
| if (feedback >= 3) |
| printf("REF: %s\nHYP: %s\n",reftran[rind],hyp_buff); |
|
|
| path = PATH_alloc(100); |
|
|
| ctext = tokenize_TEXT_first_alt(reftran[rind],(TEXT *)" \t\n"); |
| while (ctext != NULL) { |
| do { |
| check_space_in_PATH(path); |
| if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff) == |
| NULL) |
| *diff_out = '\0'; |
| if (feof(fp_diff)) break; |
| process_diff_line(diff_out,path,&firsttoken); |
| } while (!feof(fp_diff) && |
| ((TEXT_strcmp(firsttoken,ctext) != 0) || num_hyp==0)); |
| ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n"); |
| } |
|
|
| PATH_add_utt_id(path,(char *)hyp_id); |
| PATH_set_sequence(path); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| |
| if (feedback >= 2){ |
| printf("\n"); |
| PATH_print(path,stdout,199); |
| printf("\n"); |
| } |
|
|
| add_PATH_score(scor,path,spk, keep_path); |
|
|
| if (!keep_path) PATH_free(path); |
| } |
| fclose(fp_diff); |
| fclose(fp_hyp); |
|
|
| if (num_hyp != 0){ |
| fprintf(stderr,"Error: Unexpected number of output utts. Missing %d\n",num_hyp); |
| exit(1); |
| } |
|
|
| free_singarr(diff_out,TEXT); |
| free_singarr(hyp_buff,TEXT); |
| free_singarr(hyp_id,TEXT); |
| free_singarr(spkr_id,TEXT); |
| free_refs(&reftran, &refid, refcnt); |
|
|
| unlink(refwords); |
| unlink(hypwords); |
| return(scor); |
| } |
|
|
| SCORES *align_ctm_to_stm_diff(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){ |
| char *proc="align_ctm_to_stm"; |
| FILE *fp_ref, *fp_hyp; |
| WTOKE_STR1 *hyp_segs; |
| int ref_eof, ref_err, hyp_eof, hyp_err; |
| int hyp_end_chan1, ref_end_chan1; |
| int hyp_end_chan2, ref_end_chan2; |
| int just_read, hyp_file_end, ref_file_end; |
| int number_of_channels; |
| int i; |
| PATH *path; |
| STM *stm; |
| SCORES *scor; |
| int spkr, r; |
| char refwords[100], hypwords[100]; |
| TEXT *diff_out, *firsttoken, *ctext; |
| static int diff_out_len=100; |
| FILE *fp_diff; |
| int pdb = 0; |
|
|
| |
| hyp_segs = WTOKE_STR1_init(hyp_file); |
| scor = SCORES_init(set_title,20); |
| scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file); |
| scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file); |
| scor->creation_date = get_date(); |
|
|
| alloc_singZ(diff_out,diff_out_len,TEXT,'\0'); |
| |
| set_temp_files(refwords, hypwords); |
|
|
| if ((fp_hyp = fopen(hyp_file,"r")) == NULL){ |
| fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file); |
| exit(1); |
| } |
| if ((fp_ref = fopen(ref_file,"r")) == NULL){ |
| fprintf(stderr,"Can't open input reference file %s\n",ref_file); |
| exit(1); |
| } |
|
|
| if ((stm = alloc_STM(200)) == (STM *)0) { |
| fprintf(stderr,"%s: Failed to alloc STM struct\n",proc); |
| exit(1); |
| } |
| hyp_eof = ref_eof = 0; |
| do { |
| do { |
| locate_WTOKE_boundary(hyp_segs, hyp_segs->s, 1, 0, &hyp_file_end); |
| just_read = 0; |
| if ((hyp_file_end == hyp_segs->n) && !hyp_eof){ |
| fill_mark_struct(fp_hyp,hyp_segs,hyp_file,&hyp_eof,&hyp_err, |
| case_sense); |
| if (hyp_err != 0){ |
| fprintf(stdout,"; *Err: Error detected in hyp file '%s'\n", |
| hyp_file); |
| exit(1); |
| } |
| just_read = 1; |
| } |
| } while (just_read); |
| just_read = 0; |
| do { |
| locate_STM_boundary(stm, stm->s, 1, 0, &ref_file_end); |
| if ((ref_file_end == stm->num) && !ref_eof){ |
| if (just_read == 1){ |
| just_read = 0; |
| expand_STM(stm); |
| } |
| fill_STM(fp_ref, stm, ref_file, &ref_eof, case_sense,&ref_err); |
| if (hyp_err != 0){ |
| fprintf(stdout,"; *Err: Error detected in hyp file '%s'\n", |
| hyp_file); |
| exit(1); |
| } |
| just_read = 1; |
| } else |
| just_read = 0; |
| } while (just_read); |
|
|
| |
| locate_WTOKE_boundary(hyp_segs, hyp_segs->s, 1, 1, &hyp_end_chan1); |
| if (hyp_end_chan1+1 < hyp_segs->n && |
| strcmp(hyp_segs->word[hyp_segs->s].conv, |
| hyp_segs->word[hyp_end_chan1+1].conv)==0){ |
| locate_WTOKE_boundary(hyp_segs,hyp_end_chan1+1,1,1,&hyp_end_chan2); |
| number_of_channels = 2; |
| } else { |
| |
| hyp_end_chan2 = hyp_end_chan1; |
| number_of_channels = 1; |
| } |
|
|
| |
| locate_STM_boundary(stm, stm->s, 1, 1, &ref_end_chan1); |
| if (ref_end_chan1+1 < stm->num && |
| TEXT_strcmp(stm->seg[stm->s].file, |
| stm->seg[ref_end_chan1+1].file)==0){ |
| if (number_of_channels != 2){ |
| fprintf(stderr,"%s: Channel Mis-match, 1 in Hyp, 2 in Ref\n", |
| proc); |
| return((SCORES *)0); |
| } |
| locate_STM_boundary(stm, ref_end_chan1+1, 1, 1, &ref_end_chan2); |
| } else { |
| |
| if (number_of_channels != 1){ |
| fprintf(stderr,"%s: Channel Mis-match, 2 in Hyp, 1 in Ref\n", |
| proc); |
| return((SCORES *)0); |
| } |
| ref_end_chan2 = ref_end_chan1; |
| } |
|
|
| |
| if (feedback >= 1) |
| printf(" Performing alignments for file '%s'.\n", |
| stm->seg[stm->s].file); |
| if (db+pdb >= 5){ |
| printf("%s: hyp CTM File Range [%d,%d]", |
| proc,hyp_segs->s,hyp_file_end); |
| printf(" Chan1 Range[%d,%d] ",hyp_segs->s,hyp_end_chan1); |
| printf(" Chan2 Range[%d,%d]\n",hyp_end_chan1+1,hyp_end_chan2); |
| if (db+pdb >= 10){ |
| dump_word_tokens2(hyp_segs, hyp_segs->s, hyp_file_end); |
| printf("\n"); |
| } |
| printf("%s: ref STM File Range [%d,%d]",proc,stm->s,ref_file_end); |
| printf(" Chan1 Range[%d,%d] ",stm->s, ref_end_chan1); |
| printf(" Chan2 Range[%d,%d]\n",ref_end_chan1+1,ref_end_chan2); |
| if (db+pdb >= 10) dump_STM(stm, stm->s, ref_file_end); |
| printf("\n"); |
| } |
| |
| for (i=0; i<number_of_channels; i++){ |
| int h_st, h_end, r_st, r_end; |
|
|
| if (db+pdb >= 5) printf("\n%s: Starting Channel %d\n",proc,i); |
| if (i==0){ |
| h_st = hyp_segs->s; h_end = hyp_end_chan1; |
| r_st = stm->s; r_end = ref_end_chan1; |
| } else { |
| h_st = hyp_end_chan1+1; h_end = hyp_end_chan2; |
| r_st = ref_end_chan1+1; r_end = ref_end_chan2; |
| } |
|
|
| if (strcmp(hyp_segs->word[h_st].conv, |
| (char *)stm->seg[r_st].file) != 0){ |
| fprintf(stderr,"%s: File identifiers do not match,\nhyp ",proc); |
| fprintf(stderr,"file '%s' and ref file '%s' not synchronized\n", |
| hyp_segs->word[h_st].conv,stm->seg[r_st].file); |
| return((SCORES *)0); |
| } |
| if (strcmp(hyp_segs->word[h_st].turn, |
| (char *)stm->seg[r_st].chan) != 0){ |
| fprintf(stderr,"%s: channel identifiers do not match, ",proc); |
| fprintf(stderr,"hyp file '%s' and ref file '%s' not", |
| hyp_segs->word[h_st].conv,stm->seg[r_st].file); |
| fprintf(stderr," synchronized\n"); |
| return((SCORES *)0); |
| } |
|
|
| |
| dump_STM_words(stm,r_st,r_end+((r_end==stm->num)?-1:0),refwords); |
| dump_WTOKE_words(hyp_segs, h_st, h_end, hypwords); |
|
|
| if ((fp_diff = readpipe (DIFF_PROGRAM, "-y",refwords, hypwords, NULL)) == NULL){ |
| fprintf(stderr,"Error: Execution of 'diff' failed\n"); |
| exit(1); |
| } |
|
|
| for (r=r_st; r<=r_end + ((r_end==stm->num)?-1:0); r++){ |
| path = PATH_alloc(100); |
| path->num = 0; |
|
|
| |
| ctext = tokenize_TEXT_first_alt(stm->seg[r].text, |
| (TEXT*)" \t\n"); |
| while (ctext != NULL){ |
| do { |
| if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff) |
| == NULL) |
| *diff_out = '\0'; |
| if (feof(fp_diff)) break; |
| process_diff_line(diff_out,path,&firsttoken); |
| } while (!feof(fp_diff) && |
| ((TEXT_strcmp(firsttoken,ctext) != 0) || |
| r== r_end + (r_end==stm->num)?-1:0)); |
| ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n"); |
| } |
| spkr = SCORES_get_grp(scor,(char *)stm->seg[r].spkr); |
| PATH_add_utt_id(path,rsprintf("(%s-%03d)",stm->seg[r].spkr, |
| scor->grp[spkr].nsent)); |
| PATH_set_sequence(path); |
| PATH_add_label(path,(char *)stm->seg[r].labels); |
| PATH_add_file(path,(char *)stm->seg[r].chan); |
| PATH_add_channel(path,(char *)stm->seg[r].chan); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| add_PATH_score(scor,path,spkr, keep_path); |
| |
| if (feedback >= 2){ |
| printf("\n"); |
| PATH_print(path,stdout,199); |
| printf("\n"); |
| } |
| if (!keep_path) PATH_free(path); |
| } |
| fclose(fp_diff); |
|
|
| |
| stm->s = r_end+1; |
| } |
|
|
| |
| hyp_segs->s = hyp_end_chan2+1; |
| stm->s = ref_end_chan2+1; |
| } while (hyp_segs->s <= hyp_segs->n); |
|
|
| fclose(fp_hyp); |
| fclose(fp_ref); |
|
|
| unlink(refwords); |
| unlink(hypwords); |
| free_singarr(diff_out,TEXT); |
|
|
| free_mark_file(hyp_segs); |
| free_STM(stm); |
|
|
| return(scor); |
| } |
|
|
| void convert_text_to_word_list(char *file, char *words,int case_sense){ |
| FILE *fp, *fp_out; |
| TEXT *buf, *ctext; |
| int buf_len=100; |
|
|
| if ((fp=fopen(file,"r")) == NULL){ |
| fprintf(stderr,"Error: Unable to open input STM file '%s'\n",file); |
| exit(1); |
| } |
|
|
| if ((fp_out=fopen(words,"w")) == NULL){ |
| fprintf(stderr,"Error: Unable to open STM word file '%s'\n",words); |
| exit(1); |
| } |
|
|
| alloc_singZ(buf,buf_len,TEXT,'\0'); |
|
|
| |
| while (!feof(fp)){ |
| |
| *buf = '\0'; |
| while (!feof(fp) && (TEXT_is_comment(buf) || |
| TEXT_is_comment_info(buf) || |
| TEXT_is_empty(buf))) |
| if (TEXT_ensure_fgets(&buf,&buf_len,fp) == NULL) |
| *buf = '\0'; |
| if (*buf == '\0' && feof(fp)) break; |
| if (!case_sense) TEXT_str_case_change_with_mem_expand(&buf, &buf_len, 1); |
|
|
| |
| ctext = TEXT_strtok(buf,(TEXT *)" \t\n"); |
| while (ctext != NULL){ |
| fprintf(fp_out,"%s\n",ctext); |
| ctext = TEXT_strtok(NULL,(TEXT *)" \t\n"); |
| } |
| } |
| fclose(fp); |
| fclose(fp_out); |
| free_singarr(buf,TEXT); |
| } |
|
|
| SCORES *align_text_to_stm(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){ |
| |
| FILE *fp_ref; |
| PATH *path; |
| SCORES *scor; |
| int spkr, num_ref; |
| char refwords[100], hypwords[100]; |
| TEXT *diff_out, *ref_buf, *firsttoken, *ctext; |
| int diff_out_len=100, ref_buf_len=100; |
| FILE *fp_diff; |
| STM_SEG ref_seg; |
|
|
| |
| scor = SCORES_init(set_title,20); |
| scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file); |
| scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file); |
| scor->creation_date = get_date(); |
|
|
| alloc_singZ(diff_out,diff_out_len,TEXT,'\0'); |
| alloc_singZ(ref_buf,ref_buf_len,TEXT,'\0'); |
|
|
| set_temp_files(refwords, hypwords); |
|
|
| |
| convert_stm_to_word_list(ref_file,refwords,case_sense,&num_ref); |
|
|
| |
| convert_text_to_word_list(hyp_file,hypwords,case_sense); |
|
|
| |
| if ((fp_diff = readpipe (DIFF_PROGRAM,"-y",refwords, hypwords, NULL)) == |
| NULL){ |
| fprintf(stderr,"Error: Execution of 'diff' failed\n"); |
| exit(1); |
| } |
|
|
| |
| if ((fp_ref = fopen(ref_file,"r")) == NULL){ |
| fprintf(stderr,"Can't open input reference file %s\n",ref_file); |
| exit(1); |
| } |
|
|
| |
| while (!feof(fp_ref)){ |
| |
| read_stm_line(&ref_buf,&ref_buf_len,fp_ref); |
| if (feof(fp_ref)) break; |
|
|
| |
| parse_stm_line(&ref_seg, &ref_buf, &ref_buf_len, case_sense, 0); |
| num_ref --; |
| |
| |
| path = PATH_alloc(100); path->num = 0; |
|
|
| |
| ctext = tokenize_TEXT_first_alt(ref_seg.text,(TEXT *)" \t\n"); |
| while (ctext != NULL){ |
| do { |
| if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff) == NULL) |
| *diff_out = '\0'; |
| if (feof(fp_diff)) break; |
| process_diff_line(diff_out,path,&firsttoken); |
| } while (!feof(fp_diff) && |
| ((TEXT_strcmp(firsttoken,ctext) != 0) || num_ref==0)); |
| ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n"); |
| } |
|
|
| spkr = SCORES_get_grp(scor,(char *)ref_seg.spkr); |
| PATH_add_utt_id(path,rsprintf("(%s-%03d)",ref_seg.spkr, |
| scor->grp[spkr].num_path)); |
| PATH_set_sequence(path); |
| PATH_add_label(path,(char *)ref_seg.labels); |
| PATH_add_file(path,(char *)ref_seg.file); |
| PATH_add_channel(path,(char *)ref_seg.chan); |
| if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE); |
| add_PATH_score(scor,path,spkr, keep_path); |
| |
| if (feedback >= 2){ |
| printf("\n"); |
| PATH_print(path,stdout,199); |
| printf("\n"); |
| } |
| if (!keep_path) PATH_free(path); |
| free_STM_SEG(&ref_seg); |
| } |
| fclose(fp_diff); |
| fclose(fp_ref); |
|
|
| free_singarr(diff_out,TEXT); |
| free_singarr(ref_buf,TEXT); |
|
|
| unlink(refwords); |
| unlink(hypwords); |
|
|
| return(scor); |
| } |
|
|