Initial import to Gerrit.
[profile/ivi/festival.git] / lib / mbrola.scm
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 ;;;  Support for MBROLA as an external module.
35 ;;;
36
37 ;;; You might want to set this in your sitevars.scm
38 (defvar mbrola_progname "/cstr/external/mbrola/mbrola"
39   "mbrola_progname
40   The program name for mbrola.")
41 (defvar mbrola_database "fr1"
42   "mbrola_database
43  The name of the MBROLA database to usde during MBROLA Synthesis.")
44
45 (define (MBROLA_Synth utt)
46   "(MBROLA_Synth UTT)
47   Synthesize using MBROLA as external module.  Basically dump the info
48   from this utterance. Call MBROLA and reload the waveform into utt.
49   [see MBROLA]"
50   (let ((filename (make_tmp_filename))
51         )
52     (save_segments_mbrola utt filename)
53     (system (string-append mbrola_progname " " 
54                            mbrola_database " "
55                            filename " "
56                            filename ".au"))
57     (utt.import.wave utt (string-append filename ".au"))
58     (apply_hooks after_synth_hooks utt)
59     (delete-file filename)
60     (delete-file (string-append filename ".au"))
61     utt))
62
63 (define (save_segments_mbrola utt filename)
64   "(save_segments_mbrola UTT FILENAME)
65   Save segment information in MBROLA format in filename.  The format is
66   phone duration (ms) [% position F0 target]*. [see MBROLA]"
67   (let ((fd (fopen filename "w")))
68     (mapcar
69      (lambda (segment) 
70        (save_seg_mbrola_entry 
71         (item.feat segment 'name)
72         (item.feat segment 'segment_start)
73         (item.feat segment 'segment_duration)
74         (mapcar
75          (lambda (targ_item)
76            (list
77             (item.feat targ_item "pos")
78             (item.feat targ_item "f0")))
79          (item.relation.daughters segment 'Target)) ;; list of targets
80         fd))
81      (utt.relation.items utt 'Segment))
82     (fclose fd)))
83
84 (define (save_seg_mbrola_entry name start dur targs fd)
85   "(save_seg_mbrola_entry ENTRY NAME START DUR TARGS FD)
86   Entry contains, (name duration num_targs start 1st_targ_pos 1st_targ_val)."
87   (format fd "%s %d " name (nint (* dur 1000)))
88   (if targs     ;; if there are any targets
89       (mapcar
90        (lambda (targ) ;; targ_pos and targ_val
91          (let ((targ_pos (car targ))
92                (targ_val (car (cdr targ))))
93                                           
94            (format fd "%d %d " 
95                    (nint (* 100 (/ (- targ_pos start) dur))) ;; % pos of target
96                    (nint (parse-number targ_val)))           ;; target value
97            ))
98        targs))
99   (terpri fd)
100   (terpri fd)
101 )
102         
103 (provide 'mbrola)