home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / fest-141.zip / festival / lib / tobi_rules.scm < prev    next >
Text File  |  1999-05-30  |  30KB  |  822 lines

  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. ;;;                Authors: Robert A. J. Clark and Alan W Black
  34. ;;;                Modifications and Checking: 
  35. ;;;                         Gregor Moehler (moehler@ims.uni-stuttgart.de)
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37. ;;;
  38. ;;; Generate F0 points from tobi labels using rules given in:
  39. ;;; Jilka, Moehler & Dogil (forthcomming in Speech Communications)
  40. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  41. ;;;
  42. ;;;  *** Converted to new Relation architecture -- but not checked yet -- awb
  43. ;;;      -> crude (beta) checking: gm in Dec. 98
  44. ;;;
  45. ;;;  Known problems and bugs:
  46. ;;;      Can't currently use voicing intervals which cross syllable boundaries,
  47. ;;;      so pre/post-nuclear tones are currently places 0.2s before/after the 
  48. ;;;      nuclear tone even if no voicing occurs. Failing this they default a
  49. ;;;      percentage of the voicing for that syllable. 
  50. ;;; 
  51. ;;;      Don't know about target points ahead of the current syllable.
  52. ;;;      (As you need to know what comes before them to calculate them)
  53. ;;;      So: post accent tones are placed 0.2 ahead if following syllable exists
  54. ;;;          ends before 0.2 from starred target and is not accented
  55. ;;;      The H-target of the H+!H* is 0.2 sec instead of 0.15 sec before 
  56. ;;;      starred tone.
  57. ;;;      
  58. ;;;      Multi-utterance input has not been tested. 
  59. ;;;      
  60. ;;;      !H- does not generate any targets
  61. ;;;      
  62. ;;;      L-H% can't have an additional (high) accent in the last syllable
  63. ;;;      
  64. ;;;      Unfortunaltely some other modules may decide to put pauses in the 
  65. ;;;      middle of a phrase
  66. ;;;      
  67. ;;;      valleys are not tested yet
  68. ;;;      
  69. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  70. ;;;
  71. ;;;  To use this in a voice 
  72. ;;;     (require 'tobi_rules)
  73. ;;;  And in the voice call
  74. ;;;     (setup_tobi_f0_method)
  75. ;;;  Set the following for your speaker's F0 range
  76. ;;;  (Parameter.set 'Default_Topline 110)
  77. ;;;  (Parameter.set 'Default_Start_Baseline 90)
  78. ;;;  (Parameter.set 'Default_End_Baseline 80)
  79. ;;;  (Parameter.set 'Valley_Dip 75)
  80.  
  81. ;; level of debug printout
  82. (set! printdebug 0)
  83.  
  84. (define (setup_tobi_f0_method)
  85.   "(setup_tobi_f0_method)
  86. Set up parameters for current voice to use the implementaion
  87. of ToBI labels to F0 targets by rule."
  88.   (Parameter.set 'Int_Method Intonation_Tree)
  89.   (Parameter.set 'Int_Target_Method Int_Targets_General)
  90.   (set! int_accent_cart_tree no_int_cart_tree) ; NONE always
  91.   (set! int_tone_cart_tree   no_int_cart_tree) ; NONE always
  92.   (set! int_general_params
  93.     (list 
  94.      (list 'targ_func tobi_f0_targets)))   ; we will return a list of f0 targets here
  95.  
  96. ;  (Parameter.set 'Phrase_Method 'cart_tree)
  97.   (set! phrase_cart_tree tobi_label_phrase_cart_tree) ; redefines the phrasebreak tree
  98.   t)
  99.  
  100. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  101. ;;;;;;
  102. ;;;;;; Define and set the new f0 rules
  103. ;;;;;;
  104. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  105.  
  106. ;;; Set global parameters
  107. ;;; You may want to reset these for differen speakers
  108.  
  109. (Parameter.set 'Default_Topline 110) ;110
  110. (Parameter.set 'Default_Start_Baseline 90) ;87
  111. (Parameter.set 'Default_End_Baseline 80)   ;83
  112. (Parameter.set 'Current_Topline        (Parameter.get 'Default_Topline))
  113. (Parameter.set 'Current_Start_Baseline (Parameter.get 'Default_Start_Baseline))
  114. (Parameter.set 'Current_End_Baseline   (Parameter.get 'Default_End_Baseline))
  115. (Parameter.set 'Downstep_Factor 0.70)
  116. (Parameter.set 'Valley_Dip 75)
  117. ;;; function to add target points on a given syllable and fill in 
  118. ;;; targets where necessary
  119.  
  120. (define (tobi_f0_targets utt syl)
  121.   "(tobi_f0_targets UTT ITEM)
  122.    Returns a list of targets for the given syllable."
  123.   (if (and (>= printdebug  1)
  124.        (not(equal? 0 (item.feat syl "R:Intonation.daughter1.name"))))
  125.       (format t "### %l (%.2f %.2f) %l ptarg: %l ###\n" (item.name syl)
  126.           (item.feat syl "syllable_start")(item.feat syl "syllable_end")
  127.           (item.feat syl "R:Intonation.daughter1.name") (ttt_last_target syl)))
  128.   
  129.   ;; only continue if there is a Word related to this syllable
  130.   ;; I know there always should be, but there might be a bug elsewhere
  131.   (cond 
  132.    ((not(equal? 0 (item.feat syl "R:SylStructure.parent.name")))
  133.  
  134.     ; get current label. This assumes that there is only one accent and
  135.     ; one endtone on a syllable. Although there can be one of each.
  136.     (let ((voicing  (ttt_get_voice_times syl))                ; voicing interval
  137.       (pvoicing (ttt_get_voice_times                      ; previous voicing
  138.              (item.relation.prev syl 'Syllable)))
  139.       (nvoicing (ttt_get_voice_times                      ; next voicing
  140.              (item.relation.next syl 'Syllable)))) 
  141.  
  142.     ; if first syl of phrase set Phrase_Start and Phrase_End parameters
  143.     ; and reset downstep (currently does so on big and little breaks.)
  144.     ; only assignes Default values at this stage (maybe trained from CART later)
  145.     (if   (eq 0 (item.feat syl 'syl_in)) ;; GM maybe something better needed here?
  146.     (progn
  147.      (Parameter.set 'Phrase_Start (item.feat syl 'R:SylStructure.parent.R:Phrase.last.word_start))
  148.      (Parameter.set 'Phrase_End (item.feat syl 'R:SylStructure.parent.R:Phrase.last.word_end))
  149.      (Parameter.set 'Current_Topline (Parameter.get 'Default_Topline))
  150.      (Parameter.set 'Current_Start_Baseline (Parameter.get 'Default_Start_Baseline))
  151.      (Parameter.set 'Current_End_Baseline (Parameter.get 'Default_End_Baseline))
  152.      (if (>= printdebug  3)
  153.          (begin 
  154.            (print (format nil "new range: %f %f %f" 
  155.                   (Parameter.get 'Current_Topline) 
  156.                   (Parameter.get 'Current_End_Baseline)
  157.                   (Parameter.get 'Current_End_Baseline) ))))  ))
  158.  
  159.     ; do stuff (should go only if there is an accent/boundary?)
  160.     (let ((new_targets 
  161.        (ttt_to_targets syl (wagon syl ttt_starttone_tree)
  162.                voicing
  163.                pvoicing
  164.                nvoicing
  165.                'Starttones)))
  166.  
  167.     (set! new_targets (append new_targets 
  168.        (ttt_to_targets syl (wagon syl ttt_accent_tree)
  169.                voicing 
  170.                pvoicing 
  171.                nvoicing 
  172.                'Accents)))
  173.  
  174.     (set! new_targets (append new_targets 
  175.        (ttt_to_targets syl (wagon syl ttt_endtone_tree)
  176.                voicing
  177.                pvoicing
  178.                nvoicing
  179.                'Endtones)))
  180.  
  181.     (if (and(not(equal? new_targets nil))
  182.         (>= printdebug  2))
  183.     (begin
  184.       (format t ">> Targets: %l\n" new_targets)
  185.       (format t ">> LastTarget: %l\n" (last new_targets))
  186.       ))
  187.  
  188.       new_targets)))))
  189.  
  190.  
  191. ;;; CART tree to specify no accents
  192.  
  193. (set! no_int_cart_tree
  194. '
  195. ((NONE)))
  196.  
  197. ;;;
  198. ;;; Relate phrasing to boundary tones.
  199. ;;;
  200.  
  201. (set! tobi_label_phrase_cart_tree
  202. '
  203. ((tone in ("L-" "H-" "!H-"))
  204.  ((B))
  205.  ((tone in ("H-H%" "H-L%" "L-L%" "L-H%"))
  206.   ((BB))
  207.   ((NB)))))
  208.  
  209. ;;;
  210. ;;;  The other functions
  211. ;;;
  212.  
  213. ;;; process a list of relative targets and convert to actual targets
  214.  
  215. (define (ttt_to_targets syl rlist voicing pvoicing nvoicing type)
  216.   "Takes a list of target sets and returns a list of targets."
  217.   (if (or (and (>= printdebug  2)
  218.            rlist (atom (caar rlist)) 
  219.            (not (equal? 'NONE (caar rlist))) (not (equal? '(NONE) (caar rlist))))
  220.       (>= printdebug  3)) 
  221.        (begin (print "Entering ttt_to_targets with:")
  222.     (print (format nil "rlist: %l vc: %l pvc: %l nvc: %l type: %s" rlist voicing pvoicing nvoicing type))))
  223. (cond 
  224.  ;; nowt
  225.  ((eq (length rlist) 0) ())
  226.  ;; a single target set
  227.  ((atom (car (car rlist)))
  228.   (cond
  229.    ((eq type 'Accents)
  230.     (ttt_accent_set_to_targets syl rlist voicing pvoicing nvoicing))
  231.    ((eq type 'Starttones)
  232.     (ttt_bound_set_to_targets syl rlist voicing pvoicing))
  233.    ((eq type 'Endtones)
  234.     (ttt_bound_set_to_targets syl rlist voicing pvoicing))
  235.    (t (error "unknown target set encountered in ttt_to_targets"))))
  236.  ;; list of target sets
  237.  ((atom (car (car (car rlist))))
  238.   (append (ttt_to_targets syl (cdr rlist) voicing pvoicing nvoicing type)
  239.       (ttt_to_targets syl (car rlist) voicing pvoicing nvoicing type)))
  240.  ;; error
  241.  (t (error "something strange has happened in ttt_to_targets"))))
  242.  
  243.  
  244. ;; process a starttone/endtone target set.
  245.  
  246. (define (ttt_bound_set_to_targets syl tset voicing pvoicing)
  247.   "takes a start/endtone target set and returns a list of target points."
  248.   (if (>= printdebug  3) (begin
  249.       (print "Entering ttt_bound_set_to_targets with:")
  250.       (pprintf (format nil "tset: %l vc: %l pvc: %l" tset voicing pvoicing))))
  251.   (cond
  252.    ;; usually target given is NONE. (also ignore unknown!)
  253.    ((or (eq (car (car tset)) 'NONE)
  254.     (eq (car (car tset)) 'UNKNOWN))
  255.     nil)
  256.    ;; a pair of target pairs
  257.    ((eq (length tset) 2)
  258.     (list (ttt_get_target (car tset) voicing) 
  259.       (ttt_get_target (car (cdr tset)) voicing)))
  260.    ;; single target pair
  261.    ((eq (length tset) 1)
  262.     (cond
  263.      ;; an actual target pair
  264.      ((not (null (cdr (car tset))))
  265.       (list (ttt_get_target (car tset) voicing)))
  266.      ;; a TAKEOVER marker
  267.      ((eq (car (car tset)) 'TAKEOVER)
  268.       (list (list (ttt_interval_percent voicing 0) 
  269.           (ttt_last_target syl))))
  270.      (t (error "unknown target pair in ttt_bound_set_to_targets"))))
  271.    (t (error "unknown target set type in ttt_bound_set_to_targets"))))
  272.  
  273.  
  274. ;; process an accent target set.
  275.  
  276. (define (ttt_accent_set_to_targets syl tset voicing pvoicing nvoicing)
  277.   "takes a accent target set and returns a list of target points."
  278.   (if (>= printdebug  3) (begin
  279.       (print "Entering ttt_accent_set_to_targets with:")
  280.       (pprintf (format nil "tset: %l vc: %l pvc: %l nvc: %l" tset voicing pvoicing nvoicing))))
  281.   (cond
  282.    ;; single target in set
  283.    ((null (cdr tset)) 
  284.     (cond
  285.      ; target given is NONE.
  286.      ((or (eq (car (car tset)) 'NONE)
  287.       (eq (car (car tset)) 'UNKNOWN)) nil) 
  288.      ; V1 marker
  289.      ((eq (car (car tset)) 'V1)
  290.       (let ((target_time (+ (/ (- (next_accent_start syl)
  291.                   (ttt_last_target syl))
  292.                    2.0)
  293.                 (ttt_last_target syl))))
  294.     (list (list target_time (ttt_accent_pitch (Parameter.get 'Valley_Dip) target_time)))))
  295.      ; V2 marker
  296.      ((eq (car (car tset)) 'V2)
  297.       (let ((target_time (+ (ttt_last_target syl) 0.25)))
  298.     (list (list target_time (ttt_accent_pitch (Parameter.get 'Valley_Dip) target_time)))))
  299.      ; V3 marker
  300.      ((eq (car (car tset)) 'V3)
  301.       (let ((target_time (- (next_accent_start syl) 0.25)))
  302.     (list (list target_time (ttt_accent_pitch (Parameter.get 'Valley_Dip) target_time)))))     
  303.      ; single target pair
  304.      (t (list (ttt_get_target (car tset) voicing)))))
  305.    ;; a pair of targets
  306.    ((length tset 2)
  307.     (cond
  308.      ;; a *ed tone with PRE type tone (as in L+H*)
  309.      ((eq (car (car tset)) 'PRE)
  310.       (let ((star_target (ttt_get_target (car (cdr tset)) voicing))
  311.         (last_target (parse-number(ttt_last_target syl))))
  312.     (cond
  313.      ; normal 0.2s case (currently doesn't check for voicing)
  314.      ((and (< 0 (parse-number(item.feat syl "syl_in")))
  315.            (> (- (car star_target) 0.2) last_target))
  316.       (list  (list (- (car star_target) 0.2)
  317.                   (ttt_accent_pitch (car (cdr (car tset)))
  318.                      (- (car star_target) 0.2))) ; the time
  319.             star_target))
  320.      ; 90% prev voiced if not before last target
  321.         ; ((> (ttt_interval_percent pvoicing 90) 
  322.         ;      (ttt_last_target syl))
  323.         ;  (list (list (ttt_interval_percent pvoicing 90)
  324.         ;           (ttt_accent_pitch (car (cdr (car tset)))
  325.         ;                (ttt_interval_percent pvoicing 90)))
  326.         ;     star_target))
  327.  
  328.      ;  otherwise (UNTESTED) [NOTE: Voicing for this syllable only]
  329.      (t 
  330.       (list (list (ttt_interval_percent voicing 20)
  331.              (ttt_accent_pitch (car (cdr (car tset)))
  332.                        (ttt_interval_percent voicing 20)))
  333.            star_target)))))
  334.      ; a *ed tone with POST type tone (as L*+H)
  335.      ((eq (car(car(cdr tset))) 'POST)
  336.       (let ((star_target (ttt_get_target (car tset) voicing))
  337.         (next_target nil ) ; interesting problem
  338.         (next_syl (item.next syl)))
  339.  
  340.     (cond
  341.      ; normal 0.2s case (UNTESTED)
  342.      ((and (not (equal? next_syl nil))
  343.            (eq 0 (item.feat next_syl "accented")))
  344.       (cond
  345.        ((< (+ (car star_target) 0.2) (item.feat next_syl "syllable_end"))
  346.         (list star_target 
  347.           (list (+ (car star_target) 0.2) 
  348.             (ttt_accent_pitch (car (cdr (car (cdr tset))))
  349.                       (+ (car star_target) 0.2) ))))
  350.        (t 
  351.         
  352.         (list star_target
  353.             (list (ttt_interval_percent nvoicing 90)
  354.               (ttt_accent_pitch (car (cdr (car (cdr tset))))
  355.                         (ttt_interval_percent nvoicing 90) ))))))
  356.  
  357.      ; 20% next voiced (BUG: Can't do this as the next target hasn't been
  358.      ;                                                     calculated yet!)
  359.      (nil nil)
  360.      ;otherwise (UNTESTED)
  361.      (t (list star_target
  362.           (list (ttt_interval_percent voicing 90)
  363.             (ttt_accent_pitch (car (cdr (car (cdr tset))))
  364.                       (ttt_interval_percent voicing 90) )))))))
  365.      
  366.      (t 
  367.       (error (format nil "Unknown pair of targets: %l" tset)))))
  368.    
  369.    ;; something else...
  370.    (t (error (format nil "unknown accent set in ttt_accent_set_to_targets: %l" tset)))))
  371.  
  372.  
  373.  
  374. (define (ttt_get_target pair voicing)
  375.   "Returns actual target pair, usually for a stared tone."
  376.   (if (>= printdebug  4) (begin
  377.       (print "Entering ttt_get_target with:")
  378.       (pprintf pair) (pprintf voicing)))
  379.   (list (ttt_interval_percent voicing (car pair))
  380.     (ttt_accent_pitch (car (cdr pair))
  381.               (ttt_interval_percent voicing (car pair)))))
  382.  
  383. (define (ttt_accent_pitch value time)
  384.   "Converts a accent pitch entry to a pitch value."
  385.   (if (>= printdebug  4) (begin
  386.       (print "Entering ttt_accent_pitch with:")
  387.       (pprintf value)))
  388.   (cond
  389.    ;; a real value
  390.    ((number? value) 
  391.     (ttt_interval_percent (list (ttt_get_current_baseline time)
  392.                 (Parameter.get 'Current_Topline))
  393.               value))
  394.    ;; Downstep then Topline
  395.    ((eq value 'DHIGH)
  396.     (progn
  397.      (Parameter.set 'Current_Topline (+ (ttt_get_current_baseline time)
  398.                     (* (Parameter.get 'Downstep_Factor)
  399.                        (- (Parameter.get 'Current_Topline)
  400.                           (ttt_get_current_baseline time)))))
  401.      (ttt_interval_percent (list (ttt_get_current_baseline time)
  402.                  (Parameter.get 'Current_Topline))
  403.                100)))
  404.      
  405.    ;; Unknown
  406.    (t  (error "Unknown accent pitch value encountered"))))
  407.  
  408.  
  409. (define (ttt_get_current_baseline v)
  410.   "Returns the current declined baseline at time v."
  411.   (if (>= printdebug  4) (begin
  412.       (print "Entering  ttt_get_current_baseline with:")
  413.       (pprintf v)))
  414.   (let ((h (Parameter.get 'Current_Start_Baseline))
  415.     (l (Parameter.get 'Current_End_Baseline))
  416.     (e (Parameter.get 'Phrase_End))
  417.     (s (Parameter.get 'Phrase_Start)))
  418.     (- h (* (/ (- h l) (- e s)) (- v s)))))
  419.  
  420. ;;; find the time n% through an inteval
  421.  
  422. (define (ttt_interval_percent pair percent)
  423.   "Returns the time that is percent percent thought the pair."
  424.   (if (>= printdebug  4) (begin
  425.       (print "Entering ttt_interval_percent with:")
  426.       (pprintf (format nil "%l, %l" pair percent))))
  427.   (cond
  428.    ; no pair given: just return nil
  429.    ((null pair) nil)
  430.    ; otherwise do the calculation
  431.    (t (let ((start (car pair))
  432.         (end (car(cdr pair))))
  433.     (+ start (* (- end start) (/ percent 100)))))))
  434.  
  435.  
  436. ;;;  Getting start and end voicing times in a syllable
  437.  
  438. (define (ttt_get_voice_times syl_item)
  439.   "Returns a pair of start time of first voiced phone in syllable and
  440. end of last voiced phone in syllable, or nil if syllable is nil"
  441.   (cond
  442.    ((null syl_item) nil)
  443.    (t (let ((segs (item.relation.daughters syl_item "SylStructure")))
  444.     (list
  445.      (item.feat (ttt_first_voiced segs) "segment_start")
  446.      (item.feat (ttt_first_voiced (reverse segs)) "end"))))))
  447.  
  448. (define (ttt_first_voiced segs)
  449.   "Returns first segment that is voiced (vowel or voiced consonant)
  450. returns last segment if all are unvoiced."
  451.   (cond
  452.    ((null (cdr segs))
  453.     (car segs))  ;; last possibility
  454.    ((equal? "+" (item.feat (car segs) "ph_vc"))
  455.     (car segs))
  456.    ((equal? "+" (item.feat (car segs) "ph_cvox"))
  457.     (car segs))
  458.    (t
  459.     (ttt_first_voiced (cdr segs)))))
  460.  
  461. (define (ttt_last_target syl)
  462.   "Returns the end of the most recent previous target 
  463. in the utterance or nil if there is not one present
  464. "
  465. (if (>= printdebug  3)
  466.     (begin (print "Entering  ttt_last_target")
  467.     (print syl))
  468.     )
  469.   (let ((prev_syl (item.relation.prev syl 'Syllable)))
  470.     (cond
  471. ;     ((symbol-bound? 'new_targets) (last (caar new_targets)))
  472.      ((null prev_syl) nil)
  473.      ((ttt_last_target_segs 
  474.        (reverse (item.relation.daughters prev_syl "SylStructure")))) ;list of segments of prev. syllables
  475.      (t (ttt_last_target prev_syl)))))
  476.  
  477. (define (ttt_last_target_segs segs)
  478.   "Returns the end of the first target in a list of segments,
  479. or nil if there is not one
  480. "
  481. (if (>= printdebug  4)
  482.     (begin (print "Entering  ttt_last_target_segs with:")
  483.        (pprintf (format nil "%l" segs))
  484. ))
  485.   (cond
  486.    ((null segs) nil)
  487.    ((and  (> (parse-number 
  488.           (item.feat  (car segs) "R:Target.daughter1.f0")) 0)
  489.       (eq 0 (item.feat (car segs) "R:SylStructure.parent.lisp_lh_condition"))
  490.       (eq 0 (item.feat (car segs) "R:SylStructure.parent.lisp_hl_condition"))
  491.       (eq 0 (item.feat (car segs) "R:SylStructure.parent.lisp_valley_condition")))
  492.     (item.feat (car segs) "R:Target.daughter1.pos"))
  493.    
  494.    (t (ttt_last_target_segs (cdr segs)))))
  495.  
  496. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  497. ;;;;;;
  498. ;;;;;; CART TREES                           (ttt - tobi to target)
  499. ;;;;;;
  500. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  501.  
  502. ;;;
  503. ;;; Return a list of target lists. A target list comprises of a list
  504. ;;; of related targets (ie for the L and H in L+H*), just to confuse
  505. ;;; matters each target is also a list! (pos pitch)
  506. ;;;
  507.  
  508.  
  509. (set! ttt_endtone_tree  ; BUG: does it check the current syl for last accent?
  510.       '
  511.       ((tobi_endtone is NONE)        ; ususally none
  512.        ((((NONE))))
  513.        ((tobi_endtone is "H-H%")     ; H-H%
  514.     ((((100 120))))
  515.     ((tobi_endtone is "L-L%")    ; L-L%
  516.      ((((100 -20))))
  517.      ((tobi_endtone is "L-H%")   ; L-H%
  518.       ((lisp_last_accent > 2)
  519.        ((lisp_last_accent_type is "L*") ;GM  2nd point 80->40 of pitchrange
  520.         ((((0 25) (100 40))))
  521.         ((((0 0) (100 40)))))
  522.        ((lisp_last_accent_type is "L*")
  523.         ((((100 40))))
  524.         ((((50 0) (100 40))))))
  525.       ((tobi_endtone is "H-L%")  ; H-L%
  526.        ((lisp_last_accent_type is "L*")
  527.         ((tobi_accent is"L*")
  528.          ((((50 100) (100 100))))
  529.          ((((0 100) (100 100)))))
  530.         ((((100 100)))))
  531.       ((tobi_endtone is "!H-L%")  ; !H-L%
  532.        ((lisp_last_accent_type is "L*")
  533.         ((tobi_accent is"L*")
  534.          ((((50 DHIGH) (100 100))))
  535.          ((((0 DHIGH) (100 100)))))
  536.         ((((100 DHIGH)))))
  537.        ((tobi_endtone is "H-")
  538.         ((((100 100))))
  539.         ((tobi_endtone is "!H-")
  540.          ((((100 DHIGH))))
  541.          ((tobi_endtone is "L-")
  542.           ((((100 0))))
  543.           ((((UNKNOWN))))))))))))))
  544.  
  545. (set! ttt_starttone_tree
  546.       '
  547.       ((syl_in = 0)                                    ;; GM better: (lisp_ip_initial = 1)
  548.        ((tobi_endtone is "%H")
  549.     ((((0 100))))
  550.     ((p.tobi_endtone in ("H-" "!H-" "L-"))
  551.      ((((TAKEOVER))))       ; takeover case
  552.      ((tobi_accent is NONE)  
  553.       ((lisp_next_accent > 2) ; default cases  (dep. on whether next target is low)
  554.        ((lisp_next_accent_type in ("L*" "L*+H" "L*+!H" "L+H*" "L+!H*" "L-" "L-H%" "L-L%"))
  555.         ((((0 50)(100 25))))
  556.         ((((0 50)(100 75)))))
  557.        ((lisp_next_accent_type in ("L*" "L*+H" "L*+!H" "L+H*" "L+!H*" "L-" "L-H%" "L-L%"))
  558.         ((((0 30))))
  559.         ((((0 70))))))
  560.       ((tobi_accent in ("L*" "L*+H" "L*+!H" "L+H*" "L+!H*" "L-" "L-H%" "L-L%"))
  561.         ((((0 30))))
  562.         ((((0 70))))))))
  563.        ((((NONE))))))     ; otherwise (and usually) nothing.  
  564.  
  565. (set! ttt_accent_tree
  566.       '
  567.       ((tobi_accent is "H*" )    ; H*
  568.        ((lisp_ip_initial = 1) 
  569.     ((lisp_ip_final = 1)
  570.      ((((50 100))))
  571.      ((((85 100)))))
  572.     ((lisp_ip_final = 1)
  573.      ((((25 100))))
  574.      ((((60 100))))))
  575.        ((tobi_accent is "!H*" )    ; !H*
  576.     ((lisp_ip_initial = 1) 
  577.      ((lisp_ip_final = 1)
  578.       ((((50 DHIGH))))
  579.       ((((85 DHIGH)))))
  580.      ((lisp_ip_final = 1)
  581.       ((((25 DHIGH))))
  582.       ((((60 DHIGH))))))
  583.     ((tobi_accent is "L*" )    ; L*
  584.      ((lisp_ip_initial = 1) 
  585.       ((lisp_ip_final = 1)
  586.        ((((50 0))))
  587.        ((((85 0)))))
  588.       ((lisp_ip_final = 1)
  589.        ((((25 0))))
  590.        ((((60 0))))))
  591.      ((tobi_accent is "L+H*")   ; L+H*
  592.       ((lisp_ip_initial = 1) 
  593.        ((lisp_ip_final = 1)
  594.         ((((PRE 20) (70 100))))    
  595.         ((((PRE 20) (90 100)))))   
  596.        ((lisp_ip_final = 1)
  597.         ((((PRE 20) (25 100))))
  598.         ((((PRE 20) (75 100))))))
  599.      ((tobi_accent is "L+!H*")   ; L+!H*
  600.       ((lisp_ip_initial = 1) 
  601.        ((lisp_ip_final = 1)
  602.         ((((PRE 20) (70 DHIGH)))) 
  603.         ((((PRE 20) (90 DHIGH)))))
  604.        ((lisp_ip_final = 1)
  605.         ((((PRE 20) (25 DHIGH))))
  606.         ((((PRE 20) (75 DHIGH))))))
  607.       ((tobi_accent is "L*+H")   ; L*+H
  608.        ((lisp_ip_initial = 1) 
  609.         ((lisp_ip_final = 1)
  610.          ((((35 0) (POST 100))))
  611.          ((((55 0) (POST 100)))))
  612.         ((lisp_ip_final = 1)
  613.          ((((15 0) (POST 100))))
  614.          ((((40 0) (POST 100))))))
  615.       ((tobi_accent is "L*+!H")   ; L*+!H
  616.        ((lisp_ip_initial = 1) 
  617.         ((lisp_ip_final = 1)
  618.          ((((35 0) (POST DHIGH))))
  619.          ((((55 0) (POST DHIGH)))))
  620.         ((lisp_ip_final = 1)
  621.          ((((15 0) (POST DHIGH))))
  622.          ((((40 0) (POST DHIGH))))))
  623.        ((tobi_accent is "H+!H*")    ; H+!H* 
  624.         ((lisp_ip_initial = 1)
  625.          ((lisp_ip_final = 1)
  626.           ((((PRE 143) (60 DHIGH)))) ; the 143 is a hack to level out the downstep
  627.           ((((PRE 143) (90 DHIGH)))))
  628.          ((lisp_ip_final = 1)
  629.           ((((PRE 143) (20 DHIGH))))
  630.           ((((PRE 143) (60 DHIGH))))))
  631.         ((lisp_lh_condition = 1) 
  632.          ((((100 75))))
  633.          ((lisp_lh_condition = 2)
  634.           ((((0 90))))    
  635.           ((lisp_hl_condition = 1)
  636.            ((((100 25))))
  637.            ((lisp_valley_condition = 1)
  638.         ((((V1 85))))
  639.         ((lisp_valley_condition = 2)
  640.          ((((V2 70))))
  641.          ((lisp_valley_condition = 3)
  642.           ((((V3 70))))
  643.           ((tobi_accent is NONE)   ; usually we find no accent
  644.            ((((NONE))))
  645.            ((((UNKNOWN))))))))))))))))))))     ; UNKNOWN TARGET FOUND
  646.  
  647.      
  648. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  649. ;;;;;;
  650. ;;;;;;   Lisp Feature functions.
  651. ;;;;;;
  652. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  653.  
  654. (define (valley_condition syl)
  655. "(valley_condition syl)
  656. Function to determine if a lowered target between two high target points
  657. is needed in this syllable.
  658. Returns:  0 - no target required
  659.           1 - the single target case
  660.           2 - the first of the two target case
  661.           3 - the second of the two target case
  662. "
  663. (if (>= printdebug  4)
  664.     (begin (print "Entering valley_condition")))
  665. (cond
  666.  ((and (eq 0 (item.feat syl 'accented))
  667.        (string-matches (next_accent_type syl)
  668.                "\\(H\\*\\|H\\-\\|H\\-L\\%\\|H\\-H\\%\\|\\!H\\*\\|\\!H\\-\\|\\!H\\-L\\%\\|\\!H\\-H\\%\\)")
  669.        (string-matches (last_accent_type syl)
  670.                "\\(H\\*\\|L\\+H\\*\\|L\\*\\+H\\\\|\\!H\\*\\|L\\+\\!H\\*\\|L\\*\\+\\!H\\)")) 
  671.                        ;GM: excluded %H (returns nil for last target)
  672.   (let ((nas (next_accent_start syl))
  673.     (syls (item.feat syl 'syllable_start))
  674.     (syle (item.feat syl 'syllable_end))
  675.     (las (ttt_last_target syl)))
  676.     (if (>= printdebug  3)
  677.     (begin (print (format nil "nas: %l syls: %l syle %l las %l" nas syls syle las))))
  678.     (cond
  679.      ((and (< (- nas las) 0.5)
  680.        (> (- nas las) 0.25)
  681.        (< syls (+ (/ (- nas las) 2.0) (ttt_last_target syl)))
  682.        (> syle (+ (/ (- nas las) 2.0) (ttt_last_target syl)))) 1)
  683.      ((and (> (- nas las) 0.5)
  684.        (< syls (+ (ttt_last_target syl) 0.25))
  685.        (> syle (+ (ttt_last_target syl) 0.25))) 2)
  686.      ((and (> (- nas las) 0.5)
  687.        (< syls (- nas 0.25))
  688.        (> syle (- nas 0.25))) 3)
  689.      (t 0))))
  690.  (t 0))) 
  691.    
  692.        
  693.  
  694. (define (lh_condition syl)
  695. "(lh_condition syl)
  696. Function to determine the need for extra target points between an L and an H
  697. Returns: 1 - first extra target required
  698.          2 - second extra target required
  699.          0 - no target required.
  700. "
  701. (if (>= printdebug  4)
  702.     (begin (print "Entering LH_condition")))
  703. (cond
  704.  ((and (eq 0 (item.feat syl 'accented))
  705.        (string-matches (last_accent_type syl) "\\(L\\*\\)")
  706.        (string-matches (next_accent_type syl)
  707.                "\\(H\\*\\|H\\-\\|H\\-L\\%\\|H\\-H\\%\\)"))
  708.   (cond
  709.    ((and (eq 1 (last_accent syl))
  710.      (< 2 (next_accent syl))) 1)
  711.    ((and (< 2 (last_accent syl))
  712.      (eq 1 (next_accent syl))) 2)
  713.    (t 0)))
  714.  (t 0)))
  715.  
  716. (define (hl_condition syl)
  717. "(lh_condition syl)
  718. Function to determine the need for extra target points between an H and an L
  719. Returns: 1 - extra target required
  720.          0 - no target required.
  721. "
  722. (if (>= printdebug  4) 
  723.     (begin (print "Entering HL_condition")))
  724. (cond
  725.  ((and (eq 0 (item.feat syl 'accented))
  726.        (string-matches (next_accent_type syl)
  727.            "\\(L\\*\\|L\\+H\\*\\|L\\*\\+H\\|L\\-\\|L\\-L\\%\\|L-H\\%\\)")
  728.        (string-matches (last_accent_type syl)
  729.                "\\(H\\*\\|L\\+H\\*\\|L\\*\\+H\\|\\%H\\)")
  730.        (eq 1 (last_accent syl))
  731.        (< 2 (next_accent syl))) 1)
  732.  (t 0)))
  733.  
  734. (define (next_accent syl)
  735. "(next_accent syl)
  736. Wrapper for c++ func ff_next_accent.
  737. Returns the number of the syllables to the next accent in the following format.
  738. 0 - no next accent
  739. 1 - next syllable
  740. 2 - next next syllable
  741. etc..."
  742. (if (>= printdebug  4) 
  743.     (begin (print "Entering next_accent")))
  744. (cond
  745.  ((eq 0 (next_accent_type syl)) 0)
  746.  (t (+ (item.feat syl 'next_accent) 1))))
  747.  
  748.  
  749. (define (last_accent syl)
  750. "(last_accent syl)
  751. Wrapper for c++ func ff_last_accent.
  752. Returns the number of the syllables to the previous accent in the following format.
  753. 0 - no prev accent
  754. 1 - prev syllable
  755. 2 - prev to prev syllable
  756. etc..."
  757. (if (>= printdebug  4) 
  758.     (begin (print "Entering last_accent")))
  759. (cond
  760.  ((eq 0 (last_accent_type syl)) 0)
  761.  (t (+  (item.feat syl 'last_accent) 1))))
  762.  
  763. (define (next_accent_type syl)
  764. "(next_accent_type syl)
  765. Returns the type of the next accent."
  766. (cond 
  767.  ((not (eq 0 (item.feat syl "n.R:Intonation.daughter1.name")))
  768.   (item.feat syl "n.R:Intonation.daughter1.name"))
  769.  ((eq 0 (item.feat syl 'syl_out)) 0)  ;;GM real ip_final would be better
  770.  (t (next_accent_type (item.relation.next syl 'Syllable)))))
  771.  
  772. (define (last_accent_type syl)
  773. "(last_accent_type syl)
  774. Returns the type of the last (previous)  accent."
  775. (if (>= printdebug  4) 
  776.     (begin (print "Entering last_accent_type")))
  777. (cond
  778.   ((not (equal? "NONE"  (item.feat syl 'p.tobi_endtone)))
  779.    (item.feat syl 'R:Syllable.p.tobi_endtone))
  780.   ((not (equal? "NONE"  (item.feat syl 'p.tobi_accent)))
  781.    (item.feat syl 'R:Syllable.p.tobi_accent))
  782.   ((eq 0 (item.feat syl 'syl_in)) 0)  ;;GM real ip_initial would be better
  783.   (t (last_accent_type (item.prev syl 'Syllable)))))
  784.  
  785. (define (next_accent_start syl)
  786. "(next_accent_start syl)
  787. Returns the start time  of the vowel of next accented syllable"
  788. (if (>= printdebug 4) 
  789.     (begin (print "Entering next_accent_start")))
  790. (cond 
  791.  ((not (eq 0 (item.feat syl "n.R:Intonation.daughter1.name")))
  792.   (item.feat syl "R:Syllable.n.syllable_start")) ;;GM vowel start would be better
  793.  ((eq 0 (item.feat syl 'syl_out)) 0)
  794.  (t (next_accent_start (item.relation.next syl 'Syllable)))))
  795.  
  796. ; new features (not used yet)
  797.  
  798. (define (ip_final syl)
  799.   "(ip_final SYL)
  800.   returns 1 if the syllable is the final syllable of an 
  801.   ip (intermediate phrase)"
  802.   (cond  
  803.    ((or (equal? 0 (item.feat syl "syl_out"))
  804.        (equal? "L-" (item.feat syl "tobi_endtone"))
  805.        (equal? "H-" (item.feat syl "tobi_endtone"))
  806.        (equal? "!H-" (item.feat syl "tobi_endtone"))) 1)
  807.    (t 0)))
  808.  
  809. (define (ip_initial syl)
  810.   "(ip_final SYL)
  811.   returns true if the syllable is the initial syllable of an 
  812.   ip (intermediate phrase)"
  813.   (cond
  814.    ((equal? 0 (item.feat syl "syl_in"))
  815.     1)
  816.    ((equal? 1 (ip_final (item.relation.prev syl 'Syllable)))
  817.     1)
  818.    (t 0)))
  819.  
  820.  
  821. (provide 'tobi_rules)
  822.