1 /*************************************************************************/
2 /*                                                                       */
3 /*                  Language Technologies Institute                      */
4 /*                     Carnegie Mellon University                        */
5 /*                      Copyright (c) 1999-2004                          */
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: July 2001                                     */
35 /* --------------------------------------------------------------------- */
36 /*  Some more interesting join methods                                   */
37 /*       based on the mapping code in UniSyn                             */
38 /*                                                                       */
39 /*************************************************************************/
40 
41 #include "EST_error.h"
42 #include "us_synthesis.h"
43 #include "festival.h"
44 
45 #if 0
46 static int awb_voiced(EST_Track &pm,int i)
47 {
48     // Hacky guess at voicedness
49     return TRUE;
50     if ((i < 2) || (i+3 > pm.num_frames()))
51 	return FALSE;
52     else if (((pm.t(i) - pm.t(i-1)) == (pm.t(i+1) - pm.t(i))) &&
53 	     ((pm.t(i-1) - pm.t(i-2)) == (pm.t(i) - pm.t(i-1))))
54 	return FALSE;
55     else
56 	return TRUE;
57 }
58 
59 static float frame_duration(EST_Track &pm, int i)
60 {
61     if (i <= 0)
62 	return frame_duration(pm,i+1);
63     else if (i >= pm.num_frames())
64 	return frame_duration(pm,pm.num_frames()-1);
65     else
66 	return pm.t(i)-pm.t(i-1);
67 }
68 
69 static float awb_smoothed(EST_Track &pm, int i)
70 {
71     // Returned smoothed pitch period at i
72 
73     return (frame_duration(pm,i-4)+
74 	    frame_duration(pm,i-3)+
75 	    frame_duration(pm,i-2)+
76 	    frame_duration(pm,i-1)+
77 	    frame_duration(pm,i)+
78 	    frame_duration(pm,i+1)+
79 	    frame_duration(pm,i+2))/7.0;
80 }
81 #endif
82 
83 
make_segment_varied_mapping(EST_Relation & source_lab,EST_Track & source_pm,EST_Track & target_pm,EST_IVector & map,float dur_impose_factor,float f0_impose_factor)84 static void make_segment_varied_mapping(EST_Relation &source_lab,
85 					EST_Track &source_pm,
86 					EST_Track &target_pm,
87 					EST_IVector &map,
88 					float dur_impose_factor,
89 					float f0_impose_factor)
90 {
91     int n_i, s_i, u_i, u_frames;
92     int spp;
93     float stime, ttime, ltime, dratio, n_frames;
94     int max_frames;
95     EST_Item *u;
96     EST_Track ntarget_pm;
97 
98     ntarget_pm = target_pm;
99     if (target_pm.num_frames() > source_pm.num_frames())
100 	max_frames = target_pm.num_frames()+100;
101     else
102 	max_frames = source_pm.num_frames()+100;
103 
104     ntarget_pm.resize(max_frames,target_pm.num_channels());
105     map.resize(max_frames);
106 
107 //    printf("source_lab relations is %s\n",(const char *)source_lab.name());
108 
109     if (target_pm.t(target_pm.num_frames() - 1) <
110 	source_lab.tail()->F("end",0))
111     {
112 	EST_warning("Target pitchmarks end before end of target segment "
113 		    "timings (%f vs %f). Expect a truncated utterance\n",
114 		    target_pm.t(target_pm.num_frames() - 1),
115 	            source_lab.tail()->F("end",0.0));
116     }
117 
118     n_i = 0;
119     s_i = 0;
120     ltime = 0;
121     for (u = source_lab.head(); u; u = u->next())
122     {
123 	u_frames = u->I("num_frames");
124 //	stime = source_pm.t(s_i+u_frames-1) - source_pm.t(s_i);
125 	stime = u->F("unit_duration");
126 	ttime = ffeature(u,"segment_duration");
127 	if (streq("+",(EST_String)ffeature(u,"ph_vc")))
128 	    dratio = stime / (stime + ((ttime-stime)*dur_impose_factor));
129 	else
130 	    dratio = 1;
131 	n_frames = (float)u_frames / dratio;
132 /*	printf("unit %s dratio %f %d %f time %f, stime %f\n",
133 	       (const char *)u->name(),dratio,u_frames,n_frames,
134 	       ttime,stime); */
135 
136  	for (u_i = 0; u_i < n_frames; u_i++,n_i++)
137 	{
138 	    spp = (int)((float)u_i*dratio);
139 
140 	    if (s_i + spp == 0)
141 		ntarget_pm.t(n_i) = ltime;
142 	    else
143 		ntarget_pm.t(n_i) = ltime + source_pm.t(s_i+spp)-
144 		    source_pm.t(s_i+spp-1);
145 	    map[n_i] = s_i+spp;
146 	    ltime = ntarget_pm.t(n_i);
147 	    if (n_i+1 == ntarget_pm.num_frames())
148 		break;
149 	}
150 	s_i += u_frames;
151 
152     }
153 
154     ntarget_pm.resize(n_i,ntarget_pm.num_channels());
155 
156 /*    printf("target_pm.end() = %f ntarget_pm.end() = %f\n",
157       target_pm.end(), ntarget_pm.end()); */
158     target_pm = ntarget_pm;
159 /*    printf("target_pm.end() = %f ntarget_pm.end() = %f\n",
160       target_pm.end(), ntarget_pm.end()); */
161     if (n_i == 0)
162 	map.resize(0);  // nothing to synthesize
163     else
164 	map.resize(n_i - 1);
165 }
166 
cl_mapping(EST_Utterance & utt,LISP params)167 void cl_mapping(EST_Utterance &utt, LISP params)
168 {
169     EST_Relation *target_lab;
170     EST_IVector *map;
171     EST_Track *source_coef=0, *target_coef=0;
172     float dur_impose_factor, f0_impose_factor;
173 
174     source_coef = track(utt.relation("SourceCoef")->head()->f("coefs"));
175     target_coef = track(utt.relation("TargetCoef")->head()->f("coefs"));
176     target_lab = utt.relation("Segment");
177 
178     map = new EST_IVector;
179 
180     dur_impose_factor = get_param_float("dur_impose_factor",params,0.0);
181     f0_impose_factor = get_param_float("f0_impose_factor",params,0.0);
182 
183     make_segment_varied_mapping(*target_lab, *source_coef,
184 				*target_coef, *map,
185 				dur_impose_factor,
186 				f0_impose_factor);
187 
188     utt.create_relation("US_map");
189     EST_Item *item = utt.relation("US_map")->append();
190     item->set_val("map", est_val(map));
191 
192 }
193 
l_cl_mapping(LISP utt,LISP params)194 LISP l_cl_mapping(LISP utt, LISP params)
195 {
196     EST_Utterance *u = get_c_utt(utt);
197 
198     cl_mapping(*u,params);
199 
200     return utt;
201 }
202 
203 
204 
205