File: | arch/festival/wave.cc |
Location: | line 615, column 5 |
Description: | Value stored to 'd0' 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 : October 1996 */ |
35 | /*-----------------------------------------------------------------------*/ |
36 | /* */ |
37 | /* Interface to various low level waveform functions from Lisp */ |
38 | /* */ |
39 | /*=======================================================================*/ |
40 | #include <cstdio> |
41 | #include "EST_unix.h" |
42 | #include <cstdlib> |
43 | #include "festival.h" |
44 | #include "festivalP.h" |
45 | #include "EST_Wave.h" |
46 | |
47 | #ifdef WIN32 |
48 | #include "winsock2.h" |
49 | #endif |
50 | |
51 | using namespace std; |
52 | |
53 | static void utt_save_f0_from_targets(EST_Utterance *u,EST_String &filename); |
54 | static float f0_interpolate(EST_Item *ptval, EST_Item *tval, float time); |
55 | |
56 | EST_Wave *get_utt_wave(EST_Utterance *u) |
57 | { |
58 | EST_Relation *r; |
59 | |
60 | if (((r = u->relation("Wave")) == 0) || (r->head() == 0)) |
61 | { |
62 | cerr << "no waveform in utterance" << endl; |
63 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
64 | } |
65 | |
66 | return wave(r->head()->f("wave")); |
67 | } |
68 | |
69 | static LISP wave_save(LISP lwave,LISP fname,LISP ftype,LISP stype) |
70 | { |
71 | EST_Wave *w = wave(lwave); |
72 | EST_String filename,filetype,sampletype; |
73 | |
74 | if (fname == NIL((struct obj *) 0)) |
75 | filename = "save.wav"; |
76 | else |
77 | filename = get_c_string(fname); |
78 | if (ftype == NIL((struct obj *) 0)) |
79 | { |
80 | if (ft_get_param("Wavefiletype")) |
81 | filetype = get_c_string(ft_get_param("Wavefiletype")); |
82 | else |
83 | filetype = "nist"; |
84 | } |
85 | else |
86 | filetype = get_c_string(ftype); |
87 | if (stype == NIL((struct obj *) 0)) |
88 | { |
89 | if (ft_get_param("Wavesampletype")) |
90 | sampletype = get_c_string(ft_get_param("Wavesampletype")); |
91 | else |
92 | sampletype = "short"; |
93 | } |
94 | else |
95 | sampletype = get_c_string(stype); |
96 | |
97 | if (w->save_file(filename,filetype,sampletype,EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little )) != write_ok) |
98 | { |
99 | cerr << "utt.save.wave: failed to write wave to \"" << filename |
100 | << "\"" << endl; |
101 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
102 | } |
103 | |
104 | return truth; |
105 | } |
106 | |
107 | static LISP wave_save_data_fp(LISP lwave, LISP lfp, LISP ftype, LISP stype) |
108 | { |
109 | EST_Wave *w = wave(lwave); |
110 | EST_String filetype,sampletype; |
111 | FILE * fp; |
112 | |
113 | fp = get_c_file(lfp, stdoutstdout); |
114 | |
115 | if (ftype == NIL((struct obj *) 0)) |
116 | { |
117 | if (ft_get_param("Wavefiletype")) |
118 | filetype = get_c_string(ft_get_param("Wavefiletype")); |
119 | else |
120 | filetype = "nist"; |
121 | } |
122 | else |
123 | filetype = get_c_string(ftype); |
124 | if (stype == NIL((struct obj *) 0)) |
125 | { |
126 | if (ft_get_param("Wavesampletype")) |
127 | sampletype = get_c_string(ft_get_param("Wavesampletype")); |
128 | else |
129 | sampletype = "short"; |
130 | } |
131 | else |
132 | sampletype = get_c_string(stype); |
133 | |
134 | if (w->save_file_data(fp,filetype,sampletype,EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little )) != write_ok) |
135 | { |
136 | cerr << "utt.save.wave.fp: failed to write wave" << endl; |
137 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
138 | } |
139 | |
140 | return truth; |
141 | } |
142 | |
143 | |
144 | |
145 | static LISP wave_save_fp(LISP lwave, LISP lfp, LISP ftype, LISP stype) |
146 | { |
147 | EST_Wave *w = wave(lwave); |
148 | EST_String filetype,sampletype; |
149 | FILE * fp; |
150 | |
151 | fp = get_c_file(lfp, stdoutstdout); |
152 | |
153 | if (ftype == NIL((struct obj *) 0)) |
154 | { |
155 | if (ft_get_param("Wavefiletype")) |
156 | filetype = get_c_string(ft_get_param("Wavefiletype")); |
157 | else |
158 | filetype = "nist"; |
159 | } |
160 | else |
161 | filetype = get_c_string(ftype); |
162 | if (stype == NIL((struct obj *) 0)) |
163 | { |
164 | if (ft_get_param("Wavesampletype")) |
165 | sampletype = get_c_string(ft_get_param("Wavesampletype")); |
166 | else |
167 | sampletype = "short"; |
168 | } |
169 | else |
170 | sampletype = get_c_string(stype); |
171 | |
172 | if (w->save_file(fp,filetype,sampletype,EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little )) != write_ok) |
173 | { |
174 | cerr << "utt.save.wave.data.fp: failed to write wave" << endl; |
175 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
176 | } |
177 | |
178 | return truth; |
179 | } |
180 | |
181 | |
182 | |
183 | static LISP wave_save_header_fp(LISP arglist) |
184 | { |
185 | LISP lfp = car(arglist); |
186 | arglist = cdr(arglist); |
187 | LISP lwave = car(arglist); |
188 | arglist = cdr(arglist); |
189 | LISP lftype = car(arglist); |
190 | arglist = cdr(arglist); |
191 | LISP lstype = car(arglist); |
192 | arglist = cdr(arglist); |
193 | LISP force_values = car(arglist); |
194 | arglist = cdr(arglist); |
195 | |
196 | FILE *fp; |
197 | fp = get_c_file(lfp, NULL__null); |
198 | EST_String ftype, stype; |
199 | EST_Wave *w = wave(lwave); |
200 | |
201 | int num_samples = w->num_samples(); |
202 | int num_channels = w->num_channels(); |
203 | int sample_rate = w->sample_rate(); |
204 | int bo = EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little ); |
205 | |
206 | num_samples = (int) get_param_float("numsamples", force_values, (float) num_samples); |
207 | num_channels = (int) get_param_float("numchannels", force_values, (float) num_channels); |
208 | sample_rate = (int) get_param_float("samplerate", force_values, (float) sample_rate); |
209 | bo = (int) get_param_float("bo", force_values, (float) bo); |
210 | |
211 | if (lftype == NIL((struct obj *) 0)) |
212 | { |
213 | if (ft_get_param("Wavefiletype")) |
214 | ftype = get_c_string(ft_get_param("Wavefiletype")); |
215 | else |
216 | ftype = "nist"; |
217 | } |
218 | else |
219 | ftype = get_c_string(lftype); |
220 | |
221 | if (lstype == NIL((struct obj *) 0)) |
222 | { |
223 | if (ft_get_param("Wavesampletype")) |
224 | stype = get_c_string(ft_get_param("Wavesampletype")); |
225 | else |
226 | stype = "short"; |
227 | } |
228 | else |
229 | stype = get_c_string(lstype); |
230 | |
231 | |
232 | if (wave_io_save_header(fp, num_samples, num_channels, |
233 | sample_rate, stype, bo, ftype) != write_ok) |
234 | { |
235 | cerr << "utt.save.wave.header: failed" << endl; |
236 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
237 | } |
238 | |
239 | return truth; |
240 | } |
241 | |
242 | static LISP wave_load(LISP fname,LISP ftype,LISP stype,LISP srate) |
243 | { |
244 | EST_Wave *w = new EST_Wave; |
245 | EST_read_status r; |
246 | |
247 | if (ftype == NIL((struct obj *) 0)) |
248 | r = w->load(get_c_string(fname)); |
249 | else if (streq("raw",get_c_string(ftype))(strcmp("raw",get_c_string(ftype))==0)) |
250 | r = w->load_file(get_c_string(fname), |
251 | get_c_string(ftype), |
252 | get_c_int(srate), |
253 | get_c_string(stype), |
254 | EST_NATIVE_BO((((char *)&est_endian_loc)[0] == 0) ? bo_big : bo_little ), |
255 | 1); |
256 | else |
257 | r = w->load(get_c_string(fname),get_c_string(ftype)); |
258 | |
259 | if (r != format_okread_ok) |
260 | cerr << "Cannot load wavefile: " << get_c_string(fname) << endl; |
261 | |
262 | return siod(w); |
263 | } |
264 | |
265 | static LISP wave_copy(LISP w) |
266 | { |
267 | return siod(new EST_Wave(*wave(w))); |
268 | } |
269 | |
270 | static LISP wave_append(LISP w1,LISP w2) |
271 | { |
272 | EST_Wave *wave1 = wave(w1); |
273 | EST_Wave *wave2 = wave(w2); |
274 | |
275 | *wave1 += *wave2; |
276 | |
277 | return w1; |
278 | } |
279 | |
280 | static LISP wave_info(LISP w1) |
281 | { |
282 | EST_Wave *w = wave(w1); |
283 | |
284 | return cons(make_param_float("num_samples", |
285 | w->num_samples()), |
286 | cons(make_param_float("sample_rate", |
287 | w->sample_rate()), |
288 | cons(make_param_float("num_channels", |
289 | w->num_channels()), |
290 | cons(make_param_str("file_type", |
291 | w->file_type()), |
292 | NIL((struct obj *) 0))))); |
293 | } |
294 | |
295 | static LISP wave_set(LISP lwave,LISP lx, LISP ly, LISP lv) |
296 | { |
297 | EST_Wave *t = wave(lwave); |
298 | |
299 | t->a(get_c_int(lx),get_c_int(ly)) = (short)get_c_float(lv); |
300 | return lv; |
301 | } |
302 | |
303 | static LISP wave_set_sample_rate(LISP lwave,LISP lsr) |
304 | { |
305 | EST_Wave *t = wave(lwave); |
306 | |
307 | t->set_sample_rate(get_c_int(lsr)); |
308 | return lsr; |
309 | } |
310 | |
311 | static LISP wave_get(LISP lwave,LISP lx, LISP ly) |
312 | { |
313 | EST_Wave *t = wave(lwave); |
314 | |
315 | return flocons(t->a(get_c_int(lx),get_c_int(ly))); |
316 | } |
317 | |
318 | static LISP wave_resize(LISP lwave,LISP lsamples, LISP lchannels) |
319 | { |
320 | EST_Wave *t; |
321 | |
322 | if (lwave) |
323 | t = wave(lwave); |
324 | else |
325 | t = new EST_Wave; |
326 | |
327 | t->resize(get_c_int(lsamples),get_c_int(lchannels)); |
328 | |
329 | return siod(t); |
330 | } |
331 | |
332 | static LISP wave_resample(LISP w1,LISP newrate) |
333 | { |
334 | EST_Wave *w = wave(w1); |
335 | |
336 | w->resample(get_c_int(newrate)); |
337 | |
338 | return w1; |
339 | } |
340 | |
341 | static LISP wave_rescale(LISP lw,LISP lgain,LISP normalize) |
342 | { |
343 | EST_Wave *w = wave(lw); |
344 | float gain = get_c_float(lgain); |
345 | |
346 | if (normalize) |
347 | w->rescale(gain,TRUE(1==1)); |
348 | else |
349 | w->rescale(gain); |
350 | |
351 | return lw; |
352 | } |
353 | |
354 | void play_wave(EST_Wave *w) |
355 | { |
356 | EST_Option al; |
357 | LISP audio; |
358 | |
359 | if (audsp_mode) // asynchronous mode |
360 | audsp_play_wave(w); |
361 | else |
362 | { |
363 | if ((audio = ft_get_param("Audio_Method")) != NIL((struct obj *) 0)) |
364 | al.add_item("-p",get_c_string(audio)); |
365 | if ((audio = ft_get_param("Audio_Device")) != NIL((struct obj *) 0)) |
366 | al.add_item("-audiodevice",get_c_string(audio)); |
367 | if ((audio = ft_get_param("Audio_Command")) != NIL((struct obj *) 0)) |
368 | al.add_item("-command",quote_string(get_c_string(audio))); |
369 | if ((audio = ft_get_param("Audio_Required_Rate")) != NIL((struct obj *) 0)) |
370 | al.add_item("-rate",get_c_string(audio)); |
371 | if ((audio = ft_get_param("Audio_Required_Format")) != NIL((struct obj *) 0)) |
372 | al.add_item("-otype",get_c_string(audio)); |
373 | al.add_item("-quality","HIGH"); |
374 | play_wave(*w,al); |
375 | } |
376 | } |
377 | |
378 | static LISP wave_play(LISP lw) |
379 | { |
380 | play_wave(wave(lw)); |
381 | return truth; |
382 | } |
383 | |
384 | static LISP track_save(LISP ltrack,LISP fname,LISP ftype) |
385 | { |
386 | EST_Track *t = track(ltrack); |
387 | EST_String filename,filetype; |
388 | |
389 | filename = (fname == NIL((struct obj *) 0)) ? "save.track" : get_c_string(fname); |
390 | filetype = (ftype == NIL((struct obj *) 0)) ? "est" : get_c_string(ftype); |
391 | |
392 | if (t->save(filename, filetype) != write_ok) |
393 | { |
394 | cerr << "track.save: failed to write track to \"" << filename |
395 | << "\"" << endl; |
396 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
397 | } |
398 | |
399 | return truth; |
400 | } |
401 | |
402 | static LISP track_load(LISP fname,LISP ftype,LISP ishift) |
403 | { |
404 | EST_Track *t = new EST_Track; |
405 | EST_read_status r; |
406 | float is = 0.0; |
407 | if (ishift) |
408 | is = get_c_float(ishift); |
409 | |
410 | if (ftype == NIL((struct obj *) 0)) |
411 | r = t->load(get_c_string(fname),is); |
412 | else |
413 | r = t->load(get_c_string(fname), |
414 | get_c_string(ftype), |
415 | is); |
416 | |
417 | if (r != format_okread_ok) |
418 | cerr << "Cannot load track: " << get_c_string(fname) << endl; |
419 | |
420 | return siod(t); |
421 | } |
422 | |
423 | static LISP track_index_below(LISP ltrack, LISP ltime) |
424 | { |
425 | EST_Track *t = track(ltrack); |
426 | int index = -1; |
427 | |
428 | if(ltime) |
429 | { |
430 | index = t->index_below(get_c_float(ltime)); |
431 | return flocons(index); |
432 | } |
433 | |
434 | return NIL((struct obj *) 0); |
435 | } |
436 | |
437 | static LISP track_resize(LISP ltrack,LISP lframes, LISP lchannels) |
438 | { |
439 | EST_Track *t; |
440 | |
441 | if (ltrack) |
442 | t = track(ltrack); |
443 | else |
444 | t = new EST_Track; |
445 | |
446 | t->resize(get_c_int(lframes),get_c_int(lchannels)); |
447 | |
448 | return siod(t); |
449 | } |
450 | |
451 | static LISP track_set(LISP ltrack,LISP lx, LISP ly, LISP lv) |
452 | { |
453 | EST_Track *t = track(ltrack); |
454 | |
455 | t->a(get_c_int(lx),get_c_int(ly)) = get_c_float(lv); |
456 | return lv; |
457 | } |
458 | |
459 | static LISP track_set_time(LISP ltrack,LISP lx, LISP lt) |
460 | { |
461 | EST_Track *t = track(ltrack); |
462 | |
463 | t->t(get_c_int(lx)) = get_c_float(lt); |
464 | return lt; |
465 | } |
466 | |
467 | static LISP track_get(LISP ltrack,LISP lx, LISP ly) |
468 | { |
469 | EST_Track *t = track(ltrack); |
470 | |
471 | return flocons(t->a(get_c_int(lx),get_c_int(ly))); |
472 | } |
473 | |
474 | static LISP track_get_time(LISP ltrack,LISP lx) |
475 | { |
476 | EST_Track *t = track(ltrack); |
477 | |
478 | return flocons(t->t(get_c_int(lx))); |
479 | } |
480 | |
481 | static LISP track_frames(LISP ltrack) |
482 | { |
483 | return flocons((float)track(ltrack)->num_frames()); |
484 | } |
485 | |
486 | static LISP track_channels(LISP ltrack) |
487 | { |
488 | return flocons((float)track(ltrack)->num_channels()); |
489 | } |
490 | |
491 | static LISP track_copy(LISP t) |
492 | { |
493 | return siod(new EST_Track(*track(t))); |
494 | } |
495 | |
496 | static LISP track_insert(LISP argv, LISP env) |
497 | { |
498 | int i,j; |
499 | /* TRACK1 X1 TRACK2 X2 COUNT */ |
500 | EST_Track *t1 = track(leval(siod_nth(0,argv),env)); |
501 | int x1 = get_c_int(leval(siod_nth(1,argv),env)); |
502 | EST_Track *t2 = track(leval(siod_nth(2,argv),env)); |
503 | int x2 = get_c_int(leval(siod_nth(3,argv),env)); |
504 | int count = get_c_int(leval(siod_nth(4,argv),env)); |
505 | |
506 | if (t1->num_channels() != t2->num_channels()) |
507 | { |
508 | cerr << "track.insert: different number of channels" << |
509 | t1->num_channels() << " != " << t2->num_channels() << endl; |
510 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
511 | } |
512 | |
513 | if (x1 + count >= t1->num_frames()) |
514 | t1->resize(x1+count,t1->num_channels()); |
515 | |
516 | for (i=0; i<count; i++) |
517 | { |
518 | for (j=0; j<t1->num_channels(); j++) |
519 | t1->a(x1+i,j) = t2->a(x2+i,j); |
520 | /* not sure this is right */ |
521 | t1->t(x1+i) = |
522 | (x1+i > 0 ? t1->t(x1+i-1) : 0) + |
523 | t2->t(x2+i) - (x2+i > 0 ? t2->t(x2+i-1) : 0); |
524 | } |
525 | |
526 | return siod_nth(1,argv); |
527 | } |
528 | |
529 | static LISP utt_save_f0(LISP utt, LISP fname) |
530 | { |
531 | // Save utt's F0 in fname as an ESPS file |
532 | EST_Utterance *u = utterance(utt); |
533 | EST_String filename = get_c_string(fname); |
534 | |
535 | if ((u->relation_present("F0")) && (u->relation("F0")->head() != 0)) |
536 | { |
537 | EST_Track *f0 = track(u->relation("F0")->head()->f("f0")); |
538 | if (f0->save(filename,"esps") != write_ok) |
539 | { |
540 | cerr << "utt.save.f0: failed to write f0 to \"" << |
541 | filename << "\"" << endl; |
542 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
543 | } |
544 | } |
545 | else if (u->relation("Target") != 0) |
546 | utt_save_f0_from_targets(u,filename); |
547 | else |
548 | { |
549 | cerr << "utt.save.f0: utterance doesn't contain F0 or Target stream" |
550 | << endl; |
551 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
552 | } |
553 | return utt; |
554 | } |
555 | |
556 | static void utt_save_f0_from_targets(EST_Utterance *u,EST_String &filename) |
557 | { |
558 | // Modifications by Gregor Moehler to do proper target tracing (GM) |
559 | EST_Item *s; |
560 | EST_Track f0; |
561 | float p = 0.0; |
562 | float length = u->relation("Segment")->last()->f("end"); |
563 | int i,frames = (int)(length / 0.010); |
564 | f0.resize(frames,4); |
565 | |
566 | EST_Item *ptval, *tval; |
567 | |
568 | ptval = tval = u->relation("Target")->first_leaf(); |
569 | for (i=0,s=u->relation("Segment")->first(); s != 0; s=s->next()) |
570 | { |
571 | if (i >= frames) |
572 | break; // may hit here one before end |
573 | for ( ; p < s->F("end",0); p+=0.010,i++) |
574 | { |
575 | if (tval != 0 && p > (float)ffeature(tval,"pos")) |
576 | { |
577 | ptval = tval; |
578 | tval = next_leaf(tval); |
579 | } |
580 | if (i >= frames) |
581 | break; // may hit here one before end |
582 | if ((ffeature(s,"ph_vc") == "+") || |
583 | (ffeature(s,"ph_cvox") == "+")) |
584 | { |
585 | f0(i,0) = f0_interpolate(ptval,tval,p); |
586 | f0(i,1) = 1; |
587 | } |
588 | else |
589 | { |
590 | f0(i,0) = 0; |
591 | f0(i,1) = 0.0; // unvoiced; |
592 | } |
593 | } |
594 | } |
595 | f0.set_channel_name("F0",0); |
596 | f0.set_channel_name("prob_voice",1); |
597 | f0.fill_time(0.01); |
598 | |
599 | if (f0.save(filename,"esps") != write_ok) |
600 | { |
601 | cerr << "utt.save.f0: failed to write F0 to \"" << |
602 | filename << "\"" << endl; |
603 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
604 | } |
605 | |
606 | return; |
607 | } |
608 | |
609 | static float f0_interpolate(EST_Item *ptval, EST_Item *tval, float time) |
610 | { |
611 | // GM: changed, to use proper targets |
612 | // Return interpolated F0 at time t |
613 | float p1,p0,d1,d0; |
614 | |
615 | d0=0; |
Value stored to 'd0' is never read | |
616 | d1=0; |
617 | |
618 | if (tval == 0) // after last target |
619 | return ffeature(ptval,"f0"); |
620 | |
621 | else if (time < (float) ffeature(ptval,"pos")) // before 1st target |
622 | return ffeature(tval,"f0"); |
623 | |
624 | else { |
625 | p0 = ffeature(ptval,"f0"); |
626 | p1 = ffeature(tval,"f0"); |
627 | d0 = ffeature(ptval,"pos"); |
628 | d1 = ffeature(tval,"pos"); |
629 | } |
630 | |
631 | if (p0 == 0.0 || d1 == d0) |
632 | return p1; |
633 | else if (p1 == 0.0) |
634 | return p0; |
635 | else |
636 | return p0 + (p1-p0)*(time-d0)/(d1-d0); |
637 | } |
638 | |
639 | static LISP utt_send_wave_client(LISP utt) |
640 | { |
641 | // Send the waveform to a client (must be acting as server) |
642 | EST_Utterance *u = utterance(utt); |
643 | EST_Wave *w; |
644 | EST_String tmpfile = make_tmp_filename(); |
645 | LISP ltype; |
646 | EST_String type; |
647 | |
648 | w = get_utt_wave(u); |
649 | if (ft_server_socket == -1) |
650 | { |
651 | cerr << "utt_send_wave_client: not in server mode" << endl; |
652 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
653 | } |
654 | |
655 | ltype = ft_get_param("Wavefiletype"); |
656 | if (ltype == NIL((struct obj *) 0)) |
657 | type = "nist"; |
658 | else |
659 | type = get_c_string(ltype); |
660 | w->save(tmpfile,type); |
661 | #ifdef WIN32 |
662 | if (send(ft_server_socket,"WV\n",3,0) != 3) { |
663 | std::cerr << "Error sending wave to client" << std::endl; |
664 | return NIL((struct obj *) 0); |
665 | } |
666 | #else |
667 | if (write(ft_server_socket,"WV\n",3) != 3) { |
668 | std::cerr << "Error sending wave to client" << std::endl; |
669 | return NIL((struct obj *) 0); |
670 | } |
671 | #endif |
672 | socket_send_file(ft_server_socket,tmpfile); |
673 | unlink(tmpfile); |
674 | |
675 | return utt; |
676 | } |
677 | |
678 | /* Asterisk support, see http://www.asterisk.org */ |
679 | |
680 | static LISP utt_send_wave_asterisk(LISP utt) |
681 | { |
682 | // Send the waveform to a client (must be acting as server) |
683 | EST_Utterance *u = utterance(utt); |
684 | EST_Wave *w; |
685 | EST_String tmpfile = make_tmp_filename(); |
686 | LISP ltype; |
687 | EST_String type; |
688 | |
689 | w = get_utt_wave(u); |
690 | if (ft_server_socket == -1) |
691 | { |
692 | cerr << "utt_send_wave_asterisk: not in server mode" << endl; |
693 | festival_error()(errjmp_ok ? longjmp(*est_errjmp,1) : festival_tidy_up(),exit (-1)); |
694 | } |
695 | |
696 | ltype = ft_get_param("Wavefiletype"); |
697 | if (ltype == NIL((struct obj *) 0)) |
698 | type = "nist"; |
699 | else |
700 | type = get_c_string(ltype); |
701 | w->resample(8000); |
702 | w->rescale(5); |
703 | |
704 | w->save(tmpfile,type); |
705 | #ifdef WIN32 |
706 | if (send(ft_server_socket,"WV\n",3,0) != 3) { |
707 | std::cerr << "Error sending wave to asterisk" << std::endl; |
708 | return NIL((struct obj *) 0); |
709 | } |
710 | #else |
711 | if (write(ft_server_socket,"WV\n",3) != 3) { |
712 | std::cerr << "Error sending wave to asterisk" << std::endl; |
713 | return NIL((struct obj *) 0); |
714 | } |
715 | #endif |
716 | socket_send_file(ft_server_socket,tmpfile); |
717 | unlink(tmpfile); |
718 | |
719 | return utt; |
720 | } |
721 | |
722 | |
723 | static LISP send_sexpr_to_client(LISP l) |
724 | { |
725 | EST_String tmpfile = make_tmp_filename(); |
726 | FILE *fd; |
727 | |
728 | fd = fopen(tmpfile,"w"); |
729 | |
730 | lprin1f(l,fd); |
731 | fprintf(fd,"\n"); |
732 | fclose(fd); |
733 | #ifdef WIN32 |
734 | if (send(ft_server_socket,"LP\n",3,0) != 3) { |
735 | std::cerr << "Error sending expression to client" << std::endl; |
736 | return NIL((struct obj *) 0); |
737 | } |
738 | #else |
739 | if (write(ft_server_socket,"LP\n",3) != 3) { |
740 | std::cerr << "Error sending expression to client" << std::endl; |
741 | return NIL((struct obj *) 0); |
742 | } |
743 | #endif |
744 | socket_send_file(ft_server_socket,tmpfile); |
745 | unlink(tmpfile); |
746 | |
747 | return l; |
748 | } |
749 | |
750 | void festival_wave_init(void) |
751 | { |
752 | // declare utterance (wave) specific Lisp functions |
753 | init_lsubr("wave.save.header", wave_save_header_fp, |
754 | "(wave.save.header FILEPOINTER WAVE FILETYPE SAMPLETYPE OVERRIDEPARAMS)\n\ |
755 | Write a wave header of format FILETYPE to FILEPOINTER.\n\ |
756 | Header parameters are read first from WAVE and SAMPLETYPE,\n\ |
757 | and can be overridden with OVERRIDEPARAMS\n\ |
758 | OVERRIDEPARAMS = ( (\"numsamples\" 84000)\n\ |
759 | (\"numchannels\" 1)\n\ |
760 | (\"samplerate\" 16000)\n\ |
761 | (\"bo\" 10)\n\ |
762 | (\"numsamples\" 16000)\n\ |
763 | )"); |
764 | init_subr_4("wave.save.fp", wave_save_fp, |
765 | "(wave.save.fp WAVE FILEPOINTER FILETYPE SAMPLETYPE)\n\ |
766 | Write WAVE to FILEPOINTER, respecting FILETYPE and SAMPLETYPE if specified\n\ |
767 | if these last two arguments are unspecified the global parameters\n\ |
768 | Wavefiletype and Wavesampletype are used. Returns t is successful\n\ |
769 | and throws an error if not."); |
770 | init_subr_4("wave.save.data.fp", wave_save_data_fp, |
771 | "(wave.save.data.fp WAVE FILEPOINTER FILETYPE SAMPLETYPE)\n\ |
772 | Write WAVE to FILEPOINTER, respecting FILETYPE and SAMPLETYPE if specified\n\ |
773 | ignoring any file header.\n\ |
774 | if these last two arguments are unspecified the global parameters\n\ |
775 | Wavefiletype and Wavesampletype are used. Returns t is successful\n\ |
776 | and throws an error if not. It can be used with wave.save.header\n\ |
777 | in order to concatenate several waves."); |
778 | init_subr_4("wave.save",wave_save, |
779 | "(wave.save WAVE FILENAME FILETYPE SAMPLETYPE)\n\ |
780 | Save WAVE in FILENAME, respecting FILETYPE and SAMPLETYPE if specified\n\ |
781 | if these last two arguments are unspecified the global parameters\n\ |
782 | Wavefiletype and Wavesampletype are used. Returns t is successful\n\ |
783 | and throws an error if not."); |
784 | init_subr_4("wave.load",wave_load, |
785 | "(wave.load FILENAME FILETYPE SAMPLETYPE SAMPLERATE)\n\ |
786 | Load and return a wave from FILENAME. Respect FILETYPE is specified\n\ |
787 | if not specified respect whatever header is on the file. SAMPLETYPE\n\ |
788 | and SAMPLERATE are only used if FILETYPE is raw."); |
789 | init_subr_1("wave.copy",wave_copy, |
790 | "(wave.copy WAVE)\n\ |
791 | Return a copy of WAVE."); |
792 | init_subr_2("wave.append",wave_append, |
793 | "(wave.copy WAVE1 WAVE2)\n\ |
794 | Destuctively append WAVE2 to WAVE1 and return WAVE1."); |
795 | init_subr_1("wave.info",wave_info, |
796 | "(wave.info WAVE)\n\ |
797 | Returns assoc list of info about this wave."); |
798 | init_subr_2("wave.resample",wave_resample, |
799 | "(wave.resample WAVE NEWRATE)\n\ |
800 | Resamples WAVE to NEWRATE."); |
801 | init_subr_3("wave.rescale",wave_rescale, |
802 | "(wave.rescale WAVE GAIN NORMALIZE)\n\ |
803 | If NORMALIZE is specified and non-nil, maximizes the waveform first\n\ |
804 | before applying the gain."); |
805 | init_subr_1("wave.play",wave_play, |
806 | "(wave.play WAVE)\n\ |
807 | Play wave of selected audio"); |
808 | init_subr_3("wave.resize",wave_resize, |
809 | "(wave.resize WAVE NEWSAMPLES NEWCHANNELS)\n\ |
810 | Resize WAVE to have NEWSAMPLES number of frames and NEWCHANNELS\n\ |
811 | number of channels. If WAVE is nil a new wave is made of the\n\ |
812 | requested size."); |
813 | init_subr_4("wave.set",wave_set, |
814 | "(wave.set WAVE X Y V)\n\ |
815 | Set position X Y to V in WAVE.") |
816 | ; init_subr_3("wave.get",wave_get, |
817 | "(wave.get WAVE X Y)\n\ |
818 | Get value of X Y in WAVE."); |
819 | init_subr_2("wave.set_sample_rate",wave_set_sample_rate, |
820 | "(wave.set_sample_rate WAVE SR)\n\ |
821 | set sample rate to SR."); |
822 | |
823 | |
824 | init_subr_3("track.save",track_save, |
825 | "(track.save TRACK FILENAME FILETYPE)\n\ |
826 | Save TRACK in FILENAME, in format FILETYPE, est is used if FILETYPE\n\ |
827 | is unspecified or nil."); |
828 | init_subr_3("track.load",track_load, |
829 | "(track.load FILENAME FILETYPE ISHIFT)\n\ |
830 | Load and return a track from FILENAME. Respect FILETYPE is specified\n\ |
831 | and ISHIFT if specified."); |
832 | init_subr_1("track.copy",track_copy, |
833 | "(track.copy TRACK)\n\ |
834 | Return a copy of TRACK."); |
835 | init_subr_2("track.index_below",track_index_below, |
836 | "(track.index_below TRACK TIME)\n\ |
837 | Returns the first frame index before this time."); |
838 | init_subr_3("track.resize",track_resize, |
839 | "(track.resize TRACK NEWFRAMES NEWCHANNELS)\n\ |
840 | Resize TRACK to have NEWFRAMES number of frames and NEWCHANNELS\n\ |
841 | number of channels. If TRACK is nil a new track is made of the\n\ |
842 | requested size."); |
843 | init_subr_1("track.num_frames",track_frames, |
844 | "(track.num_frames TRACK)\n\ |
845 | Returns number of frames in TRACK."); |
846 | init_subr_1("track.num_channels",track_channels, |
847 | "(track.num_channels TRACK)\n\ |
848 | Returns number of channels in TRACK."); |
849 | init_subr_4("track.set",track_set, |
850 | "(track.set TRACK X Y V)\n\ |
851 | Set position X Y to V in TRACK."); |
852 | init_subr_3("track.get",track_get, |
853 | "(track.get TRACK X Y)\n\ |
854 | Get value of X Y in TRACK."); |
855 | init_subr_3("track.set_time",track_set_time, |
856 | "(track.set_time TRACK X TIME)\n\ |
857 | Set time at X to TIME in TRACK."); |
858 | init_subr_2("track.get_time",track_get_time, |
859 | "(track.get_time TRACK X)\n\ |
860 | Get time of X in TRACK."); |
861 | init_fsubr("track.insert",track_insert, |
862 | "(track.insert TRACK1 X1 TRACK2 X2 COUNT)\n\ |
863 | Insert TRACK2 from X2 to X2+COUNT into TRACK1 at X1. TRACK1 is resized\n\ |
864 | as required."); |
865 | init_subr_1("utt.send.wave.client",utt_send_wave_client, |
866 | "(utt.send.wave.client UTT)\n\ |
867 | Sends wave in UTT to client. If not in server mode gives an error\n\ |
868 | Note the client must be expecting to receive the waveform."); |
869 | init_subr_1("utt.send.wave.asterisk",utt_send_wave_asterisk, |
870 | "(utt.send.wave.asterisk UTT)\n\ |
871 | Sends wave in UTT to client. If not in server mode gives an error\n\ |
872 | Note the client must be expecting to receive the waveform. The waveform\n\ |
873 | is rescaled and resampled according to what asterisk needs"); |
874 | init_subr_1("send_sexpr_to_client", send_sexpr_to_client, |
875 | "(send_sexpr_to_client SEXPR)\n\ |
876 | Sends given sexpression to currently connected client."); |
877 | init_subr_2("utt.save.f0",utt_save_f0, |
878 | "(utt.save.f0 UTT FILENAME)\n\ |
879 | Save F0 of UTT as esps track file in FILENAME."); |
880 | |
881 | } |
882 | |
883 | |
884 |