Bug Summary

File:modules/UniSyn/us_mapping.cc
Location:line 622, column 2
Description:Value stored to 'source_lab' 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: 6 Jan 1998 */
36/* --------------------------------------------------------------------- */
37/* LPC residual synthesis alternative version */
38/* */
39/*************************************************************************/
40
41#include "EST_error.h"
42#include "EST_inline_utils.h"
43#include "us_synthesis.h"
44
45#include "Phone.h"
46
47#include <fstream>
48
49using namespace std;
50
51// void make_segment_single_mapping(EST_Relation &source_lab,
52// EST_Track &source_pm,
53// EST_Track &target_pm, EST_IVector &map)
54// {
55// int i = 0;
56// int s_i_start, s_i_end, t_i_start, t_i_end;
57// EST_Item *s;
58// float s_end, s_start, t_end, t_start, f, m;
59// map.resize(target_pm.num_frames());
60
61// s_start = t_start = 0.0;
62
63// if (target_pm.t(target_pm.num_frames() - 1) <
64// source_lab.tail()->F("end",0))
65// {
66// EST_warning("Target pitchmarks end before end of target segment "
67// "timings (%f vs %f). Expect a truncated utterance\n",
68// target_pm.t(target_pm.num_frames() - 1),
69// source_lab.tail()->F("end",0.0));
70// }
71
72// //cout << "Source_pm" << source_pm.equal_space() << endl << endl;
73// //cout << "Target_pm" << target_pm.equal_space() << endl << endl;
74
75// for (s = source_lab.head(); s; s = s->next())
76// {
77// s_end = s->F("source_end");
78// t_end = s->F("end");
79
80// s_i_start = source_pm.index_below(s_start);
81// s_i_end = source_pm.index_below(s_end);
82// t_i_start = target_pm.index_below(t_start);
83// t_i_end = target_pm.index_below(t_end);
84
85// // fudge to make sure that at least one frame is available
86// if (s_i_end <= s_i_start)
87// s_i_end += 1;
88
89// //printf("%d %d %d %d\n", s_i_start, s_i_end, t_i_start, t_i_end);
90// //printf("%f %f %f %f\n\n", s_start, s_end, t_start, t_end);
91
92// m = float (s_i_end - s_i_start)/ float(t_i_end - t_i_start);
93// for (i = t_i_start, f = 0.0; i < t_i_end; ++i, ++f)
94// map[i] = EST_NINT(f * m) + s_i_start;
95// s_start = s->F("source_end");
96// t_start = s->F("end");
97// }
98// if (i == 0)
99// map.resize(0); // nothing to synthesize
100// else
101// map.resize(i - 1);
102// }
103
104
105void make_segment_single_mapping(EST_Relation &source_lab,
106 EST_Track &source_pm,
107 EST_Track &target_pm, EST_IVector &map)
108{
109 int i = 0;
110 int s_i_start, s_i_end, t_i_start, t_i_end;
111 EST_Item *s;
112 float s_end, s_start, t_end, t_start, m;
113 map.resize(target_pm.num_frames());
114
115 s_start = t_start = 0.0;
116 s_i_start = t_i_start = 0;
117
118 if (target_pm.t(target_pm.num_frames() - 1) <
119 source_lab.tail()->F("end",0))
120 {
121 EST_warning(EST_error_where = __null), (*EST_warning_func)("Target pitchmarks end before end of target segment "
122 "timings (%f vs %f). Expect a truncated utterance\n",
123 target_pm.t(target_pm.num_frames() - 1),
124 source_lab.tail()->F("end",0.0));
125 }
126
127
128
129 for (s = source_lab.head(); s; s = s->next())
130 {
131
132 // printf( "*********************************************\nphone %s\n", s->S("name").str());
133
134 s_end = s->F("source_end");
135 t_end = s->F("end");
136
137 s_i_end = source_pm.index_below(s_end);
138 t_i_end = target_pm.index_below(t_end);
139
140 // make sure that at least one frame is available
141 if (s_i_end <= s_i_start)
142 s_i_end += 1;
143
144// printf("(s_i_start s_i_end t_i_start t_i_end) %d %d %d %d\n",
145// s_i_start, s_i_end, t_i_start, t_i_end );
146// printf("(s_i_start-s_i_end t_i_start-t_i_end) %d %d\n",
147// s_i_end - s_i_start, t_i_end - t_i_start);
148
149
150
151 // OK for time alignment mapping function here to be single
152 // linear across subcomponents?...
153 // m = float(t_i_end-t_i_start+1)/float (s_i_end-s_i_start+1);
154 m = (t_end-t_start)/(s_end-s_start);
155 //m =1.0;
156 // printf( "m=%f\n", m );
157
158 // time offsets for relative times
159 float apm_t_off = (s_i_start==0) ? 0.0 : source_pm.t(s_i_start-1);
160 float tpm_t_off = (t_i_start==0) ? 0.0 : target_pm.t(t_i_start-1);
161
162// printf("apm_t_off = %f\ntpm_t_off = %f\n", apm_t_off, tpm_t_off);
163
164 int apm_i = s_i_start; // analysis pitch mark index
165 float apm_t = source_pm.t(apm_i)-apm_t_off;// analysis pitch mark time
166 float next_apm_t = source_pm.t(apm_i+1)-apm_t_off;
167
168 for( i=t_i_start; i<=t_i_end; ++i ){
169 float tpm_t = target_pm.t(i)-tpm_t_off; // target pitch mark time
170
171 // find closest pitchmark (assume only need forward search from current
172 // point, since pitchmarks should always be increasing)
173 while( (apm_i<=s_i_end) && (fabs((next_apm_t*m)-tpm_t) <= fabs((apm_t*m)-tpm_t)) ){
174// printf("(next_apm_t apm_t) %f %f\n",
175// fabs((next_apm_t*m)-tpm_t), fabs((apm_t*m)-tpm_t) );
176 apm_t = next_apm_t;
177 ++apm_i;
178 next_apm_t = source_pm.t(apm_i+1)-apm_t_off;
179 }
180
181// // printf( "tpm %d = apm %d\n", i, apm_i );
182
183// int slow_index = source_pm.index( target_pm(i) );
184
185// printf( "(my slow) %d %d\n", apm_i, slow_index );
186
187 map[i] = apm_i;
188 }
189
190 // for next loop
191 s_i_start = s_i_end+1;
192 t_i_start = t_i_end+1;
193 s_start = source_pm.t(s_i_start);
194 t_start = target_pm.t(t_i_start);
195
196 }
197 if (i == 0)
198 map.resize(0); // nothing to synthesize
199 else
200 map.resize(i);
201}
202
203
204void make_linear_mapping(EST_Track &pm, EST_IVector &map)
205{
206 int pm_num_frames = pm.num_frames();
207
208 map.resize(pm_num_frames);
209
210 for (int i = 0; i < pm_num_frames; ++i)
211 map[i] = i;
212}
213
214
215static bool contiguous( const EST_Item*left, const EST_Item* right )
216{
217 if( (item(left->f("source_ph1")))->next() == item(right->f("source_ph1")) )
218 return true;
219
220 return false;
221}
222
223
224// note this function overlooks the spacing of the 1st pitchmark (could
225// assume previous pitchmark at 0.0 time...)
226static void pitchmarksToSpaces( const EST_Track &pm, EST_IVector *spaces,
227 int start_pm, int end_pm, int wav_srate )
228{
229 int left_pm, right_pm;
230 int num_frames = end_pm-start_pm;
231 spaces->resize( num_frames, 0 );
232
233 left_pm = (int) rint( pm.t(start_pm)*wav_srate ); //should always be > 0
234 for( int i=0; i<num_frames; ++i ){
235 right_pm = (int) rint( pm.t(start_pm+i+1)*wav_srate );
236 (*spaces)[i] = right_pm - left_pm;
237 left_pm = right_pm;
238 }
239}
240
241
242void make_join_interpolate_mapping( const EST_Track &source_pm,
243 EST_Track &target_pm,
244 const EST_Relation &units,
245 EST_IVector &map )
246{
247 // would be good if this parameter was available from the current
248 // voice...
249 float wav_srate = wave(units.head()->f("sig"))->sample_rate();
250
251 // currently, the pitchmarks are just moved, there's no deletion or
252 // insertion
253 int target_pm_length = source_pm.length();
254 target_pm.resize(target_pm_length, source_pm.num_channels());
255
256 // places to keep temporary debugging information
257 EST_IVector source_spacing(target_pm_length);
258 EST_IVector target_spacing(target_pm_length);
259 EST_IVector voicing(target_pm_length);
260
261 // handle special case of first half of first diphone unit
262 EST_Item *diphone_left = units.head();
263
264 int left_start_index = diphone_left->I("middle_frame");
265 int left_end_index = source_pm.index(diphone_left->F("end"));
266
267 for( int i=0; i<left_start_index; ++i ){
268 target_pm.t(i) = source_pm.t(i);
269 voicing[i] = 0;
270 }
271 // middle loop
272 for( EST_Item *diphone_right=diphone_left->next();
273 diphone_right;
274 diphone_right=diphone_left->next() ){
275
276 printf( "%s\t%f\n", diphone_left->S("name").str(), diphone_left->F("end"));
277
278 int right_start_index = left_end_index + 1;
279 int right_end_index = right_start_index + diphone_right->I("middle_frame");
280
281 printf( "%d %d %d %d (l_start, l_end, r_start, r_end\n",
282 left_start_index,
283 left_end_index,
284 right_start_index,
285 right_end_index );
286
287 EST_String join_phone_name = item(diphone_left->f("ph1"))->next()->S("name");
288
289 cerr << "phone contigous " << contiguous(diphone_left,diphone_right) << endl;
290
291 ///////////DEBUG//////////////////////////////////////////////
292 int voicing_val;
293 if( ph_is_sonorant( join_phone_name ) &&
294 ! ph_is_silence( join_phone_name ) ){
295 voicing_val = 1;
296 }
297 else
298 voicing_val = 0;
299
300 for( int i=left_start_index; i<right_end_index; ++i )
301 voicing[i] = voicing_val;
302 ///////////DEBUG//////////////////////////////////////////////
303
304
305 //if not contigous and current phone is a sonorant, then do smoothing
306 if( (!contiguous(diphone_left,diphone_right)) &&
307 ph_is_sonorant( join_phone_name ) &&
308 (!ph_is_silence( join_phone_name) )){
309
310 cerr << "smoothing phone " << join_phone_name << "\n";
311
312 printf( "** Calculating spaces **\n" );
313
314 ///////////////////////////////////////////////////////////////////////
315 // calculate pitchmark spacings expressed as number of waveform samples
316 EST_IVector spaces;
317
318 pitchmarksToSpaces( source_pm, &spaces,
319 left_start_index, right_end_index,
320 (int)wav_srate );
321
322 int num_frames = right_end_index-left_start_index;
323
324 printf( "** Adjusting spaces**\n" );
325// ///////////////////////////////////////////////////////////////////////
326// // now smooth spacings (kind of recursive ad hoc averaging...)
327
328// for( int i=left_end_index-left_start_index; i>=0; --i ){
329// int ns = (spaces[i]+spaces[i+1])/2;
330// spaces[i+1] += spaces[i] - ns;
331// spaces[i] = ns;
332// }
333
334// for( int i=right_start_index-left_start_index; i<num_frames-1; ++i){
335// int ns = (spaces[i]+spaces[i+1])/2;
336// spaces[i+1] += spaces[i] - ns;
337// spaces[i] = ns;
338// }
339
340// printf("** new spaces ** \n" );
341// for( int i=0; i<num_frames; ++i )
342// printf( "space %d (%d) = %d samples\n", i, num_frames, spaces[i] );
343
344
345 int join_i = left_end_index-left_start_index;
346 int joindiff = spaces[join_i+1] - spaces[join_i];
347
348
349 const unsigned int DEFAULT_SMOOTHN = 5;
350
351
352 //modify left
353 int smoothn = min( DEFAULT_SMOOTHN, join_i );
354
355 for( int i=0; i<smoothn; ++i )
356 spaces[join_i-i] += (int) rint(joindiff*((float)(smoothn-i)/(2*smoothn)));
357
358 //modify right
359 joindiff = -joindiff;
360 smoothn = min( DEFAULT_SMOOTHN, num_frames-join_i );
361
362 for( int i=0; i<smoothn; ++i )
363 spaces[join_i+1+i] += (int) rint( joindiff*((float)(smoothn-i)/(2*smoothn)));
364
365
366 ////////////////////////////////////////////////////////////////////////
367 // copy modified pitchmark positions back into target_pm track
368 printf( "** using modified spaces ** \n" );
369
370 for( int i=left_start_index; i<right_end_index; ++i ){
371 printf( "Using space %d for target pitchmark %d\n", i-left_start_index, i );
372 target_pm.t(i) = target_pm.t(i-1) + ((float)spaces[i-left_start_index]/wav_srate);
373 }
374 }
375 else{
376 cerr << "no smoothing for " << join_phone_name << "\n";
377 for( int i=left_start_index; i<right_end_index; ++i ){
378 printf( "Using source pm %d for target pitchmark %d\n", i, i );
379 target_pm.t(i) = source_pm.t(i);
380 }
381 }
382
383 cerr <<endl;
384
385 // for the next iteration
386 left_start_index = right_end_index; // +1 ???
387 left_end_index = source_pm.index( diphone_right->F("end") );
388 diphone_left = diphone_right;
389 }
390
391 // copy the remaining pitchmarks
392 for( int i=left_start_index; i<target_pm_length; ++i )
393 target_pm.t(i) = source_pm.t(i);
394
395 make_linear_mapping( target_pm, map );
396
397 //////////////////////////////////////////////////////////////////////
398 // save for comparison before and after this smoothing function
399
400 // source spacing
401 pitchmarksToSpaces( source_pm,
402 &source_spacing,
403 0, target_pm_length-1,
404 (int)wav_srate );
405
406 ofstream outfile( "/home/korin/projects/smoothing_temp/f0/source_spacing.est" );
407 if( !outfile )
408 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open source pitchmark spacing output file" );
409
410 outfile << source_spacing << endl;
411 outfile.close();
412
413 // target spacing
414 pitchmarksToSpaces( target_pm,
415 &target_spacing,
416 0, target_pm_length-1,
417 (int)wav_srate );
418
419 ofstream afterfile( "/home/korin/projects/smoothing_temp/f0/target_spacing.est" );
420 if( !afterfile)
421 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open target pitchmark spacing output file" );
422
423 afterfile << target_spacing << endl;
424 afterfile.close();
425
426 ofstream voicingfile( "/home/korin/projects/smoothing_temp/f0/voicing.est" );
427 if( !voicingfile)
428 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open target pitchmark spacing output file" );
429
430 voicingfile << voicing << endl;
431 voicingfile.close();
432}
433
434void make_join_interpolate_mapping2( const EST_Track &source_pm,
435 EST_Track &target_pm,
436 const EST_Relation &units,
437 EST_IVector &map )
438{
439 // would be good if this parameter was available from the current
440 // voice...
441 float wav_srate = wave(units.head()->f("sig"))->sample_rate();
442
443 // currently, the pitchmarks are just moved, there's no deletion or
444 // insertion
445 int target_pm_length = source_pm.length();
446 target_pm.resize(target_pm_length, source_pm.num_channels());
447
448 // places to keep temporary debugging information
449 EST_IVector source_spacing(target_pm_length);
450 EST_IVector target_spacing(target_pm_length);
451 EST_IVector voicing(target_pm_length);
452
453 // handle special case of first half of first diphone unit
454 EST_Item *diphone_left = units.head();
455
456 int left_start_index = diphone_left->I("middle_frame");
457 int left_end_index = source_pm.index(diphone_left->F("end"));
458
459 for( int i=0; i<left_start_index; ++i ){
460 target_pm.t(i) = source_pm.t(i);
461 voicing[i] = 0;
462 }
463 // middle loop
464 for( EST_Item *diphone_right=diphone_left->next();
465 diphone_right;
466 diphone_right=diphone_left->next() ){
467
468 printf( "%s\t%f\n", diphone_left->S("name").str(), diphone_left->F("end"));
469
470 int right_start_index = left_end_index + 1;
471 int right_end_index = right_start_index + diphone_right->I("middle_frame");
472
473 printf( "%d %d %d %d (l_start, l_end, r_start, r_end\n",
474 left_start_index,
475 left_end_index,
476 right_start_index,
477 right_end_index );
478
479 EST_String join_phone_name = item(diphone_left->f("ph1"))->next()->S("name");
480
481 cerr << "phone contigous " << contiguous(diphone_left,diphone_right) << endl;
482
483 ///////////DEBUG//////////////////////////////////////////////
484 int voicing_val;
485 if( ph_is_sonorant( join_phone_name ) &&
486 ! ph_is_silence( join_phone_name ) ){
487 voicing_val = 1;
488 }
489 else
490 voicing_val = 0;
491
492 for( int i=left_start_index; i<right_end_index; ++i )
493 voicing[i] = voicing_val;
494
495 ///////////DEBUG//////////////////////////////////////////////
496
497
498// //if current phone is a sonorant, then add to concat_spaces wave to do
499// //smoothing at end of sonorant stretch
500// EST_Wave concat_spaces(10000, 1, 1); //sample rate is irrelevant
501// int cs_index=0;
502
503// EST_IVector spaces;
504// if( ph_is_sonorant( join_phone_name ) &&
505// (!ph_is_silence( join_phone_name) )){
506
507// cerr << "smoothing phone " << join_phone_name << "\n";
508
509// printf( "** Calculating spaces **\n" );
510
511// ///////////////////////////////////////////////////////////////////////
512// // calculate pitchmark spacings expressed as number of waveform samples
513// pitchmarksToSpaces( source_pm, &spaces,
514// left_start_index, right_end_index,
515// (int)wav_srate );
516
517// // copy into right part of concat_spaces
518// for( int i=0; i<spaces.length(); i++ )
519// concat_spaces.a_no_check(cs_index+i) = spaces[i];
520
521// cs_index += spaces.length();
522// }
523// else{
524// // if we have some saved up pitchmarks, process them, and continue as
525// // usual
526// if( cs_index > 0 ){
527// ////////////////////////////////////////////////////////////////////////
528// // filter them to modify
529
530
531// ////////////////////////////////////////////////////////////////////////
532// // copy modified pitchmark positions back into correct region of
533// // target_pm track
534// printf( "** using modified spaces ** \n" );
535
536// for( int i=left_start_index; i<right_end_index; ++i ){
537// printf( "Using space %d for target pitchmark %d\n", i-left_start_index, i );
538// target_pm.t(i) = target_pm.t(i-1) + ((float)spaces[i-left_start_index]/wav_srate);
539// }
540
541// // prepare for next voiced section
542// concat_spaces.fill(0);
543// cs_index = 0;
544// }
545
546 cerr << "no smoothing for " << join_phone_name << "\n";
547 for( int i=left_start_index; i<right_end_index; ++i ){
548 printf( "Using source pm %d for target pitchmark %d\n", i, i );
549 target_pm.t(i) = source_pm.t(i);
550 }
551
552
553 cerr <<endl;
554
555 // for the next iteration
556 left_start_index = right_end_index; // +1 ???
557 left_end_index = source_pm.index( diphone_right->F("end") );
558 diphone_left = diphone_right;
559 }
560
561 // copy the remaining pitchmarks
562 for( int i=left_start_index; i<target_pm_length; ++i )
563 target_pm.t(i) = source_pm.t(i);
564
565 make_linear_mapping( target_pm, map );
566
567 //////////////////////////////////////////////////////////////////////
568 // save for comparison before and after this smoothing function
569
570 // source spacing
571 pitchmarksToSpaces( source_pm,
572 &source_spacing,
573 0, target_pm_length-1,
574 (int)wav_srate );
575
576 ofstream outfile( "/home/korin/projects/smoothing_temp/f0/source_spacing.est" );
577 if( !outfile )
578 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open source pitchmark spacing output file" );
579
580 outfile << source_spacing << endl;
581 outfile.close();
582
583 // target spacing
584 pitchmarksToSpaces( target_pm,
585 &target_spacing,
586 0, target_pm_length-1,
587 (int)wav_srate );
588
589 ofstream afterfile( "/home/korin/projects/smoothing_temp/f0/target_spacing.est" );
590 if( !afterfile)
591 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open target pitchmark spacing output file" );
592
593 afterfile << target_spacing << endl;
594 afterfile.close();
595
596 ofstream voicingfile( "/home/korin/projects/smoothing_temp/f0/voicing.est" );
597 if( !voicingfile)
598 EST_error(EST_error_where = __null), (*EST_error_func)( "Couldn't open target pitchmark spacing output file" );
599
600 voicingfile << voicing << endl;
601 voicingfile.close();
602
603 if( const_cast<EST_Track&>(source_pm).save( "/home/korin/projects/smoothing_temp/f0/sourceCoef.est" )
604 != write_ok )
605 EST_warning(EST_error_where = __null), (*EST_warning_func)( "couldn't write sourceCoef.est file" );
606}
607
608
609void us_mapping(EST_Utterance &utt, const EST_String &method)
610{
611 EST_Relation *source_lab, *target_lab;
612 EST_IVector *map;
613 EST_Track *source_coef=0, *target_coef=0;
614
615 source_coef = track(utt.relation("SourceCoef")->head()->f("coefs"));
616 target_coef = track(utt.relation("TargetCoef")->head()->f("coefs"));
617
618 map = new EST_IVector;
619
620// cout << "mapping method: " << method << endl;
621 if (method != "segment_single")
622 source_lab = utt.relation("SourceSegments");
Value stored to 'source_lab' is never read
623 target_lab = utt.relation("Segment", 1);
624
625/* if (method == "segment")
626 make_segment_double_mapping(*source_lab, *source_coef, *target_lab,
627 *target_coef, *map);
628 else if (method == "dp_segment")
629 make_dp_mapping(*source_lab, *source_coef, *target_lab,
630 *target_coef, "Match", *map);
631 */
632 if (method == "linear")
633 make_linear_mapping(*source_coef, *map);
634 else if (method == "segment_single")
635 make_segment_single_mapping(*target_lab, *source_coef,
636 *target_coef, *map);
637 else if (method == "interpolate_joins"){
638 cerr << "Doing interpolate_joins\n";
639 EST_Relation *units = utt.relation("Unit");
640 make_join_interpolate_mapping(*source_coef, *target_coef, *units,*map);
641 }
642 else if (method == "interpolate_joins2"){
643 cerr << "Doing interpolate_joins2\n";
644 EST_Relation *units = utt.relation("Unit");
645 make_join_interpolate_mapping2(*source_coef, *target_coef, *units,*map);
646 }
647 else
648 EST_error(EST_error_where = __null), (*EST_error_func)("Mapping method \"%s\" not found\n", (const char *)method);
649
650 utt.create_relation("US_map");
651 EST_Item *item = utt.relation("US_map")->append();
652 item->set_val("map", est_val(map));
653}
654
655
656void add_wave_to_utterance(EST_Utterance &u, EST_Wave &sig,
657 const EST_String &name)
658{
659 u.create_relation(name);
660 EST_Item *item = u.relation(name)->append();
661 item->set_val("wave", est_val(&sig));
662}
663
664void map_to_relation(EST_IVector &map, EST_Relation &r,
665 const EST_Track &source_pm,
666 const EST_Track &target_pm)
667{
668 EST_Item *s, *t, *a=NULL__null;
669 EST_Utterance *u = r.utt();
670 int i;
671
672// cout << "source: " << source_pm;
673// cout << "target: " << target_pm;
674
675 u->create_relation("smap");
676 u->create_relation("tmap");
677
678 for (i = 0; i < source_pm.num_frames(); ++i)
679 {
680 s = u->relation("smap")->append();
681 s->set("index", i);
682 s->set("end", source_pm.t(i));
683 }
684
685 for (i = 0; i < target_pm.num_frames(); ++i)
686 {
687 s = u->relation("tmap")->append();
688 s->set("index", i);
689 s->set("end", target_pm.t(i));
690 }
691
692 EST_Item *last_s = 0;
693
694 for (s = u->relation("smap")->head(); s; s = s->next())
695 {
696 int n = s->I("index");
697 for (t = u->relation("tmap")->head(); t; t = t->next())
698 {
699 if (map(t->I("index")) == n)
700 {
701 if (last_s != s)
702 a = u->relation("lmap")->append(s);
703 last_s = s;
704 a->append_daughter(t);
705 t->set("map", n);
706 }
707 }
708 }
709}
710
711/*
712void make_segment_double_mapping(EST_Relation &source_lab,
713 EST_Track &source_pm,
714 EST_Relation &target_lab,
715 EST_Track &target_pm, EST_IVector &map)
716{
717 int i = 0;
718 int s_i_start, s_i_end, t_i_start, t_i_end;
719 EST_Item *s, *t;
720 float s_end, s_start, t_end, t_start, f, m;
721 map.resize(target_pm.num_frames());
722
723 s_start = t_start = 0.0;
724
725 if (target_pm.t(target_pm.num_frames() - 1) <
726 target_lab.tail()->F("end"))
727 EST_warning("Target pitchmarks end before end of target segment "
728 "timings. Expect a truncated utterance.\n");
729
730 for (s = source_lab.head(), t = target_lab.head(); s && t;
731 s = s->next(), t = t->next())
732 {
733 if (s->S("name") != t->S("name"))
734 cerr << "Warning: Source and Target segment names do not match: "
735 << s->S("name") << " " << t->S("name") << endl;
736
737 s_end = s->F("end");
738 t_end = t->F("end");
739
740 s_i_start = source_pm.index_below(s_start);
741 s_i_end = source_pm.index_below(s->F("end"));
742 t_i_start = target_pm.index_below(t_start);
743 t_i_end = target_pm.index_below(t->F("end"));
744
745 // fudge to make sure that at least one frame is available
746 if (s_i_end <= s_i_start)
747 s_i_end += 1;
748
749 // printf("%d %d %d %d\n", s_i_start, s_i_end, t_i_start, t_i_end);
750 // printf("%f %f %f %f\n", s_start, s_end, t_start, t_end);
751
752 m = float (s_i_end - s_i_start)/ float(t_i_end - t_i_start);
753 for (i = t_i_start, f = 0.0; i < t_i_end; ++i, ++f)
754 map[i] = EST_NINT(f * m) + s_i_start;
755
756 s_start = s->F("end");
757 t_start = t->F("end");
758 }
759 if (i == 0)
760 map.resize(0); // nothing to synthesize
761 else
762 map.resize(i - 1);
763}
764
765
766void make_dp_mapping(EST_Relation &source_lab, EST_Track &source_pm,
767 EST_Relation &target_lab, EST_Track &target_pm,
768 const EST_String &match_name, EST_IVector &map)
769{
770 int i = 0, j;
771 int s_i_start, s_i_end, t_i_start, t_i_end;
772 EST_Item *s, *t;
773 float s_end, s_start, t_end, t_start, f, m, prev_end;
774 map.resize(target_pm.num_frames());
775
776 map.fill(-1);
777
778 s_start = t_start = 0.0;
779
780 // should really be replaced by feature functions.
781 for (prev_end = 0.0, s = source_lab.head(); s; s = s->next())
782 {
783 s->set("start", prev_end);
784 prev_end = s->F("end");
785 }
786
787 // should really be replaced by feature functions.
788 for (prev_end = 0.0, s = target_lab.head(); s; s = s->next())
789 {
790 s->set("start", prev_end);
791 prev_end = s->F("end");
792 }
793
794 if (target_pm.t(target_pm.num_frames() - 1) <
795 target_lab.tail()->F("end", 1))
796 EST_warning("Target pitchmarks end before end of target segment "
797 "timings. Expect a truncated utterance.\n");
798
799 for (s = source_lab.head(); s; s = s->next())
800 {
801 s_start = s->F("start");
802
803 cout << "source: " << *s << endl;
804
805 while (s && (!s->in_relation(match_name)))
806 s = s->next();
807
808 cout << "active source: " << *s << endl;
809
810 s_end = s->F("end");
811
812 cout << "daughter: " << daughter1(s->as_relation(match_name)) << endl;
813 cout << "parent: " << parent(s->as_relation(match_name)) << endl;
814
815 t = parent(s->as_relation(match_name));
816
817 cout << "active target: " << *t << endl;
818
819 t_end = t->F("end");
820 t_start = t->F("start");
821
822 s_i_start = source_pm.index_below(s_start);
823 s_i_end = source_pm.index_below(s->F("end"));
824 t_i_start = target_pm.index_below(t_start);
825 t_i_end = target_pm.index_below(t->F("end"));
826
827 // fudge to make sure that at least one frame is available
828 if (s_i_end <= s_i_start)
829 s_i_end += 1;
830
831 //printf("%d %d %d %d\n", s_i_start, s_i_end, t_i_start, t_i_end);
832 //printf("%f %f %f %f\n", s_start, s_end, t_start, t_end);
833
834 m = float (s_i_end - s_i_start)/ float(t_i_end - t_i_start);
835 for (i = t_i_start, f = 0.0; i < t_i_end; ++i, ++f)
836 map[i] = EST_NINT(f * m) + s_i_start;
837
838 cout << endl;
839
840 }
841
842 for (i = 0, j = 0; i < target_pm.num_frames(); ++i)
843 {
844 cout << map(i) << " ";
845 if (map(i) != -1)
846 {
847 map[j] = map(i);
848 cout << map(j) << " ";
849 target_pm.t(j++) = target_pm.t(i);
850 }
851 }
852
853 if (j == 0)
854 map.resize(0); // nothing to synthesize
855 else
856 map.resize(j);
857}
858*/