home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / share / festival / sable-mode.scm < prev    next >
Encoding:
Text File  |  2006-12-20  |  19.9 KB  |  558 lines

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;                                                                       ;;
  3. ;;;                Centre for Speech Technology Research                  ;;
  4. ;;;                     University of Edinburgh, UK                       ;;
  5. ;;;                         Copyright (c) 1998                            ;;
  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. ;;;  Festival (1.3.X) support for SABLE 0.2 the SGML/XML based mark up    ;;
  35. ;;;  language.                                                            ;;
  36. ;;;                                                                       ;;
  37. ;;;  This is XML version requiring Edinburgh's LTG's rxp XML parser as    ;;
  38. ;;;  distributed with Festival                                            ;;
  39. ;;;                                                                       ;;
  40.  
  41. (require_module 'rxp)
  42.  
  43. ;;(set! auto-text-mode-alist
  44. ;;      (cons
  45. ;;       (cons "\\.sable$" 'sable)
  46. ;;       auto-text-mode-alist))
  47.  
  48.  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  49.  ;;                                                                       ;;
  50.  ;; Remember where to find these two XML entities.                        ;;
  51.  ;;                                                                       ;;
  52.  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  53.  
  54.  
  55. (xml_register_id "-//SABLE//DTD SABLE speech mark up//EN"
  56.         (path-append xml_dtd_dir  "Sable.v0_2.dtd")
  57.         )
  58.  
  59. (xml_register_id "-//SABLE//ENTITIES Added Latin 1 for SABLE//EN"
  60.          (path-append xml_dtd_dir  "sable-latin.ent")
  61.          )
  62.  
  63. ;; (print (xml_registered_ids))
  64.  
  65. (defvar SABLE_RXDOUBLE "-?\\(\\([0-9]+\\.[0-9]*\\)\\|\\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)\\([eE][---+]?[0-9]+\\)?")
  66.  
  67. (defvar sable_pitch_base_map
  68.   '((highest 1.2)
  69.     (high 1.1)
  70.     (medium 1.0)
  71.     (default 1.0)
  72.     (low 0.9)
  73.     (lowest 0.8)))
  74. (defvar sable_pitch_med_map
  75.   '((highest 1.2)
  76.     (high 1.1)
  77.     (medium 1.0)
  78.     (default 1.0)
  79.     (low 0.9)
  80.     (lowest 0.8)))
  81. (defvar sable_pitch_range_map
  82.   '((largest 1.2)
  83.     (large 1.1)
  84.     (medium 1.0)
  85.     (default 1.0)
  86.     (small 0.9)
  87.     (smallest 0.8)))
  88. (defvar sable_rate_speed_map
  89.   '((fastest 1.5)
  90.     (fast 1.2)
  91.     (medium 1.0)
  92.     (default 1.0)
  93.     (slow 0.8)
  94.     (slowest 0.6)))
  95. (defvar sable_volume_level_map
  96.   '((loudest 2.0) 
  97.     (loud 1.5)
  98.     (default 1.0)
  99.     (medium 1.0)
  100.     (quiet 0.5)))
  101.  
  102. (define (sable_init_globals)
  103.   (set! utts nil)
  104.   (set! sable_omitted_mode nil)
  105.   (set! sable_word_features_stack nil)
  106.   (set! sable_pitch_context nil)
  107.   (set! sable_vol_context nil)
  108.   (set! sable_vol_type 'no_change)
  109.   (set! sable_vol_factor 1.0)
  110.   (set! sable_current_language 'britishenglish)
  111.   (set! sable_unsupported_language nil)
  112.   (set! sable_language_stack nil)
  113.   (set! sable_current_speaker 'voice_rab_diphone)
  114.   (set! sable_speaker_stack nil)
  115. )
  116.  
  117. (define (sable_token_to_words token name)
  118.   "(sable_token_to_words utt token name)
  119. SABLE mode token specific analysis."
  120.   (cond
  121.    ((or sable_omitted_mode sable_unsupported_language)
  122.     ;; don't say anything (whole utterance)
  123.     nil)
  124.    ((string-equal "1" (item.feat token "done_sable_sub"))
  125.     ;; to catch recursive calls this when splitting up sub expressions
  126.     (sable_previous_token_to_words token name))
  127.    ((and (not (string-equal "0" (item.feat token "sable_sub")))
  128.      (string-equal "0" (item.feat token "p.sable_sub")))
  129.     (let (words (sub (item.feat token "sable_sub")))
  130.       (item.set_feat token "done_sable_sub" "1")
  131.       (set! words 
  132.         (apply append
  133.            (mapcar
  134.             (lambda (w)
  135.               (set! www (sable_previous_token_to_words token w))
  136.               www)
  137.             (read-from-string sub))))
  138.       (item.set_feat token "done_sable_sub" "0")
  139.       words))
  140.    ((string-equal "1" (item.feat token "sable_ignore"))
  141.     ;; don't say anything (individual word)
  142.     nil)
  143.    ((string-equal "1" (item.feat token "sable_ipa"))
  144.     ;; Each token is an IPA phone
  145.     (item.set_feat token "phonemes" (sable-map-ipa name))
  146.     (list name))
  147.    ((string-equal "1" (item.feat token "sable_literal"))
  148.     ;; Only deal with spell here
  149.     (let ((subwords) (subword))
  150.       (item.set_feat token "pos" token.letter_pos)
  151.       (mapcar
  152.        (lambda (letter)
  153.      ;; might be symbols or digits
  154.      (set! subword (sable_previous_token_to_words token letter))
  155.      (if subwords
  156.          (set! subwords (append subwords subword))
  157.          (set! subwords subword)))
  158.        (symbolexplode name))
  159.       subwords))
  160.    ((not (string-equal "0" (item.feat token "token_pos")))
  161.     ;; bypass the prediction stage, if English
  162.     (if (member_string (Parameter.get 'Language)
  163.                '(britishenglish americanenglish))
  164.     (builtin_english_token_to_words token name)
  165.     (sable_previous_token_to_words token name)))
  166.    ;; could be others here later
  167.    (t  
  168.     (sable_previous_token_to_words token name))))
  169.  
  170. (defvar sable_elements
  171. '(
  172.   ("(SABLE" (ATTLIST UTT)
  173.     (eval (list sable_current_speaker))  ;; so we know what state we start in
  174.     (sable_setup_voice_params)
  175.     nil
  176.   )
  177.   (")SABLE" (ATTLIST UTT)
  178.     (xxml_synth UTT)  ;;  Synthesis the remaining tokens
  179.     nil
  180.   )
  181.   ;; Utterance break elements
  182.   ("(LANGUAGE" (ATTLIST UTT)
  183.    ;; Status: probably complete 
  184.    (xxml_synth UTT)
  185.    (set! sable_language_stack 
  186.      (cons 
  187.       (list sable_current_language sable_unsupported_language)
  188.       sable_language_stack))
  189.    ;; Select a new language
  190.    (let ((language (upcase (car (xxml_attval "ID" ATTLIST)))))
  191.      (cond
  192.       ((or (string-equal language "SPANISH")
  193.        (string-equal language "ES"))
  194.        (set! sable_current_language 'spanish)
  195.        (set! sable_unsupported_language nil)
  196.        (select_language 'spanish))
  197.       ((or (string-equal language "ENGLISH")
  198.        (string-equal language "EN"))
  199.        (set! sable_current_language 'britishenglish)
  200.        (set! sable_unsupported_language nil)
  201.        (select_language 'britishenglish))
  202.       (t  ;; skip languages you don't know
  203.        ;; BUG: if current language isn't English this wont work
  204.        (apply_hooks tts_hooks
  205.             (eval (list 'Utterance 'Text
  206.                 (string-append "Some text in " language))))
  207.        (set! sable_unsupported_language t)))
  208.      nil))
  209.   (")LANGUAGE" (ATTLIST UTT)
  210.    (xxml_synth UTT)
  211.    (set! sable_unsupported_language (car (cdr (car sable_language_stack))))
  212.    (set! sable_current_language (car (car sable_language_stack)))
  213.    (set! sable_language_stack (cdr sable_language_stack))
  214.    (if (not sable_omitted_mode)
  215.        (begin
  216.      (select_language sable_current_language)
  217.      (sable_setup_voice_params)))
  218.    nil)
  219.   ("(SPEAKER" (ATTLIST UTT)
  220.    ;; Status: GENDER/AGE ignored, should be done by sable-def-speaker 
  221.    ;;         function to define Festival voices to SABLE
  222.    (xxml_synth UTT)
  223.    (set! sable_speaker_stack (cons sable_current_speaker sable_speaker_stack))
  224.    (cond
  225.     ((not equal? sable_current_language 'britishenglish)
  226.      (print "SABLE: choosen unknown voice, current voice unchanged"))
  227.     ((equal? (car (xxml_attval "NAME" ATTLIST)) 'male1)
  228.      (set! sable_current_speaker 'voice_rab_diphone)
  229.      (voice_rab_diphone))
  230.     ((equal? (car (xxml_attval "NAME" ATTLIST)) 'male2)
  231.      (set! sable_current_speaker 'voice_don_diphone)
  232.      (voice_don_diphone))
  233.     ((equal? (car (xxml_attval "NAME" ATTLIST)) 'male3)
  234.      (set! sable_current_speaker 'voice_ked_diphone)
  235.      (voice_ked_diphone))
  236.     ((equal? (car (xxml_attval "NAME" ATTLIST)) 'female1)
  237.      (set! sable_current_speaker 'voice_us1_mbrola)
  238.      (voice_us1_mbrola))
  239.     ((equal? (car (xxml_attval "NAME" ATTLIST)) 'male4)
  240.      (set! sable_current_speaker 'voice_us2_mbrola)
  241.      (voice_us2_mbrola))
  242.    (t
  243.       (set! sable_current_speaker (intern (string-append "voice_" (car (xxml_attval "NAME" ATTLIST)))))
  244.       (eval (list sable_current_speaker))))
  245.     (sable_setup_voice_params)
  246.    nil)
  247.   (")SPEAKER" (ATTLIST UTT)
  248.    (xxml_synth UTT)
  249.    (set! sable_utt UTT)
  250.    (set! sable_current_speaker (car sable_speaker_stack))
  251.    (set! sable_speaker_stack (cdr sable_speaker_stack))
  252.    (eval (list sable_current_speaker))
  253.    (sable_setup_voice_params)
  254.    nil)
  255.   ("BREAK" (ATTLIST UTT)
  256.    ;; Status: probably complete
  257.    ;; may cause an utterance break
  258.    (let ((level (upcase (car (xxml_attval "LEVEL" ATTLIST)))))
  259.      (cond
  260.       ((null UTT) nil)
  261.       ((string-equal "LARGE" level)
  262.        (xxml_synth UTT)
  263.        nil)
  264.       (t
  265.        (let ((last_token (utt.relation.last UTT'Token)))
  266.      (if last_token
  267.          (item.set_feat last_token "pbreak" "B"))
  268.      UTT)))))
  269.   ("(DIV" (ATLIST UTT)
  270.    ;; Status: probably complete
  271.    (xxml_synth UTT)
  272.    nil)
  273.   ("AUDIO" (ATTLIST UTT)
  274.    ;; Status: MODE (background) ignored, only insertion supported
  275.    ;; mime type of file also ignored, as its LEVEL
  276.    (let ((tmpfile (make_tmp_filename)))
  277.      ;; ignoring mode-background (and will for sometime)
  278.      ;; ignoring level option
  279.      (xxml_synth UTT)  ;; synthesizing anything ready to be synthesized
  280.      (get_url (car (xxml_attval "SRC" ATTLIST)) tmpfile)
  281.      (apply_hooks tts_hooks
  282.           (eval (list 'Utterance 'Wave tmpfile)))
  283.      (delete-file tmpfile)
  284.      nil))
  285.   ("(EMPH" (ATTLIST UTT)
  286.    ;; Status: nesting makes no difference, levels ignored
  287.    ;; Festival is particularly bad at adding specific emphasis
  288.    ;; that's what happens when you use statistical methods that
  289.    ;; don't include any notion of emphasis
  290.    ;; This is *not* recursive and only one level of EMPH supported
  291.    (sable_push_word_features)
  292.    (set! xxml_word_features 
  293.      (cons (list "dur_stretch" 1.6)
  294.            (cons
  295.         (list "EMPH" "1") xxml_word_features)))
  296.    UTT)
  297.   (")EMPH" (ATTLIST UTT)
  298.    (set! xxml_word_features (sable_pop_word_features))
  299.    UTT)
  300.   ("(PITCH" (ATTLIST UTT)
  301.    ;; Status: probably complete
  302.    ;; At present festival requires an utterance break here
  303.    (xxml_synth UTT)
  304.    (set! sable_pitch_context (cons int_lr_params sable_pitch_context))
  305.    (let ((base (sable_interpret_param
  306.         (car (xxml_attval "BASE" ATTLIST))
  307.         sable_pitch_base_map
  308.         (cadr (assoc 'target_f0_mean int_lr_params))
  309.         sable_pitch_base_original))
  310.      (med (sable_interpret_param
  311.            (car (xxml_attval "MED" ATTLIST))
  312.            sable_pitch_med_map
  313.            (cadr (assoc 'target_f0_mean int_lr_params))
  314.            sable_pitch_med_original))
  315.      (range (sable_interpret_param
  316.          (car (xxml_attval "RANGE" ATTLIST))
  317.          sable_pitch_range_map
  318.          (cadr (assoc 'target_f0_std int_lr_params))
  319.          sable_pitch_range_original))
  320.      (oldmean (cadr (assoc 'target_f0_mean int_lr_params))))
  321.      ;; Festival (if it supports anything) supports mean and std
  322.      ;; so we treat base as med if med doesn't seem to do anything
  323.      (if (equal? med oldmean)
  324.      (set! med base))
  325.      (set! int_lr_params
  326.        (cons
  327.         (list 'target_f0_mean med)
  328.         (cons
  329.          (list 'target_f0_std range)
  330.          int_lr_params)))
  331.    nil))
  332.   (")PITCH" (ATTLIST UTT)
  333.    (xxml_synth UTT)
  334.    (set! int_lr_params (car sable_pitch_context))
  335.    (set! sable_pitch_context (cdr sable_pitch_context))
  336.    nil)
  337.   ("(RATE" (ATTLIST UTT)
  338.    ;; Status: can't deal with absolute word per minute SPEED.
  339.    (sable_push_word_features)
  340.    ;; can't deal with words per minute value
  341.    (let ((rate (sable_interpret_param
  342.         (car (xxml_attval "SPEED" ATTLIST))
  343.         sable_rate_speed_map
  344.         (sable_find_fval "dur_stretch" xxml_word_features 1.0)
  345.         sable_rate_speed_original)))
  346.      (set! xxml_word_features 
  347.        (cons (list "dur_stretch" (/ 1.0 rate)) xxml_word_features))
  348.      UTT))
  349.   (")RATE" (ATTLIST UTT)
  350.    (set! xxml_word_features (sable_pop_word_features))
  351.    UTT)
  352.   ("(VOLUME" (ATTLIST UTT)
  353.    ;; Status: probably complete
  354.    ;; At present festival requires an utterance break here
  355.    (xxml_synth UTT)
  356.    (set! sable_vol_context (cons (list sable_vol_type sable_vol_factor)
  357.                  sable_vol_context))
  358.    (let ((level (sable_interpret_param
  359.         (car (xxml_attval "LEVEL" ATTLIST))
  360.         sable_volume_level_map
  361.         sable_vol_factor
  362.         1.0)))
  363.      (cond
  364.       ((string-matches (car (xxml_attval "LEVEL" ATTLIST)) ".*%")
  365.        (set! sable_vol_type 'relative))
  366.       ((string-matches (car (xxml_attval "LEVEL" ATTLIST))  SABLE_RXDOUBLE)
  367.        (set! sable_vol_type 'absolute))
  368.       (t
  369.        (set! sable_vol_type 'relative)))
  370.      (set! sable_vol_factor level))
  371.    nil)
  372.   (")VOLUME" (ATTLIST UTT)
  373.    (xxml_synth UTT)
  374.    (set! sable_vol_type (car (car sable_vol_context)))
  375.    (set! sable_vol_factor (car (cdr (car sable_vol_context))))
  376.    (set! sable_vol_context (cdr sable_vol_context))
  377.    nil)
  378.   ("(ENGINE" (ATTLIST UTT)
  379.    ;; Status: probably complete
  380.    (xxml_synth UTT)
  381.    (if (string-matches (car (xxml_attval "ID" ATTLIST)) "festival.*")
  382.        (let ((datastr ""))
  383.      (mapcar
  384.       (lambda (c) (set! datastr (string-append datastr " " c)))
  385.       (xxml_attval "DATA" ATTLIST))
  386.      (apply_hooks tts_hooks (eval (list 'Utterance 'Text datastr)))
  387.      (set! sable_omitted_mode t)) ;; ignore contents 
  388.        ;; else 
  389.        ;;  its not relevant to me
  390.        )
  391.    nil)
  392.   (")ENGINE" (ATTLIST UTT)
  393.    (xxml_synth UTT)
  394.    (set! sable_omitted_mode nil)
  395.    nil)
  396.   ("MARKER" (ATTLIST UTT)
  397.    ;; Status: does nothing
  398.    ;; Can't support this without low-level control of audio spooler
  399.    (format t "SABLE: marker \"%s\"\n" 
  400.        (car (xxml_attval "MARK" ATTLIST)))
  401.    UTT)
  402.   ("(PRON" (ATTLIST UTT)
  403.    ;; Status: IPA currently ignored
  404.    (sable_push_word_features)
  405.    ;; can't deal with words per minute value
  406.    (let ((ipa (xxml_attval "IPA" ATTLIST))
  407.      (sub (xxml_attval "SUB" ATTLIST)))
  408.      (cond
  409.       (ipa
  410.        (format t "SABLE: ipa ignored\n")
  411.        (set! xxml_word_features 
  412.          (cons (list "sable_ignore" "1") xxml_word_features)))
  413.       (sub
  414.        (set! xxml_word_features 
  415.          (cons (list "sable_sub" (format nil "%l" sub))
  416.            xxml_word_features))
  417.        (set! xxml_word_features 
  418.          (cons (list "sable_ignore" "1") xxml_word_features))))
  419.      UTT))
  420.   (")PRON" (ATTLIST UTT)
  421.    (set! xxml_word_features (sable_pop_word_features))
  422.    UTT)
  423.   ("(SAYAS" (ATTLIST UTT)
  424.    ;; Status: only a few of the types are dealt with
  425.    (sable_push_word_features)
  426.     (set! sable_utt UTT)
  427.    ;; can't deal with words per minute value
  428.    (let ((mode (downcase (car (xxml_attval "MODE" ATTLIST))))
  429.      (modetype (car (xxml_attval "MODETYPE" ATTLIST))))
  430.      (cond
  431.       ((string-equal mode "literal")
  432.        (set! xxml_word_features 
  433.          (cons (list "sable_literal" "1") xxml_word_features)))
  434.       ((string-equal mode "phone")
  435.        (set! xxml_word_features 
  436.          (cons (list "token_pos" "digits") xxml_word_features)))
  437.       ((string-equal mode "ordinal")
  438.        (set! xxml_word_features 
  439.          (cons (list "token_pos" "ordinal") xxml_word_features)))
  440.       ((string-equal mode "cardinal")
  441.        (set! xxml_word_features 
  442.          (cons (list "token_pos" "cardinal") xxml_word_features)))
  443.       (t
  444.        ;; blindly trust festival to get it right 
  445.        t))
  446.      UTT))
  447.   (")SAYAS" (ATTLIST UTT)
  448.    (set! xxml_word_features (sable_pop_word_features))
  449.    UTT)
  450.  
  451.          
  452. ))
  453.  
  454. (define (sable_init_func)
  455.   "(sable_init_func)
  456. Initialisation for SABLE mode"
  457.   (sable_init_globals)
  458.   (voice_rab_diphone)
  459.   (set! sable_previous_elements xxml_elements)
  460.   (set! xxml_elements sable_elements)
  461.   (set! sable_previous_token_to_words english_token_to_words)
  462.   (set! english_token_to_words sable_token_to_words)
  463.   (set! token_to_words sable_token_to_words))
  464.  
  465. (define (sable_exit_func)
  466.   "(sable_exit_func)
  467. Exit function for SABLE mode"
  468.   (set! xxml_elements sable_previous_elements)
  469.   (set! token_to_words sable_previous_token_to_words)
  470.   (set! english_token_to_words sable_previous_token_to_words))
  471.  
  472. (define (sable_push_word_features)
  473. "(sable_push_word_features)
  474. Save current word features on stack."
  475.   (set! sable_word_features_stack 
  476.     (cons xxml_word_features sable_word_features_stack)))
  477.  
  478. (define (sable_adjust_volume utt)
  479.   "(sable_adjust_volume utt)
  480. Amplify or attenutate signale based on value of sable_vol_factor
  481. and sable_vol_type (absolute or relative)."
  482.   (set! utts (cons utt utts))
  483.   (cond
  484.    ((equal? sable_vol_type 'no_change)
  485.     utt)
  486.    ((equal? sable_vol_type 'absolute)
  487.     (utt.wave.rescale utt sable_vol_factor 'absolute))
  488.    ((equal? sable_vol_type 'relative)
  489.     (utt.wave.rescale utt sable_vol_factor))
  490.    (t
  491.     (format stderr "SABLE: volume unknown type \"%s\"\n" sable_vol_type)
  492.     utt))
  493.    utt)
  494.  
  495. (define (sable_pop_word_features)
  496. "(sable_pop_word_features)
  497. Pop word features from stack."
  498.   (let ((r (car sable_word_features_stack)))
  499.     (set! sable_word_features_stack (cdr sable_word_features_stack))
  500.     r))
  501.  
  502. (define (sable_find_fval feat flist def)
  503.   (cond
  504.    ((null flist) def)
  505.    ((string-equal feat (car (car flist)))
  506.     (car (cdr (car flist))))
  507.    (t
  508.     (sable_find_fval feat (cdr flist) def))))
  509.  
  510. (define (sable_interpret_param ident map original current)
  511. "(sable_interpret_param IDENT MAP ORIGINAL CURRENT)
  512. If IDENT is in map return ORIGINAL times value in map, otherwise
  513. treat IDENT of the form +/-N% and modify CURRENT accordingly."
  514.   (let ((mm (assoc ident map)))
  515.     (cond 
  516.      (mm
  517.       (* original (car (cdr mm))))
  518.      ((string-matches ident SABLE_RXDOUBLE)
  519.       (parse-number ident))
  520.      ((string-matches ident ".*%")
  521.       (+ current (* current (/ (parse-number (string-before ident "%")) 
  522.                    100.0))))
  523. ;;     ((string-matches ident ".*%")
  524. ;;      (* current (/ (parse-number (string-before ident "%")) 100.0)))
  525.      ((not ident) current)
  526.      (t
  527.       (format stderr "SABLE: modifier \"%s\" not of float, tag or +/-N\n"
  528.           ident)
  529.       current))))
  530.  
  531. (define (sable_setup_voice_params)
  532. "(sable_setup_voice_params)
  533. Set up original values for various voice parameters."
  534.  (set! sable_pitch_base_original (cadr (assoc 'target_f0_mean int_lr_params)))
  535.  (set! sable_pitch_med_original (cadr (assoc 'target_f0_mean int_lr_params)))
  536.  (set! sable_pitch_range_original (cadr (assoc 'target_f0_std int_lr_params)))
  537.  (set! sable_rate_speed_original 1.0)
  538.  (if (and after_synth_hooks (not (consp after_synth_hooks)))
  539.      (set! after_synth_hooks 
  540.        (cons after_synth_hooks (list sable_adjust_volume)))
  541.      (set! after_synth_hooks 
  542.        (append after_synth_hooks (list sable_adjust_volume))))
  543. )
  544.  
  545. ;;; Declare the new mode to Festival
  546. (set! tts_text_modes
  547.    (cons
  548.     (list
  549.       'sable   ;; mode name
  550.       (list         
  551.        (list 'init_func sable_init_func)
  552.        (list 'exit_func sable_exit_func)
  553.        '(analysis_type xml)
  554.        ))
  555.     tts_text_modes))
  556.  
  557. (provide 'sable-mode)
  558.