Bug Summary

File:modules/UniSyn_diphone/us_diphone_index.cc
Location:line 480, column 5
Description:Value stored to 'index' is never read

Annotated Source Code

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/* */
34/* Author: Paul Taylor */
35/* Date: 1998, 1999 */
36/* --------------------------------------------------------------------- */
37/* LPC residual synthesis alternative version */
38/* */
39/*************************************************************************/
40
41#include "siod.h"
42#include "EST.h"
43#include "us_diphone.h"
44#include "Phone.h"
45
46using namespace std;
47
48static bool US_full_coefs = false;
49USDiphIndex *diph_index = 0;
50extern LISP us_dbs;
51
52static void us_get_all_diphones(EST_Relation &diphone);
53static void load_grouped_diphone(int unit);
54void get_diphone(EST_Item &d);
55static int find_diphone_index_simple(const EST_String &d,USDiphIndex &di);
56void us_check_db();
57void us_add_diphonedb(USDiphIndex *db);
58void load_full_diphone(int unit);
59
60VAL_REGISTER_CLASS(us_db,USDiphIndex)val_type val_type_us_db="us_db"; class USDiphIndex *us_db(const
EST_Val &v) { if (v.type() == val_type_us_db) return (class
USDiphIndex *)v.internal_ptr(); else (EST_error_where = __null
), (*EST_error_func)("val not of type val_type_""us_db"); return
__null; } static void val_delete_us_db(void *v) { delete (class
USDiphIndex *)v; } EST_Val est_val(const class USDiphIndex *
v) { return EST_Val(val_type_us_db, (void *)v,val_delete_us_db
); }
61SIOD_REGISTER_CLASS(us_db,USDiphIndex)class USDiphIndex *us_db(LISP x) { return us_db(val(x)); } int
us_db_p(LISP x) { if (val_p(x) && (val_type_us_db ==
val(x).type())) return (1==1); else return (1==0); } LISP siod
(const class USDiphIndex *v) { if (v == 0) return ((struct obj
*) 0); else return siod(est_val(v)); }
62
63USDiphIndex::USDiphIndex() : dihash(1500)
64{
65 gc_protect(&params);
66}
67
68USDiphIndex::~USDiphIndex()
69{
70 gc_unprotect(&params);
71
72}
73
74void us_check_db()
75{
76 if (diph_index == 0)
77 EST_error(EST_error_where = __null), (*EST_error_func)("US DB: no diphone database loaded\n");
78 diph_index->ts.restart();
79}
80
81void awb_free_diph_index()
82{
83 /* chaising memory leaks */
84 if (diph_index != 0)
85 {
86 delete diph_index;
87 diph_index = 0;
88 }
89}
90
91/*static EST_String get_diphone_name(EST_Item *item,const EST_String dir)
92{
93 // Get diphone name which may differ from phone name
94 // Looks for us_diphone_<dir>, us_diphone, or name in that order
95 EST_String d1;
96 static EST_String dname = "us_diphone";
97
98 if (!item)
99 return "";
100 else if ((d1 = item->S(dname+"_"+dir)) != "0")
101 return d1;
102 else if ((d1 = item->S(dname)) != "0")
103 return d1;
104 else
105 return item->S("name");
106}
107*/
108
109static EST_String get_diphone_name(EST_Item *item,const EST_String dir)
110{
111 // Get diphone name which may differ from phone name
112 // Looks for us_diphone_<dir>, us_diphone, or name in that order
113 EST_String d1;
114 static EST_String dname = "us_diphone";
115 static EST_String def = "0";
116
117 if (!item)
118 return "";
119 else if ((d1 = (EST_String)item->f(dname+"_"+dir,def)) != "0")
120 return d1;
121 else if ((d1 = (EST_String)item->f(dname,def)) != "0")
122 return d1;
123 else
124 return item->f("name","0").string();
125}
126
127
128void us_get_diphones(EST_Utterance &utt)
129{
130 // Create unit stream with coefficients and signals for each
131 // diphone
132 EST_Item *p, *d;
133 EST_String name1, name2, file;
134
135 us_check_db();
136
137 if (!utt.relation_present("Unit"))
138 utt.create_relation("Unit");
139
140 US_full_coefs = (siod_get_lval("us_full_coefs", NULL__null) == NIL((struct obj *) 0))
141 ? false : true;
142
143 p = utt.relation("Segment")->head();
144 name1 = get_diphone_name(p,"left"); // left part of first diphone
145
146 utt.relation("Unit")->f.set("grouped", ((diph_index->grouped) ? 1 : 0));
147
148 if (!diph_index->grouped)
149 {
150 utt.relation("Unit")->f.set("coef_dir", diph_index->coef_dir);
151 utt.relation("Unit")->f.set("sig_dir", diph_index->sig_dir);
152 utt.relation("Unit")->f.set("coef_ext", diph_index->coef_ext);
153 utt.relation("Unit")->f.set("sig_ext", diph_index->sig_ext);
154 }
155
156 for (p = p->next(); p; p = p->next())
157 {
158 d = utt.relation("Unit")->append();
159 name2 = get_diphone_name(p,"right");
160 d->set("name", (name1 + "-" + name2));
161 get_diphone(*d);
162 name1 = get_diphone_name(p,"left");
163 }
164
165// utt.create_relation("SourceSegments");
166// for (p = utt.relation("Segment", 1)->head(); p; p = p->next())
167// {
168// d = utt.relation("SourceSegments")->append();
169// d->set_name(p->name());
170// }
171
172 if (!US_full_coefs)
173 parse_diphone_times(*(utt.relation("Unit", 1)),
174 *(utt.relation("Segment", 1)));
175}
176
177LISP us_check_diphone_presence(LISP name)
178{
179 /* requested by "Nicholas Volk" <nvolk@bitlips.fi> */
180 int x = find_diphone_index_simple(get_c_string(name),*diph_index);
181 if ( x < 0 )
182 return NIL((struct obj *) 0);
183 else
184 return name;
185}
186
187LISP us_make_group_file(LISP lname, LISP params)
188{
189 EST_String group_file, index_file;
190 EST_String track_file_format, sig_file_format, sig_sample_format;
191 EST_Relation diphone;
192 EST_TokenStream ts;
193 EST_Item *d;
194 EST_Wave *sig;
195 EST_Track *tr;
196 FILE *fp, *fp_group;
197 const int block_size = 1024;
198 int pos;
199
200 us_check_db();
201
202 track_file_format = get_param_str("track_file_format",params,"est_binary");
203 sig_file_format = get_param_str("sig_file_format",params,"snd");
204 sig_sample_format = get_param_str("sig_sample_format",params,"mulaw");
205
206 group_file = make_tmp_filename();
207 group_file += ".group";
208 index_file = get_c_string(lname);
209 us_get_all_diphones(diphone);
210
211 if ((fp = fopen(group_file, "wb")) == NULL__null)
212 EST_error(EST_error_where = __null), (*EST_error_func)("US DB: failed to open group file as temporary file\n");
213
214 for (d = diphone.head(); d; d = d->next())
215 {
216 sig = wave(d->f("sig"));
217 tr = track(d->f("coefs"));
218
219 pos = ftell(fp);
220 d->set("track_start", pos);
221 tr->save(fp, track_file_format);
222
223 pos = ftell(fp);
224 d->set("wave_start", pos);
225 sig->save_file(fp, sig_file_format, sig_sample_format, EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little
)
);
226 }
227 fclose(fp);
228
229 if ((fp = fopen(index_file, "wb")) == NULL__null)
230 EST_error(EST_error_where = __null), (*EST_error_func)("US DB: failed to open group file \"%s\" for writing\n",
231 (const char *) index_file);
232
233 fprintf(fp, "EST_File index\n");
234 fprintf(fp, "DataType ascii\n");
235 fprintf(fp, "NumEntries %d\n", diphone.length());
236 fprintf(fp, "IndexName %s\n", (const char *)diph_index->name);
237 fprintf(fp, "DataFormat grouped\n");
238 fprintf(fp, "Version 2\n");
239 fprintf(fp, "track_file_format %s\n",(const char *)track_file_format);
240 fprintf(fp, "sig_file_format %s\n",(const char *)sig_file_format);
241 fprintf(fp, "EST_Header_End\n");
242
243 for (d = diphone.head(); d; d = d->next())
244 fprintf(fp, "%s %d %d %d\n", (const char *)d->S("name"),
245 d->I("track_start"), d->I("wave_start"),
246 d->I("middle_frame"));
247
248 // Copy binary data from temporary group file to end of
249 // real group file
250 char buf[block_size];
251 int r;
252
253 if ((fp_group = fopen(group_file, "rb")) == NULL__null)
254 {
255 fprintf(stderrstderr,"Unexpected lost temporary group file from \"%s\"\n",
256 (const char *)group_file);
257 return NIL((struct obj *) 0);
258 }
259
260 while ((r = fread(buf, sizeof(char), block_size, fp_group)) != 0)
261 fwrite(buf, sizeof(char), r, fp);
262
263 fclose(fp);
264 fclose(fp_group);
265 unlink(group_file);
266
267 return NIL((struct obj *) 0);
268}
269
270static void us_get_all_diphones(EST_Relation &diphone)
271{
272 EST_Item *d;
273 EST_String name1;
274
275 for (int i = 0; i < diph_index->diphone.n(); ++i)
276 {
277 d = diphone.append();
278 d->set("name", diph_index->diphone[i].S("name"));
279 get_diphone(*d);
280 }
281}
282
283int read_diphone_index(const EST_String &filename,
284 USDiphIndex &di)
285{
286 EST_TokenStream ts;
287 int i, ref;
288 int num_entries;
289 EST_Option hinfo;
290 EST_EstFileType t;
291 EST_String v, pointer, n;
292 bool ascii;
293 EST_read_status r;
294 EST_Item d;
295
296 di.index_offset = 0;
297
298 if (ts.open(filename) != 0)
299 {
300 cerr << "US DB: can't open index file " << filename << endl;
301 return misc_read_errorread_error;
302 }
303 // set up the character constant values for this stream
304 ts.set_SingleCharSymbols(";");
305
306 if ((r = read_est_header(ts, hinfo, ascii, t)) != format_okread_ok)
307 return r;
308 if (t != est_file_index)
309 return misc_read_errorread_error;
310
311 num_entries = hinfo.ival("NumEntries");
312 di.grouped = (hinfo.val("DataFormat") == "grouped") ? true : false;
313 di.diphone.resize(num_entries);
314
315 if (di.grouped)
316 {
317 di.track_file_format = hinfo.val_def("track_file_format","est");
318 di.sig_file_format = hinfo.val_def("sig_file_format","est");
319 for (i = 0; i < num_entries; ++i)
320 {
321 di.diphone[i].set("name", ts.get().string());
322 di.diphone[i].set("count", 0);
323 di.diphone[i].set("track_start", atoi(ts.get().string()));
324 di.diphone[i].set("wave_start", atoi(ts.get().string()));
325 di.diphone[i].set("middle_frame", atoi(ts.get().string()));
326 di.dihash.add_item(di.diphone[i].f("name"),i);
327 }
328 di.index_offset = ts.tell();
329 // cout << "index offset = " << di.index_offset << endl;
330 }
331 else
332 {
333 int n_num_entries = num_entries;
334 for (i = 0; i < n_num_entries; ++i)
335 {
336 if (ts.eof())
337 EST_error(EST_error_where = __null), (*EST_error_func)("US DB: unexpected EOF in \"%s\": %d entries "
338 "instead of %s\n", (const char *)filename,
339 i, num_entries);
340
341 n = ts.get().string();
342 di.diphone[i].set("name", n);
343 di.diphone[i].set("filename", ts.get().string());
344 di.diphone[i].set("count", 0);
345 if (!di.diphone[i].S("filename").contains("&", 0))
346 {
347 di.diphone[i].set("start", atof(ts.get().string()));
348 di.diphone[i].set("middle", atof(ts.get().string()));
349 di.diphone[i].set("end", ts.get().string());
350 if ((di.diphone[i].F("start")>=di.diphone[i].F("middle"))||
351 (di.diphone[i].F("middle") >= di.diphone[i].F("end")))
352 {
353 cerr << "US DB: diphone index for " << n <<
354 " start middle end not in order, ignored " << endl;
355 i--;
356 n_num_entries--;
357 }
358 }
359 di.dihash.add_item(n,i);
360 }
361
362 // now copy reference entries
363 for (i = 0; i < n_num_entries; ++i)
364 if (di.diphone[i].S("filename").contains("&", 0))
365 {
366 pointer = di.diphone[i].S("filename").after("&", 0);
367// cout << "pointer: = " << pointer << endl;
368 if ((ref = find_diphone_index_simple(pointer,di)) == -1)
369 {
370 cerr << "US DB: Illegal diphone pointer in index file: "
371 << i << " "
372 << di.diphone[i].S("name") << " -> " <<
373 di.diphone[i].S("filename") << endl;
374 EST_error(EST_error_where = __null), (*EST_error_func)("");
375 }
376 di.diphone[i].set("filename",
377 di.diphone[ref].S("filename"));
378 di.diphone[i].set("start", di.diphone[ref].S("start"));
379 di.diphone[i].set("middle", di.diphone[ref].S("middle"));
380 di.diphone[i].set("end", di.diphone[ref].S("end"));
381 // accurate values of these depend on where the
382 // pitchmarks are placed.
383 // di.diphone[i].fset("first_dur",di.diphone[ref].fS("first_dur"));
384 // di.diphone[i].fset("second_dur",
385 //di.diphone[ref].fS("second_dur"));
386 }
387 }
388
389 return format_okread_ok;
390}
391
392void get_diphone(EST_Item &d)
393{
394 int unit;
395
396 unit = find_diphone_index(d);
397
398 if (diph_index->diphone[unit].f("count") == 0)
399 {
400 if (diph_index->grouped)
401 load_grouped_diphone(unit);
402 else
403 {
404 if (US_full_coefs)
405 load_full_diphone(unit);
406 else
407 load_separate_diphone(unit, false, "all");
408 }
409 diph_index->diphone[unit].set("count", d.I("count", 0) + 1);
410 }
411
412 if (US_full_coefs)
413 {
414 d.set_val("full_sig", diph_index->diphone[unit].f("full_sig"));
415 d.set_val("full_coefs", diph_index->diphone[unit].f("full_coefs"));
416 }
417 else
418 {
419 d.set_val("sig", diph_index->diphone[unit].f("sig"));
420 d.set_val("coefs", diph_index->diphone[unit].f("coefs"));
421 d.set_val("middle_frame",
422 diph_index->diphone[unit].f("middle_frame"));
423 }
424
425 if (!diph_index->grouped)
426 {
427 d.set_val("filename", diph_index->diphone[unit].f("filename"));
428 d.set_val("diphone_start", diph_index->diphone[unit].F("start"));
429 d.set_val("diphone_middle", diph_index->diphone[unit].F("middle"));
430 d.set_val("diphone_end", diph_index->diphone[unit].F("end"));
431 }
432}
433
434static void load_grouped_diphone(int unit)
435{
436 int middle_frame;
437 EST_Track *coefs;
438 EST_Wave *sig;
439 int wave_start, track_start;
440
441 coefs = new EST_Track;
442 sig = new EST_Wave;
443
444 track_start = diph_index->diphone[unit].I("track_start");
445 wave_start = diph_index->diphone[unit].I("wave_start");
446 middle_frame = diph_index->diphone[unit].I("middle_frame");
447
448 diph_index->ts.seek(track_start + diph_index->index_offset);
449 coefs->load(diph_index->ts); // type is self determined at present
450
451 diph_index->ts.seek(wave_start + diph_index->index_offset);
452 sig->load(diph_index->ts,diph_index->sig_file_format);
453
454 diph_index->diphone[unit].set_val("coefs", est_val(coefs));
455 diph_index->diphone[unit].set("middle_frame", middle_frame);
456
457 diph_index->diphone[unit].set_val("sig", est_val(sig));
458}
459
460
461static int find_diphone_index_simple(const EST_String &d,USDiphIndex &di)
462{
463 int found,r;
464
465 r = di.dihash.val(d,found);
466 if (found)
467 return r;
468 else
469 return -1;
470}
471
472int find_diphone_index(const EST_Item &d)
473{
474 // Find the approrpiate entry in the diphone index table
475 // mapping to alternates if required.
476 int index;
477 EST_String diname = d.f("name");
478
479 // If all goes well the diphone will be found directly in the index
480 index=find_diphone_index_simple(diname,*diph_index);
Value stored to 'index' is never read
481 if ((index=find_diphone_index_simple(diname,*diph_index)) != -1)
482 return index;
483
484 // But for various reasons it might not be there so allow
485 // a run time specification of alternates. This isn't optimal
486 // but is better than falling immediately back on just a default
487 // diphone
488 LISP alt_left = get_param_lisp("alternates_left",diph_index->params,NIL((struct obj *) 0));
489 LISP alt_right = get_param_lisp("alternates_right",diph_index->params,NIL((struct obj *) 0));
490 EST_String di_left = diname.before("-");
491 EST_String di_right = diname.after("-");
492 EST_String di_left_alt = get_param_str(di_left,alt_left,di_left);
493 EST_String di_right_alt = get_param_str(di_right,alt_right,di_right);
494 EST_String di_alt = di_left_alt+"-"+di_right_alt;
495
496 if ((index=find_diphone_index_simple(di_alt,*diph_index)) != -1)
497 {
498// cout << "UniSyn: using alternate diphone " << di_alt << " for " <<
499// diname << endl;
500 return index;
501 }
502
503 // It really isn't there so return the default one and print and error
504 // now
505 EST_String default_diphone =
506 get_param_str("default_diphone",diph_index->params,"");
507
508 if (default_diphone != "")
509 {
510 index = find_diphone_index_simple(default_diphone,*diph_index);
511 if (index == -1)
512 {
513 cerr << "US DB: can't find diphone " << d.f("name")
514 << " and even default diphone (" << default_diphone
515 << ") doesn't exist" << endl;
516 EST_error(EST_error_where = __null), (*EST_error_func)("");
517 }
518 else
519 cerr << "UniSyn: using default diphone " << default_diphone <<
520 " for " << diname << endl;
521 return index;
522 }
523 else
524 {
525 cerr << "US DB: can't find diphone " << d.f("name") <<
526 " nor alternatives" << endl;
527 EST_error(EST_error_where = __null), (*EST_error_func)("");
528 }
529 return -1;
530}
531
532void us_full_cut(EST_Relation &unit)
533{
534 EST_Track *full_coefs, *sub_coefs;
535 EST_Wave *full_sig, sub_sig;
536 EST_Item *s;
537 int pm_start, pm_end, pm_middle;
538 int samp_start, samp_end;
539 float start_time;
540
541 for (s = unit.head(); s; s = s->next())
542 {
543 sub_coefs = new EST_Track;
544
545 full_coefs = track(s->f("full_coefs"));
546 full_sig = wave(s->f("full_sig"));
547
548 pm_start = full_coefs->index(s->F("diphone_start"));
549 pm_middle = full_coefs->index(s->F("diphone_middle"));
550 pm_end = full_coefs->index(s->F("diphone_end"));
551
552 full_coefs->copy_sub_track(*sub_coefs, pm_start,
553 pm_end - pm_start + 1);
554
555 start_time = full_coefs->t(Gof((pm_start - 1), 0)((((pm_start - 1)) > (0)) ? ((pm_start - 1)) : (0)));
556
557 for (int j = 0; j < sub_coefs->num_frames(); ++j)
558 sub_coefs->t(j) = sub_coefs->t(j) - start_time;
559
560
561 s->set("middle_frame", pm_middle - pm_start -1);
562 s->set_val("coefs", est_val(sub_coefs));
563
564 // go to the periods before and after
565 samp_start = (int)(full_coefs->t(Gof((pm_start - 1), 0)((((pm_start - 1)) > (0)) ? ((pm_start - 1)) : (0)))
566 * (float)full_sig->sample_rate());
567 if (pm_end+1 < full_coefs->num_frames())
568 pm_end++;
569 samp_end = (int)(full_coefs->t(pm_end)
570 * (float)full_sig->sample_rate());
571
572
573 full_sig->sub_wave(sub_sig, samp_start, samp_end - samp_start + 1);
574 EST_Wave *sig = new EST_Wave(sub_sig);
575
576 s->set_val("sig", est_val(sig));
577
578 }
579}
580
581
582void us_add_diphonedb(USDiphIndex *db)
583{
584 // Add this to list of loaded diphone dbs and select it
585 LISP lpair;
586
587 if (us_dbs == NIL((struct obj *) 0))
588 gc_protect(&us_dbs);
589
590 lpair = siod_assoc_str(db->name,us_dbs);
591
592 if (lpair == NIL((struct obj *) 0))
593 { // new diphone db of this name
594 us_dbs = cons(cons(rintern(db->name),
595 cons(siod(db),NIL((struct obj *) 0))),
596 us_dbs);
597 }
598 else
599 { // already one of this name
600 cerr << "US_db: warning redefining diphone database "
601 << db->name << endl;
602 setcar(cdr(lpair),siod(db));
603 }
604
605 diph_index = db;
606}
607