|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(require 'apml_f2bf0lr) |
|
(require 'apml_kaldurtreeZ) |
|
|
|
|
|
|
|
(defvar apml_default_pitch_mean 170 ) |
|
(defvar apml_default_pitch_standard_deviation 34 ) |
|
|
|
|
|
|
|
(define (apml_client_synth apml) |
|
"(apml_client_synth apml) |
|
Synthesise apml and return waveform(s) to client." |
|
(utt.send.wave.client (apml_synth apml))) |
|
|
|
(define (apml_synth apml) |
|
"(apml_synth xml) |
|
Synthesis an apml string." |
|
(let ((tmpfile (make_tmp_filename)) |
|
utt) |
|
(string_to_file tmpfile apml) |
|
(set! utt (apml_file_synth tmpfile)) |
|
(delete-file tmpfile) |
|
utt)) |
|
|
|
(define (apml_file_synth filename) |
|
"(apml_file_synth filename) |
|
Synthesis an apml file." |
|
(let ((utt (Utterance Tokens nil))) |
|
(utt.load utt filename) |
|
(utt.synth utt))) |
|
|
|
(define (string_to_file file s) |
|
"(string_to_file file string) |
|
Write string to file." |
|
(let ((fd)) |
|
(set! fd (fopen file "wb")) |
|
(format fd "%s" s) |
|
(fclose fd))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(set! apml_phrase_tree |
|
' |
|
((lisp_apml_punc in ("?" "." ":")) |
|
((BB)) |
|
((lisp_apml_punc in ("'" "\"" "," ";")) |
|
((B)) |
|
((lisp_apml_last_word is 1) |
|
((BB)) |
|
((NB)))))) |
|
|
|
|
|
(define (apml_punc word) |
|
(item.feat (item.relation.parent word 'Token) 'punc)) |
|
|
|
(define (apml_last_word word) |
|
(if (item.next word) |
|
"0" "1")) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (apml_is_pause word) |
|
(if (item.relation (item.relation.parent word 'Token) 'Pause) |
|
t |
|
nil)) |
|
|
|
(define (apml_pause word) |
|
(if (item.relation word 'Pause) |
|
(item.feat (item.relation.parent (item.relation.parent word 'Token) 'Pause) "sec") |
|
0)) |
|
|
|
(define (Apml_Pauses utt) |
|
"(Pauses UTT) |
|
Predict pause insertion for apml." |
|
(let ((words (utt.relation.items utt 'Word)) lastword tpname) |
|
(if words |
|
(begin |
|
(insert_initial_pause utt) |
|
(set! lastword (car (last words))) |
|
(mapcar |
|
(lambda (w) |
|
(let ((pbreak (item.feat w "pbreak")) |
|
(emph (item.feat w "R:Token.parent.EMPH"))) |
|
(cond |
|
((apml_is_pause w) |
|
(insert_pause utt w)) |
|
((or (string-equal "B" pbreak) |
|
(string-equal "BB" pbreak)) |
|
(insert_pause utt w)) |
|
((equal? w lastword) |
|
(insert_pause utt w))))) |
|
words) |
|
|
|
(mapcar |
|
(lambda (w) |
|
(let ((pos (item.feat w "pos"))) |
|
(if (or (string-equal "punc" pos) |
|
(string-equal "fpunc" pos)) |
|
(let ((pbreak (item.feat w "pbreak")) |
|
(wp (item.relation w 'Phrase))) |
|
(if (and (string-matches pbreak "BB?") |
|
(item.relation.prev w 'Word)) |
|
(item.set_feat |
|
(item.relation.prev w 'Word) "pbreak" pbreak)) |
|
(item.relation.remove w 'Word) |
|
|
|
(item.relation.remove wp 'Phrase))))) |
|
words))) |
|
utt)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(set! apml_accent_cart |
|
' |
|
((lisp_apml_accent is "Hstar") |
|
((H*)) |
|
((lisp_apml_accent is "Lstar") |
|
((L*)) |
|
((lisp_apml_LHLH is "LHLH") |
|
((L+H*L-H%)) |
|
((lisp_apml_accent is "LplusHstar") |
|
((L+H*)) |
|
((lisp_apml_accent is "LstarplusH") |
|
((L*+H)) |
|
((NONE)))))))) |
|
|
|
(set! apml_boundary_cart |
|
' |
|
((lisp_apml_boundary is "LL") |
|
((L-L%)) |
|
((lisp_apml_LHLH is "LHLH") |
|
((NONE)) |
|
((lisp_apml_boundary is "LH") |
|
((L-H%)) |
|
((lisp_apml_boundary is "HH") |
|
((H-H%)) |
|
((lisp_apml_boundary is "HL") |
|
((H-L%)) |
|
((NONE)))))))) |
|
|
|
|
|
(define (apml_accent syl) |
|
(let ((token (item.relation.parent (item.relation.parent syl 'SylStructure) 'Token))) |
|
(if (and (eq (item.feat syl 'stress) 1) |
|
(item.relation.parent token 'Emphasis)) |
|
(item.feat (item.relation.parent token 'Emphasis) 'x-pitchaccent) |
|
0))) |
|
|
|
(define (apml_boundary syl) |
|
(let ((token (item.relation.parent (item.relation.parent syl 'SylStructure) 'Token))) |
|
(if (and (> (item.feat syl 'syl_break) 0) |
|
(item.relation.parent token 'Boundary)) |
|
(item.feat (item.relation.parent token 'Boundary) 'type) |
|
0))) |
|
|
|
(define (apml_LHLH syl) |
|
(let ((accent (apml_accent syl)) |
|
(boundary (apml_boundary syl))) |
|
(if (and (string-equal accent "LplusHstar") |
|
(string-equal boundary "LH")) |
|
"LHLH" |
|
0))) |
|
|
|
|
|
(define (apml_seg_is_LHLH_vowel seg) |
|
(if (and (string-equal (apml_LHLH (item.relation.parent seg 'SylStructure)) |
|
"LHLH") |
|
(string-equal (item.feat seg 'ph_vc) "+")) |
|
"LHLH" |
|
0)) |
|
|
|
|
|
|
|
|
|
(define (apml_tgtype syl) |
|
(let ((l (apml_boundl (item.relation.parent syl 'SylStructure))) |
|
(r (apml_boundr (item.relation.parent syl 'SylStructure)))) |
|
(if (eq (item.feat syl 'accented) 0) |
|
0 |
|
(cond |
|
((eq l 0) |
|
1) |
|
((eq r 1) |
|
3) |
|
(t 2))))) |
|
|
|
|
|
(define (apml_iecount syl) |
|
(if (eq (item.feat syl 'accented) 0) |
|
0 |
|
(+ (item.feat syl 'asyl_in) 1))) |
|
|
|
|
|
(define (apml_boundl word) |
|
"(apml_boundl word) |
|
Number of boundaries in this performative to the left of this word." |
|
(let ((w (item.prev word)) |
|
(c 0)) |
|
(while (and w (apml_same_p w word)) |
|
(if (item.relation.parent (item.relation.parent w 'Token) 'Boundary) |
|
(set! c (+ c 1))) |
|
(set! w (item.prev w))) |
|
c)) |
|
|
|
(define (apml_boundr word) |
|
"(apml_boundr word) |
|
Number of boundaries in this performative to the right of this word." |
|
(let ((w word) |
|
(c 0)) |
|
(while (and w (apml_same_p w word)) |
|
(if (item.relation.parent (item.relation.parent w 'Token) 'Boundary) |
|
(set! c (+ c 1))) |
|
(set! w (item.next w))) |
|
c)) |
|
|
|
(define (apml_same_p w1 w2) |
|
"(apml_same_p w1 w2) |
|
Are these two words in the same performative?" |
|
(let ((p1 (item.relation.parent (item.relation.parent w1 'Token) 'SemStructure)) |
|
(p2 (item.relation.parent (item.relation.parent w1 'Token) 'SemStructure))) |
|
(if (and (item.parent p1) (item.parent p2)) |
|
(equal? (item.parent p1) (item.parent p2)) |
|
(equal? p1 p2)))) |
|
|
|
|
|
|
|
|
|
|
|
(define (apml_seg_times utt) |
|
"(apml_seg_times utt) |
|
Output the segment timings for an apml utterance." |
|
(let ((segs (utt.relation.items utt 'Segment))) |
|
(mapcar |
|
(lambda (x) |
|
(format t "%s %s\n" (item.name x) (item.feat x 'end))) |
|
segs) |
|
t)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (find_hstar_left syl) |
|
"(find_hstar_left syl) |
|
If the closest accent or boundary to the left is H* return how many syllables away it is. Returns 0 if nearest accent is not H*" |
|
(let ((count 0)) |
|
|
|
(if (or (not (string-equal (item.feat syl 'tobi_accent) "NONE")) |
|
(not (string-equal (item.feat syl 'tobi_endtone) "NONE"))) |
|
0) |
|
(while (and syl |
|
(string-equal (item.feat syl 'tobi_accent) "NONE") |
|
(string-equal (item.feat syl 'tobi_endtone) "NONE")) |
|
(set! count (+ count 1)) |
|
(set! syl (item.prev syl))) |
|
(cond |
|
|
|
((null syl) |
|
0) |
|
((string-equal (item.feat syl 'tobi_accent) "H*") |
|
count) |
|
(t 0)))) |
|
|
|
(define (find_ll_right syl) |
|
"(find_ll_right syl) |
|
If the closest accent or boundary to the right is L-L% return how many syllables away it is. Returns 0 if nearest is not L-L%." |
|
(let ((count 0)) |
|
|
|
(if (or (not (string-equal (item.feat syl 'tobi_accent) "NONE")) |
|
(not (string-equal (item.feat syl 'tobi_endtone) "NONE"))) |
|
0) |
|
(while (and syl |
|
(string-equal (item.feat syl 'tobi_accent) "NONE") |
|
(string-equal (item.feat syl 'tobi_endtone) "NONE")) |
|
(set! count (+ count 1)) |
|
(set! syl (item.next syl))) |
|
(cond |
|
|
|
((null syl) |
|
0) |
|
((string-equal (item.feat syl 'tobi_endtone) "L-L%") |
|
count) |
|
(t 0)))) |
|
|
|
(define (l_spread syl) |
|
"(l_spread syl) |
|
Proportion of pitch lowering required due to L- spreading backwards." |
|
(let ((l (find_hstar_left syl)) |
|
(r (find_ll_right syl))) |
|
(cond |
|
((or (eq l 0) |
|
(eq r 0)) |
|
0) |
|
(t |
|
(/ r (- (+ l r) 1)))))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (apml_print_semstruct utt) |
|
"(apml_print_semstruct utt) |
|
Pretty print APML semantic structure." |
|
(let ((i (utt.relation.first utt 'SemStructure))) |
|
(while (not (null i)) |
|
(apml_pss_item 0 i) |
|
(apml_pss_daughters 1 (item.daughters i)) |
|
(set! i (item.next i))))) |
|
|
|
(define (apml_pss_daughters depth list) |
|
(mapcar |
|
(lambda (x) |
|
(apml_pss_item depth x) |
|
(apml_pss_daughters (+ depth 1) (item.daughters x)) |
|
) |
|
list)) |
|
|
|
|
|
(define (apml_pss_item depth item) |
|
(let ((c 0)) |
|
(while (< c depth) |
|
(format t " ") |
|
(set! c (+ c 1))) |
|
(format t "%s\n" (item.name item)))) |
|
|
|
|
|
(define (apml_print_words utt) |
|
"(apml_print_words utt) |
|
Pretty print APML words with associated accents." |
|
(mapcar |
|
(lambda (x) |
|
(format t "%s (" (item.name x)) |
|
(apml_pww_accent x) |
|
(apml_pww_boundary x) |
|
(apml_pww_pause x) |
|
(format t ")\n")) |
|
(utt.relation.items utt 'Word)) |
|
t) |
|
|
|
(define (apml_pww_accent item) |
|
(let ((p (item.relation.parent (item.relation.parent item 'Token) 'Emphasis))) |
|
(if p (apml_ppw_list (item.features p))))) |
|
|
|
(define (apml_pww_boundary item) |
|
(let ((p (item.relation.parent (item.relation.parent item 'Token) 'Boundary))) |
|
(if p (apml_ppw_list (item.features p))))) |
|
|
|
(define (apml_pww_pause item) |
|
(let ((p (item.relation.parent (item.relation.parent item 'Token) 'Pause))) |
|
(if p (apml_ppw_list (item.features p))))) |
|
|
|
(define (apml_ppw_list l) |
|
(mapcar |
|
(lambda (x) |
|
(format t " %s" x)) |
|
(flatten l))) |
|
|
|
|
|
(define (apml_print_sylstructure utt filename) |
|
"(apml_print_sylstructure utt filename) |
|
Pretty print APML syllable structure. Filename t for stdout" |
|
(let (fd) |
|
(if (not (eq? filename t)) |
|
(set! fd (fopen filename "wb")) |
|
(set! fd t)) |
|
(mapcar |
|
(lambda (x) |
|
(format fd "%s\n" (item.name x)) |
|
(apml_psyl fd x)) |
|
(utt.relation.items utt 'Word)) |
|
t)) |
|
|
|
(define (apml_psyl fd word) |
|
(mapcar |
|
(lambda (x) |
|
(apml_psegs fd x) |
|
(if (eq (item.feat x 'stress) 1) |
|
(format fd " (1)")) |
|
(if (item.relation.daughter1 x 'Intonation) |
|
(begin |
|
(let ((ie (item.relation.daughter1 x 'Intonation))) |
|
(format fd " [") |
|
(while ie |
|
(format fd "%s" (item.name ie)) |
|
(set! ie (item.next ie)) |
|
(if ie (format t " "))) |
|
(format fd "]")))) |
|
(format fd "\n")) |
|
(item.daughters (item.relation word 'SylStructure)))) |
|
|
|
(define (apml_psegs fd syl) |
|
(let ((segs (item.daughters syl))) |
|
(format fd " ") |
|
(while segs |
|
(format fd "%s" (item.name (car segs))) |
|
(if (cdr segs) |
|
(format fd ".")) |
|
(set! segs (cdr segs))))) |
|
|
|
|
|
(define (apml_get_lr_params) |
|
(let ((m 0) |
|
(s 0)) |
|
(if (or (equal? (Parameter.get 'Int_Target_Method) Int_Targets_LR) |
|
(equal? (Parameter.get 'Int_Target_Method) Int_Targets_5_LR)) |
|
(begin |
|
(set! m (car (cdr (car int_lr_params)))) |
|
(set! s (car (cdr (car (cdr int_lr_params)))))) |
|
(begin |
|
(set! m apml_default_pitch_mean) |
|
(set! s apml_default_pitch_standard_deviation))) |
|
(list m s))) |
|
|
|
|
|
|
|
|
|
(define (apml_initialise) |
|
"(apml_initialise) |
|
Set up the current voice for apml use." |
|
(if (not (string-matches current-voice ".*multisyn.*")) |
|
(cond |
|
((or (string-equal (Parameter.get 'Language) "americanenglish") |
|
(string-equal (Parameter.get 'Language) "britishenglish")) |
|
(begin |
|
(format t "Initialising APML for English.\n") |
|
|
|
(Parameter.set 'Phrase_Method 'cart_tree) |
|
(set! phrase_cart_tree apml_phrase_tree) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(set! int_accent_cart_tree apml_accent_cart) |
|
(set! int_tone_cart_tree apml_boundary_cart) |
|
(Parameter.set 'Int_Method Intonation_Tree) |
|
|
|
(set! f0_lr_start apml_f2b_f0_lr_start) |
|
(set! f0_lr_left apml_f2b_f0_lr_left) |
|
(set! f0_lr_mid apml_f2b_f0_lr_mid) |
|
(set! f0_lr_right apml_f2b_f0_lr_right) |
|
(set! f0_lr_end apml_f2b_f0_lr_end) |
|
(set! int_lr_params |
|
(list (list 'target_f0_mean (car (apml_get_lr_params))) |
|
(list 'target_f0_std (car (cdr (apml_get_lr_params)))) |
|
(list 'model_f0_mean 170) |
|
(list 'model_f0_std 40))) |
|
(Parameter.set 'Int_Target_Method Int_Targets_5_LR) |
|
nil)) |
|
((string-equal (Parameter.get 'Language) "italian") |
|
(begin |
|
(format t "Initialising APML for Italian.\n") |
|
|
|
(Parameter.set 'Phrase_Method 'cart_tree) |
|
(set! phrase_cart_tree apml_phrase_tree) |
|
|
|
(set! int_accent_cart_tree apml_accent_cart) |
|
(set! int_tone_cart_tree apml_boundary_cart) |
|
(Parameter.set 'Int_Method Intonation_Tree) |
|
|
|
(set! f0_lr_start apml_f2b_f0_lr_start) |
|
(set! f0_lr_mid apml_f2b_f0_lr_mid) |
|
(set! f0_lr_end apml_f2b_f0_lr_end) |
|
(set! int_lr_params |
|
(list (list 'target_f0_mean (car (apml_get_lr_params))) |
|
(list 'target_f0_std (car (cdr (apml_get_lr_params)))) |
|
(list 'model_f0_mean 170) |
|
(list 'model_f0_std 34))) |
|
(Parameter.set 'Int_Target_Method Int_Targets_LR) |
|
nil)) |
|
(t nil)))) |
|
|
|
(provide 'apml) |
|
|