| File: | modules/base/phrasify.cc |
| Location: | line 617, column 5 |
| Description: | Value stored to 'lang_prob' is never read |
| 1 | /*************************************************************************/ |
| 2 | /* */ |
| 3 | /* Centre for Speech Technology Research */ |
| 4 | /* University of Edinburgh, UK */ |
| 5 | /* Copyright (c) 1996,1997 */ |
| 6 | /* All Rights Reserved. */ |
| 7 | /* */ |
| 8 | /* Permission is hereby granted, free of charge, to use and distribute */ |
| 9 | /* this software and its documentation without restriction, including */ |
| 10 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
| 11 | /* distribute, sublicense, and/or sell copies of this work, and to */ |
| 12 | /* permit persons to whom this work is furnished to do so, subject to */ |
| 13 | /* the following conditions: */ |
| 14 | /* 1. The code must retain the above copyright notice, this list of */ |
| 15 | /* conditions and the following disclaimer. */ |
| 16 | /* 2. Any modifications must be clearly marked as such. */ |
| 17 | /* 3. Original authors' names are not deleted. */ |
| 18 | /* 4. The authors' names are not used to endorse or promote products */ |
| 19 | /* derived from this software without specific prior written */ |
| 20 | /* permission. */ |
| 21 | /* */ |
| 22 | /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */ |
| 23 | /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */ |
| 24 | /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */ |
| 25 | /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */ |
| 26 | /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ |
| 27 | /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */ |
| 28 | /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */ |
| 29 | /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */ |
| 30 | /* THIS SOFTWARE. */ |
| 31 | /* */ |
| 32 | /*************************************************************************/ |
| 33 | /* Author : Alan W Black */ |
| 34 | /* Date : August 1996 */ |
| 35 | /*-----------------------------------------------------------------------*/ |
| 36 | /* */ |
| 37 | /* Phrase break prediction */ |
| 38 | /* */ |
| 39 | /*=======================================================================*/ |
| 40 | #include <cstdio> |
| 41 | #include "festival.h" |
| 42 | #include "modules.h" |
| 43 | |
| 44 | using namespace std; |
| 45 | |
| 46 | static void phrasing_none(EST_Utterance &u); |
| 47 | static void phrasing_by_cart(EST_Utterance &u); |
| 48 | static void phrasing_by_probmodels(EST_Utterance &u); |
| 49 | static void phrasing_by_fa(EST_Utterance &u); |
| 50 | static EST_VTCandidate *bb_candlist(EST_Item *s,EST_Features &f); |
| 51 | static EST_VTPath *bb_npath(EST_VTPath *p,EST_VTCandidate *c,EST_Features &f); |
| 52 | static double find_b_prob(EST_VTPath *p,int n,int *state); |
| 53 | |
| 54 | // Used in various default value cases |
| 55 | static int B_word = 0; |
| 56 | static int BB_word = 0; |
| 57 | static int NB_word = 0; |
| 58 | static int pos_p_start_tag = 0; |
| 59 | static int pos_pp_start_tag = 0; |
| 60 | static int pos_n_start_tag = 0; |
| 61 | |
| 62 | static double gscale_s = 1.0; |
| 63 | static double gscale_p = 0.0; |
| 64 | static EST_Ngrammar *bb_ngram = 0; |
| 65 | static EST_Ngrammar *bb_pos_ngram = 0; |
| 66 | static LISP bb_tags = NIL((struct obj *) 0); |
| 67 | static LISP pos_map = NIL((struct obj *) 0); |
| 68 | static LISP phrase_type_tree = NIL((struct obj *) 0); |
| 69 | |
| 70 | /* Interslice */ |
| 71 | static EST_Track *bb_track = 0; |
| 72 | |
| 73 | LISP FT_Classic_Phrasify_Utt(LISP utt) |
| 74 | { |
| 75 | // Predict and add phrasing to an utterance |
| 76 | EST_Utterance *u = get_c_utt(utt)(utterance(utt)); |
| 77 | LISP phrase_method = ft_get_param("Phrase_Method"); |
| 78 | |
| 79 | *cdebug << "Phrasify module\n"; |
| 80 | |
| 81 | if (u->relation_present("Phrase")) |
| 82 | return utt; // already specified |
| 83 | else if (phrase_method == NIL((struct obj *) 0)) |
| 84 | phrasing_none(*u); // all one phrase |
| 85 | else if (streq("prob_models",get_c_string(phrase_method))(strcmp("prob_models",get_c_string(phrase_method))==0)) |
| 86 | phrasing_by_probmodels(*u); |
| 87 | else if (streq("cart_tree",get_c_string(phrase_method))(strcmp("cart_tree",get_c_string(phrase_method))==0)) |
| 88 | phrasing_by_cart(*u); |
| 89 | else if (streq("forced_align",get_c_string(phrase_method))(strcmp("forced_align",get_c_string(phrase_method))==0)) |
| 90 | phrasing_by_fa(*u); |
| 91 | else |
| 92 | { |
| 93 | cerr << "PHRASIFY: unknown phrase method \"" << |
| 94 | get_c_string(phrase_method) << endl; |
| 95 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
| 96 | } |
| 97 | |
| 98 | return utt; |
| 99 | } |
| 100 | |
| 101 | static void phrasing_none(EST_Utterance& u) |
| 102 | { |
| 103 | // All in a single phrase |
| 104 | EST_Item *w,*phr=0; |
| 105 | |
| 106 | u.create_relation("Phrase"); |
| 107 | |
| 108 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 109 | { |
| 110 | if (phr == 0) |
| 111 | phr = add_phrase(u); |
| 112 | append_daughter(phr,"Phrase",w); |
| 113 | if (w->next() == 0) |
| 114 | { |
| 115 | w->set("pbreak","B"); |
| 116 | phr->set_name("4"); |
| 117 | phr = 0; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | } |
| 122 | |
| 123 | static void phrasing_by_cart(EST_Utterance &u) |
| 124 | { |
| 125 | EST_Item *w,*phr=0; |
| 126 | LISP tree; |
| 127 | EST_Val pbreak; |
| 128 | |
| 129 | u.create_relation("Phrase"); |
| 130 | tree = siod_get_lval("phrase_cart_tree","no phrase cart tree"); |
| 131 | |
| 132 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 133 | { |
| 134 | if (phr == 0) |
| 135 | phr = add_phrase(u); |
| 136 | append_daughter(phr,"Phrase",w); |
| 137 | pbreak = wagon_predict(w,tree); |
| 138 | w->set("pbreak",pbreak.string()); |
| 139 | if ((pbreak == "B") || (pbreak == "BB")) |
| 140 | { |
| 141 | phr->set_name((EST_String)pbreak); |
| 142 | phr = 0; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | } |
| 147 | |
| 148 | static void pbyp_get_params(LISP params) |
| 149 | { |
| 150 | EST_String bb_pos_name,bb_pos_filename,bb_name,bb_break_filename; |
| 151 | EST_String bb_track_name; |
| 152 | LISP l1; |
| 153 | |
| 154 | bb_pos_name = get_param_str("pos_ngram_name",params,""); |
| 155 | bb_pos_filename = get_param_str("pos_ngram_filename",params,""); |
| 156 | if ((bb_pos_ngram = get_ngram(bb_pos_name,bb_pos_filename)) == 0) |
| 157 | { |
| 158 | cerr << "PHRASIFY: no ngram called \"" << |
| 159 | bb_pos_name << "\" defined." << endl; |
| 160 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
| 161 | } |
| 162 | |
| 163 | gscale_s = get_param_float("gram_scale_s",params,1.0); |
| 164 | gscale_p = get_param_float("gram_scale_p",params,0.0); |
| 165 | pos_map = get_param_lisp("pos_map",params,NIL((struct obj *) 0)); |
| 166 | |
| 167 | bb_name = get_param_str("break_ngram_name",params,""); |
| 168 | bb_break_filename = get_param_str("break_ngram_filename",params,""); |
| 169 | if ((bb_ngram = get_ngram(bb_name,bb_break_filename)) == 0) |
| 170 | { |
| 171 | cerr << "PHRASIFY: no ngram called \"" << |
| 172 | bb_name << "\" defined." << endl; |
| 173 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
| 174 | } |
| 175 | bb_tags = get_param_lisp("break_tags",params,NIL((struct obj *) 0)); |
| 176 | phrase_type_tree = get_param_lisp("phrase_type_tree",params,NIL((struct obj *) 0)); |
| 177 | |
| 178 | bb_track_name = get_param_str("break_track_name",params,""); |
| 179 | if (bb_track_name != "") |
| 180 | { |
| 181 | if (bb_track) |
| 182 | delete bb_track; |
| 183 | bb_track = new EST_Track; |
| 184 | if (bb_track->load(bb_track_name) != format_okread_ok) |
| 185 | { |
| 186 | delete bb_track; |
| 187 | cerr << "PHRASE: failed to load FA track " << |
| 188 | bb_track_name << endl; |
| 189 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | l1 = siod_get_lval("pos_p_start_tag",NULL__null); |
| 194 | if (l1 != NIL((struct obj *) 0)) |
| 195 | pos_p_start_tag = bb_pos_ngram->get_vocab_word(get_c_string(l1)); |
| 196 | l1 = siod_get_lval("pos_pp_start_tag",NULL__null); |
| 197 | if (l1 != NIL((struct obj *) 0)) |
| 198 | pos_pp_start_tag = bb_pos_ngram->get_vocab_word(get_c_string(l1)); |
| 199 | l1 = siod_get_lval("pos_n_start_tag",NULL__null); |
| 200 | if (l1 != NIL((struct obj *) 0)) |
| 201 | pos_n_start_tag = bb_pos_ngram->get_vocab_word(get_c_string(l1)); |
| 202 | } |
| 203 | |
| 204 | static void phrasing_by_probmodels(EST_Utterance& u) |
| 205 | { |
| 206 | // Predict phrasing using POS and prob models of B distribution |
| 207 | EST_Item *w,*phr=0; |
| 208 | EST_String pbreak; |
| 209 | int num_states; |
| 210 | |
| 211 | pbyp_get_params(siod_get_lval("phr_break_params",NULL__null)); |
| 212 | gc_protect(&bb_tags); |
| 213 | |
| 214 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 215 | { // Set up tag index for pos ngram |
| 216 | EST_String lpos = map_pos(pos_map,w->f("pos").string()); |
| 217 | w->set("phr_pos",lpos); |
| 218 | w->set("pos_index",bb_pos_ngram->get_vocab_word(lpos)); |
| 219 | } |
| 220 | B_word = bb_ngram->get_vocab_word("B"); |
| 221 | NB_word = bb_ngram->get_vocab_word("NB"); |
| 222 | BB_word = bb_ngram->get_vocab_word("BB"); |
| 223 | |
| 224 | num_states = bb_ngram->num_states(); |
| 225 | EST_Viterbi_Decoder v(bb_candlist,bb_npath,num_states); |
| 226 | |
| 227 | v.initialise(u.relation("Word")); |
| 228 | v.search(); |
| 229 | v.result("pbreak_index"); |
| 230 | |
| 231 | // Given predicted break, go through and add phrases |
| 232 | u.create_relation("Phrase"); |
| 233 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 234 | { |
| 235 | w->set("pbreak",bb_ngram-> |
| 236 | get_vocab_word(w->f("pbreak_index").Int())); |
| 237 | if (phr == 0) |
| 238 | phr = add_phrase(u); |
| 239 | append_daughter(phr,"Phrase",w); |
| 240 | if (phrase_type_tree != NIL((struct obj *) 0)) |
| 241 | { |
| 242 | EST_Val npbreak = wagon_predict(w,phrase_type_tree); |
| 243 | w->set("pbreak",npbreak.string()); // may reset to BB |
| 244 | } |
| 245 | pbreak = (EST_String)w->f("pbreak"); |
| 246 | if (pbreak == "B") |
| 247 | w->set("blevel",3); |
| 248 | else if (pbreak == "mB") |
| 249 | w->set("blevel",2); |
| 250 | if ((pbreak == "B") || (pbreak == "BB") || (pbreak == "mB")) |
| 251 | { |
| 252 | phr->set_name((EST_String)pbreak); |
| 253 | phr = 0; |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | gc_unprotect(&bb_tags); |
| 258 | bb_tags = NIL((struct obj *) 0); |
| 259 | } |
| 260 | |
| 261 | static EST_VTCandidate *bb_candlist(EST_Item *s,EST_Features &f) |
| 262 | { |
| 263 | // Find candidates with a priori probabilities |
| 264 | EST_IVector window(bb_pos_ngram->order()); |
| 265 | (void)f; |
| 266 | int tag; |
| 267 | |
| 268 | if (bb_pos_ngram->order() == 4) |
| 269 | { |
| 270 | window[1] = s->I("pos_index",0); |
| 271 | if (s->prev() != 0) |
| 272 | window[0] = s->prev()->I("pos_index",0); |
| 273 | else |
| 274 | window[0] = pos_p_start_tag; |
| 275 | if (s->next() != 0) |
| 276 | window[2] = s->next()->I("pos_index",0); |
| 277 | else |
| 278 | window[2] = pos_n_start_tag; |
| 279 | } |
| 280 | else if (bb_pos_ngram->order() == 3) |
| 281 | { |
| 282 | window[0] = s->I("pos_index",0); |
| 283 | if (s->next() != 0) |
| 284 | window[1] = s->next()->I("pos_index",0); |
| 285 | else |
| 286 | window[1] = pos_n_start_tag; |
| 287 | } |
| 288 | else if (bb_pos_ngram->order() == 5) |
| 289 | { // This is specific for some set of pos tagsets |
| 290 | window[2] = s->I("pos_index",0); |
| 291 | if (s->prev() != 0) |
| 292 | { |
| 293 | window[1] = s->prev()->I("pos_index",0); |
| 294 | } |
| 295 | else |
| 296 | { |
| 297 | window[1] = pos_p_start_tag; |
| 298 | } |
| 299 | if (s->next() != 0) |
| 300 | { |
| 301 | window[3] = s->next()->I("pos_index",0); |
| 302 | if (s->next()->next() != 0) |
| 303 | window[0] = s->next()->next()->I("pos_index",0); |
| 304 | else |
| 305 | window[0] = 0; |
| 306 | } |
| 307 | else |
| 308 | { |
| 309 | window[3] = pos_n_start_tag; |
| 310 | window[0] = 0; |
| 311 | } |
| 312 | } |
| 313 | else |
| 314 | { |
| 315 | cerr << "PHRASIFY: can't deal with ngram of size " << |
| 316 | bb_pos_ngram->order() << endl; |
| 317 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
| 318 | } |
| 319 | double prob=1.0; |
| 320 | EST_VTCandidate *all_c = 0; |
| 321 | EST_Val labelled_brk = ffeature(s,"R:Token.parent.pbreak"); |
| 322 | |
| 323 | if ((labelled_brk != "0") && |
| 324 | (ffeature(s,"R:Token.n.name") == "0")) // last word in token |
| 325 | { // there is a labelled break on the token so respect it |
| 326 | EST_VTCandidate *c = new EST_VTCandidate; |
| 327 | c->s = s; |
| 328 | c->name = bb_ngram->get_vocab_word(labelled_brk.string()); |
| 329 | c->score = log(0.95); // very very likely, but not absolute |
| 330 | c->next = all_c; |
| 331 | all_c = c; // but then if you give only one option ... |
| 332 | } |
| 333 | else if (s->next() == 0) // end of utterances so force a break |
| 334 | { |
| 335 | EST_VTCandidate *c = new EST_VTCandidate; |
| 336 | c->s = s; |
| 337 | c->name = B_word; |
| 338 | c->score = log(0.95); // very very likely, but not absolute |
| 339 | c->next = all_c; |
| 340 | all_c = c; |
| 341 | } |
| 342 | else if (s->name() == ".end_utt") |
| 343 | { // This is a quick check to see if forcing "." to B is worth it |
| 344 | EST_VTCandidate *c = new EST_VTCandidate; |
| 345 | c->s = s; |
| 346 | c->name = B_word; |
| 347 | c->score = log(0.95); // very very likely, but not absolute |
| 348 | c->next = all_c; |
| 349 | all_c = c; |
| 350 | } |
| 351 | else if (siod_get_lval("break_non_bayes",NULL__null) != NIL((struct obj *) 0)) |
| 352 | { |
| 353 | /* This uses the "wrong" formula to extract the probability */ |
| 354 | /* Extract P(B | context) rather than P(context | B) as below */ |
| 355 | /* This gives worse results as well as not following Bayes */ |
| 356 | /* equations */ |
| 357 | EST_VTCandidate *c; |
| 358 | LISP l; |
| 359 | for (l=bb_tags; l != 0; l=cdr(l)) |
| 360 | { |
| 361 | c = new EST_VTCandidate; |
| 362 | c->s = s; |
| 363 | tag = bb_ngram->get_vocab_word(get_c_string(car(l))); |
| 364 | c->name = tag; |
| 365 | window[bb_pos_ngram->order()-1] = tag; |
| 366 | const EST_DiscreteProbDistribution &pd = |
| 367 | bb_pos_ngram->prob_dist(window); |
| 368 | if (pd.samples() == 0) |
| 369 | { |
| 370 | if (tag == B_word) |
| 371 | prob = 0.2; |
| 372 | else |
| 373 | prob = 0.8; |
| 374 | } |
| 375 | else |
| 376 | prob = pd.probability(tag); |
| 377 | if (prob == 0) |
| 378 | c->score = log(0.0000001); |
| 379 | else |
| 380 | c->score = log(prob); |
| 381 | c->next = all_c; |
| 382 | all_c = c; |
| 383 | } |
| 384 | } |
| 385 | else |
| 386 | { // Standard Bayes model |
| 387 | EST_VTCandidate *c; |
| 388 | LISP l; |
| 389 | for (l=bb_tags; l != 0; l=cdr(l)) |
| 390 | { |
| 391 | c = new EST_VTCandidate; |
| 392 | c->s = s; |
| 393 | tag = bb_ngram->get_vocab_word(get_c_string(car(l))); |
| 394 | c->name = tag; |
| 395 | window[bb_pos_ngram->order()-1] = tag; |
| 396 | prob = bb_pos_ngram->reverse_probability(window); |
| 397 | |
| 398 | // If this word came from inside a token reduce the |
| 399 | // probability of a break |
| 400 | if ((ffeature(s,"R:Token.n.name") != "0") && |
| 401 | ((s->as_relation("Token")->first()->length()) < 7)) |
| 402 | { |
| 403 | float weight = ffeature(s,"pbreak_scale"); |
| 404 | if (weight == 0) weight = 0.5; |
| 405 | if (tag == B_word) |
| 406 | prob *= weight; |
| 407 | else |
| 408 | prob = 1.0-((1.0-prob)*weight); |
| 409 | } |
| 410 | if (prob == 0) |
| 411 | c->score = log(0.0000001); |
| 412 | else |
| 413 | c->score = log(prob); |
| 414 | s->set("phrase_score",c->score); |
| 415 | c->next = all_c; |
| 416 | all_c = c; |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | return all_c; |
| 421 | } |
| 422 | |
| 423 | static EST_VTPath *bb_npath(EST_VTPath *p,EST_VTCandidate *c,EST_Features &f) |
| 424 | { |
| 425 | EST_VTPath *np = new EST_VTPath; |
| 426 | (void)f; |
| 427 | // static EST_String lscorename("lscore"); |
| 428 | double prob; |
| 429 | double lprob,lang_prob; |
| 430 | |
| 431 | np->c = c; |
| 432 | np->from = p; |
| 433 | int n = c->name.Int(); |
| 434 | prob = find_b_prob(p,n,&np->state); |
| 435 | if (np->state == -1) |
| 436 | prob = find_b_prob(p,n,&np->state); |
| 437 | if (prob == 0) |
| 438 | lprob = log(0.00000001); |
| 439 | else |
| 440 | lprob = log(prob); |
| 441 | |
| 442 | lang_prob = (1.0 * c->score) + gscale_p; |
| 443 | lang_prob = c->score; |
| 444 | |
| 445 | // np->set_feature(lscorename,lang_prob+lprob); |
| 446 | if (p==0) |
| 447 | np->score = (lang_prob+lprob); |
| 448 | else |
| 449 | np->score = (lang_prob+lprob) + p->score; |
| 450 | |
| 451 | return np; |
| 452 | } |
| 453 | |
| 454 | static double find_b_prob(EST_VTPath *p,int n,int *state) |
| 455 | { |
| 456 | int oldstate=0; |
| 457 | double prob; |
| 458 | |
| 459 | if (p == 0) |
| 460 | { |
| 461 | int order = bb_ngram->order(); |
| 462 | EST_IVector window(order); |
| 463 | int i; |
| 464 | window.a_no_check(order-1) = n; |
| 465 | window.a_no_check(order-2) = B_word; |
| 466 | for (i=order-3; i>=0; i--) |
| 467 | window.a_no_check(i) = NB_word; |
| 468 | oldstate = bb_ngram->find_state_id(window); |
| 469 | } |
| 470 | else |
| 471 | oldstate = p->state; |
| 472 | const EST_DiscreteProbDistribution &pd = bb_ngram->prob_dist(oldstate); |
| 473 | if (pd.samples() == 0) |
| 474 | prob = 0; |
| 475 | else |
| 476 | prob = (double)pd.probability(n); |
| 477 | // This is too specific |
| 478 | if (n == B_word) |
| 479 | prob *= gscale_s; |
| 480 | *state = bb_ngram->find_next_state_id(oldstate,n); |
| 481 | |
| 482 | return prob; |
| 483 | |
| 484 | } |
| 485 | |
| 486 | /* Part of Interslice */ |
| 487 | |
| 488 | static double find_b_faprob(EST_VTPath *p,int n,int *state) |
| 489 | { |
| 490 | int oldstate=0; |
| 491 | int i,j; |
| 492 | EST_VTPath *d; |
| 493 | double prob; |
| 494 | double atime, wtime, wstddev=0, z=0.0; |
| 495 | static int ATOTH_BREAK=2; |
| 496 | static int ATOTH_NBREAK=1; |
| 497 | |
| 498 | if (p == 0) |
| 499 | { |
| 500 | oldstate = 0; |
| 501 | } |
| 502 | else |
| 503 | oldstate = p->state; |
| 504 | |
| 505 | /* if (streq("of", |
| 506 | ( p && p->c && p->c->s ? (const char *)ffeature(p->c->s,"name").String() : "null"))) |
| 507 | printf("ding\n"); */ |
| 508 | |
| 509 | // Prob is the prob that time since last break could be |
| 510 | // generated by the duration model |
| 511 | |
| 512 | // Skip over break if we're at one |
| 513 | for (i = oldstate; i < bb_track->num_frames(); i++) |
| 514 | { |
| 515 | if (bb_track->a(i,0) == ATOTH_NBREAK) |
| 516 | break; |
| 517 | } |
| 518 | |
| 519 | // time since last break in words with std |
| 520 | for (wstddev=wtime=0.0,d=p; d ; d=d->from) |
| 521 | { |
| 522 | wtime += ffeature(d->c->s,"word_duration").Float(); |
| 523 | wstddev += ffeature(d->c->s,"lisp_word_stddev").Float(); |
| 524 | if (bb_track->a(d->state,0) == ATOTH_BREAK) |
| 525 | break; |
| 526 | } |
| 527 | |
| 528 | // time since last break in acoustics |
| 529 | for (atime=0.01,j=i; j>0; j--) |
| 530 | { |
| 531 | if (bb_track->a(j,0) == ATOTH_BREAK) |
| 532 | break; |
| 533 | atime += bb_track->t(j) - ( i == 0 ? 0 : bb_track->t(j-1)); |
| 534 | } |
| 535 | |
| 536 | // Find best state for give time |
| 537 | if (wstddev == 0) |
| 538 | i++; |
| 539 | else if (n == B_word) |
| 540 | { /* cost of having a break here */ |
| 541 | /* extend acoustics until next break */ |
| 542 | for (; i < bb_track->num_frames(); i++) |
| 543 | { |
| 544 | if (bb_track->a(i,0) == ATOTH_BREAK) |
| 545 | break; |
| 546 | atime += bb_track->t(i) - ( i == 0 ? 0 : bb_track->t(i-1)); |
| 547 | } |
| 548 | z = fabs((atime-wtime)/wstddev); |
| 549 | } |
| 550 | else |
| 551 | { /* cost of having a non-break here */ |
| 552 | for ( i++,z = fabs((atime-wtime)/wstddev); |
| 553 | (i < bb_track->num_frames()) && (bb_track->a(i,0) == ATOTH_NBREAK); |
| 554 | i++) |
| 555 | { |
| 556 | atime += bb_track->t(i) - ( i == 0 ? 0 : bb_track->t(i-1)); |
| 557 | /* printf("better atime %f wtime %f wstddev %f z %f new z %f\n", |
| 558 | atime,wtime,wstddev,z, |
| 559 | fabs((atime-wtime)/wstddev)); */ |
| 560 | if (fabs((atime-wtime)/wstddev) > (float)z) |
| 561 | break; |
| 562 | else |
| 563 | z = fabs((atime-wtime)/wstddev); |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | |
| 568 | if (d && d->c && d->c->s && (d->c->s->next()->next()) == NULL__null) |
| 569 | { /* must be in final state */ |
| 570 | printf("must be in final state\n"); |
| 571 | if (i != bb_track->num_frames()) |
| 572 | z = 0.000001; |
| 573 | } |
| 574 | |
| 575 | if (z == 0) |
| 576 | printf("z == 0"); |
| 577 | |
| 578 | /* number hack */ |
| 579 | prob = (2.0 - z)/2.0; |
| 580 | /* prob = z; */ |
| 581 | if (prob < 0.000001) |
| 582 | prob = 0.000001; |
| 583 | else if (prob > 0.999999) |
| 584 | prob = 0.999999; |
| 585 | |
| 586 | // prob of atime given (wtime,wstddev) |
| 587 | printf("%d %d %f %f %f %f %s %s %f\n",oldstate,i,atime,wtime,wstddev,z, |
| 588 | ( p && p->c && p->c->s ? (const char *)ffeature(p->c->s,"name").String() : "null"), |
| 589 | ( n == B_word ? "B" : "NB"), |
| 590 | prob |
| 591 | ); |
| 592 | if (i >= bb_track->num_frames()) |
| 593 | i = bb_track->num_frames() - 1; |
| 594 | *state = i; |
| 595 | |
| 596 | return prob; |
| 597 | |
| 598 | } |
| 599 | |
| 600 | static EST_VTPath *bb_fapath(EST_VTPath *p,EST_VTCandidate *c,EST_Features &f) |
| 601 | { |
| 602 | EST_VTPath *np = new EST_VTPath; |
| 603 | (void)f; |
| 604 | // static EST_String lscorename("lscore"); |
| 605 | double prob; |
| 606 | double lprob,lang_prob; |
| 607 | |
| 608 | np->c = c; |
| 609 | np->from = p; |
| 610 | int n = c->name.Int(); |
| 611 | prob = find_b_faprob(p,n,&np->state); |
| 612 | if (prob == 0) |
| 613 | lprob = log(0.00000001); |
| 614 | else |
| 615 | lprob = log(prob); |
| 616 | |
| 617 | lang_prob = (1.0 * c->score) + gscale_p; |
Value stored to 'lang_prob' is never read | |
| 618 | lang_prob = c->score; |
| 619 | |
| 620 | // np->set_feature(lscorename,lang_prob+lprob); |
| 621 | if (p==0) |
| 622 | np->score = (lang_prob+lprob); |
| 623 | else |
| 624 | np->score = (lang_prob+lprob) + p->score; |
| 625 | |
| 626 | return np; |
| 627 | } |
| 628 | |
| 629 | static void phrasing_by_fa(EST_Utterance& u) |
| 630 | { |
| 631 | // Predict phrasing using POS and prob models of B distribution |
| 632 | EST_Item *w,*phr=0; |
| 633 | EST_String pbreak; |
| 634 | int num_states; |
| 635 | |
| 636 | pbyp_get_params(siod_get_lval("phr_break_params",NULL__null)); |
| 637 | gc_protect(&bb_tags); |
| 638 | |
| 639 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 640 | { // Set up tag index for pos ngram |
| 641 | EST_String lpos = map_pos(pos_map,w->f("pos").string()); |
| 642 | w->set("phr_pos",lpos); |
| 643 | w->set("pos_index",bb_pos_ngram->get_vocab_word(lpos)); |
| 644 | } |
| 645 | |
| 646 | num_states = bb_track->num_frames(); |
| 647 | |
| 648 | EST_Viterbi_Decoder v(bb_candlist,bb_fapath,num_states); |
| 649 | |
| 650 | v.initialise(u.relation("Word")); |
| 651 | v.search(); |
| 652 | v.result("pbreak_index"); |
| 653 | |
| 654 | // Given predicted break, go through and add phrases |
| 655 | u.create_relation("Phrase"); |
| 656 | for (w=u.relation("Word")->first(); w != 0; w = w->next()) |
| 657 | { |
| 658 | w->set("pbreak",bb_ngram-> |
| 659 | get_vocab_word(w->f("pbreak_index").Int())); |
| 660 | if (phr == 0) |
| 661 | phr = add_phrase(u); |
| 662 | append_daughter(phr,"Phrase",w); |
| 663 | if (phrase_type_tree != NIL((struct obj *) 0)) |
| 664 | { |
| 665 | EST_Val npbreak = wagon_predict(w,phrase_type_tree); |
| 666 | w->set("pbreak",npbreak.string()); // may reset to BB |
| 667 | } |
| 668 | pbreak = (EST_String)w->f("pbreak"); |
| 669 | if (pbreak == "B") |
| 670 | w->set("blevel",3); |
| 671 | else if (pbreak == "mB") |
| 672 | w->set("blevel",2); |
| 673 | if ((pbreak == "B") || (pbreak == "BB") || (pbreak == "mB")) |
| 674 | { |
| 675 | phr->set_name((EST_String)pbreak); |
| 676 | phr = 0; |
| 677 | } |
| 678 | } |
| 679 | |
| 680 | gc_unprotect(&bb_tags); |
| 681 | bb_tags = NIL((struct obj *) 0); |
| 682 | } |
| 683 | |
| 684 | |
| 685 | EST_Item *add_phrase(EST_Utterance& u) |
| 686 | { |
| 687 | EST_Item *item = u.relation("Phrase")->append(); |
| 688 | |
| 689 | item->set_name("phrase"); |
| 690 | |
| 691 | return item; |
| 692 | |
| 693 | } |
| 694 |