Sophie

Sophie

distrib > Mageia > 2 > i586 > by-pkgid > a2e5ae2091c2674a899ba2cbfce176e5 > files > 52

festival-2.1-3.mga1.i586.rpm

<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.52
     from ../festival.texi on 2 August 2001 -->

<TITLE>Festival Speech Synthesis System - 8  Scheme</TITLE>
</HEAD>
<BODY bgcolor="#ffffff">
Go to the <A HREF="festival_1.html">first</A>, <A HREF="festival_7.html">previous</A>, <A HREF="festival_9.html">next</A>, <A HREF="festival_35.html">last</A> section, <A HREF="festival_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC22" HREF="festival_toc.html#TOC22">8  Scheme</A></H1>

<P>
<A NAME="IDX79"></A>
Many people seem daunted by the fact that Festival uses Scheme as its
scripting language and feel they can't use Festival because they don't
know Scheme.  However most of those same people use Emacs everyday which
also has (a much more complex) Lisp system underneath.  The number of
Scheme commands you actually need to know in Festival is really very
small and you can easily just find out as you go along.  Also people use
the Unix shell often but only know a small fraction of actual commands
available in the shell (or in fact that there even is a distinction
between shell builtin commands and user definable ones).  So take it
easy, you'll learn the commands you need fairly quickly.

</P>



<H2><A NAME="SEC23" HREF="festival_toc.html#TOC23">8.1  Scheme references</A></H2>

<P>
If you wish to learn about Scheme in more detail I recommend
the book <CITE>abelson85</CITE>.

</P>
<P>
The Emacs Lisp documentation is reasonable as it is comprehensive and
many of the underlying uses of Scheme in Festival were influenced
by Emacs.  Emacs Lisp however is not Scheme so there are some
differences.

</P>
<P>
<A NAME="IDX80"></A>
Other Scheme tutorials and resources available on the Web are

<UL>
<LI>

The Revised Revised Revised Revised Scheme Report, the document
defining the language is available from 

<PRE>
<A HREF="http://tinuviel.cs.wcu.edu/res/ldp/r4rs-html/r4rs_toc.html">http://tinuviel.cs.wcu.edu/res/ldp/r4rs-html/r4rs_toc.html</A>
</PRE>

<LI>

a Scheme tutorials from the net:

<UL>
<LI><A HREF="http://www.cs.uoregon.edu/classes/cis425/schemeTutorial.html">http://www.cs.uoregon.edu/classes/cis425/schemeTutorial.html</A>

</UL>

<LI>the Scheme FAQ


<UL>
<LI><A HREF="http://www.landfield.com/faqs/scheme-faq/part1/">http://www.landfield.com/faqs/scheme-faq/part1/</A>

</UL>

</UL>



<H2><A NAME="SEC24" HREF="festival_toc.html#TOC24">8.2  Scheme fundamentals</A></H2>

<P>
But you want more now, don't you, not just be referred to some
other book.  OK here goes.

</P>
<P>
<EM>Syntax</EM>: an expression is an <EM>atom</EM> or a <EM>list</EM>.  A 
list consists of a left paren, a number of expressions and right
paren.  Atoms can be symbols, numbers, strings or other special
types like functions, hash tables, arrays, etc.

</P>
<P>
<EM>Semantics</EM>:  All expressions can be evaluated.  Lists are
evaluated as function calls.  When evaluating a list all the
members of the list are evaluated first then the first item (a
function) is called with the remaining items in the list as arguments.
Atoms are evaluated depending on their type: symbols are
evaluated as variables returning their values.  Numbers, strings,
functions, etc. evaluate to themselves.

</P>
<P>
Comments are started by a semicolon and run until end of line.

</P>
<P>
And that's it. There is nothing more to the language that.  But just
in case you can't follow the consequences of that, here are
some key examples.

</P>

<PRE>
festival&#62; (+ 2 3)
5
festival&#62; (set! a 4)
4
festival&#62; (* 3 a)
12
festival&#62; (define (add a b) (+ a b))
#&#60;CLOSURE (a b) (+ a b)&#62;
festival&#62; (add 3 4)
7
festival&#62; (set! alist '(apples pears bananas))
(apples pears bananas)
festival&#62; (car alist)
apples
festival&#62; (cdr alist)
(pears bananas)
festival&#62; (set! blist (cons 'oranges alist))
(oranges apples pears bananas)
festival&#62; (append alist blist)
(apples pears bananas oranges apples pears bananas)
festival&#62; (cons alist blist)
((apples pears bananas) oranges apples pears bananas)
festival&#62; (length alist)
3
festival&#62; (length (append alist blist))
7
</PRE>



<H2><A NAME="SEC25" HREF="festival_toc.html#TOC25">8.3  Scheme Festival specifics</A></H2>

<P>
There a number of additions to SIOD that are Festival specific though
still part of the Lisp system rather than the synthesis functions per se.

</P>
<P>
By convention if the first statement of a function is a string,
it is treated as a documentation string.  The string will be
printed when help is requested for that function symbol.

</P>
<P>
<A NAME="IDX81"></A>
<A NAME="IDX82"></A>
<A NAME="IDX83"></A>
In interactive mode if the function <CODE>:backtrace</CODE> is called (within
parenthesis) the previous stack trace is displayed.  Calling
<CODE>:backtrace</CODE> with a numeric argument will display that particular
stack frame in full.  Note that any command other than <CODE>:backtrace</CODE>
will reset the trace.  You may optionally call

<PRE>
(set_backtrace t)
</PRE>

<P>
Which will cause a backtrace to be displayed whenever a Scheme error
occurs. This can be put in your <TT>`.festivalrc'</TT> if you wish.  This
is especially useful when running Festival in non-interactive mode 
(batch or script mode) so that more information is printed when an error
occurs.

</P>
<P>
<A NAME="IDX84"></A>
A <EM>hook</EM> in Lisp terms is a position within some piece of code
where a user may specify their own customization.  The notion is used
heavily in Emacs.  In Festival there a number of places where hooks are
used.  A hook variable contains either a function or list of functions
that are to be applied at some point in the processing.  For example the
<CODE>after_synth_hooks</CODE> are applied after synthesis has been applied to
allow specific customization such as resampling or modification of the
gain of the synthesized waveform.  The Scheme function
<CODE>apply_hooks</CODE> takes a hook variable as argument and an object and
applies the function/list of functions in turn to the object.

</P>
<P>
<A NAME="IDX85"></A>
<A NAME="IDX86"></A>
<A NAME="IDX87"></A>
When an error occurs in either Scheme or within the C++ part of Festival
by default the system jumps to the top level, resets itself and
continues.  Note that errors are usually serious things, pointing to
bugs in parameters or code.  Every effort has been made to ensure
that the processing of text never causes errors in Festival.
However when using Festival as a development system it is often
that errors occur in code.  

</P>
<P>
Sometimes in writing Scheme code you know there is a potential for
an error but you wish to ignore that and continue on to the next
thing without exiting or stopping and returning to the top level.  For
example you are processing a number of utterances from a database and
some files containing the descriptions have errors in them but you
want your processing to continue through every utterance that can
be processed rather than stopping 5 minutes after you gone home after
setting a big batch job for overnight.

</P>
<P>
<A NAME="IDX88"></A>
<A NAME="IDX89"></A>
Festival's Scheme provides the function <CODE>unwind-protect</CODE> which
allows the catching of errors and then continuing normally.  For example
suppose you have the function <CODE>process_utt</CODE> which takes a filename
and does things which you know might cause an error.  You can write the
following to ensure you continue processing even in an error
occurs.

<PRE>
(unwind-protect
 (process_utt filename) 
 (begin
   (format t "Error found in processing %s\n" filename)
   (format t "continuing\n")))
</PRE>

<P>
The <CODE>unwind-protect</CODE> function takes two arguments.  The first is
evaluated and if no error occurs the value returned from that expression
is returned.  If an error does occur while evaluating the first
expression, the second expression is evaluated.  <CODE>unwind-protect</CODE>
may be used recursively.  Note that all files opened while evaluating
the first expression are closed if an error occurs.  All global
variables outside the scope of the <CODE>unwind-protect</CODE> will be left as
they were set up until the error.  Care should be taken in using this
function but its power is necessary to be able to write robust Scheme
code.

</P>


<H2><A NAME="SEC26" HREF="festival_toc.html#TOC26">8.4  Scheme I/O</A></H2>

<P>
<A NAME="IDX90"></A>
<A NAME="IDX91"></A>
Different Scheme's may have quite different implementations of 
file i/o functions so in this section we will describe the
basic functions in Festival SIOD regarding i/o.

</P>
<P>
Simple printing to the screen may be achieved with the function
<CODE>print</CODE> which prints the given s-expression to the screen.
The printed form is preceded by a new line.  This is often useful
for debugging but isn't really powerful enough for much else.

</P>
<P>
<A NAME="IDX92"></A>
<A NAME="IDX93"></A>
Files may be opened and closed and referred to file descriptors
in a direct analogy to C's stdio library.  The SIOD functions
<CODE>fopen</CODE> and <CODE>fclose</CODE> work in the exactly the same
way as their equivalently named partners in C.

</P>
<P>
<A NAME="IDX94"></A>
<A NAME="IDX95"></A>
The <CODE>format</CODE> command follows the command of the same name in Emacs
and a number of other Lisps.  C programmers can think of it as
<CODE>fprintf</CODE>.  <CODE>format</CODE> takes a file descriptor, format string
and arguments to print.  The file description may be a file descriptor
as returned by the Scheme function <CODE>fopen</CODE>, it may also be <CODE>t</CODE>
which means the output will be directed as standard out
(cf. <CODE>printf</CODE>).  A third possibility is <CODE>nil</CODE> which will cause
the output to printed to a string which is returned (cf. <CODE>sprintf</CODE>).

</P>
<P>
The format string  closely follows the format strings
in ANSI C, but it is not the same.  Specifically the directives
currently supported are, <CODE>%%</CODE>, <CODE>%d</CODE>, <CODE>%x</CODE>,
<CODE>%s</CODE>, <CODE>%f</CODE>, <CODE>%g</CODE> and <CODE>%c</CODE>.  All modifiers
for these are also supported.  In addition <CODE>%l</CODE> is provided
for printing of Scheme objects as objects.

</P>
<P>
For example

<PRE>
(format t "%03d %3.4f %s %l %l %l\n" 23 23 "abc" "abc" '(a b d) utt1)
</PRE>

<P>
will produce

<PRE>
023 23.0000 abc "abc" (a b d) #&#60;Utterance 32f228&#62;
</PRE>

<P>
on standard output.

</P>
<P>
<A NAME="IDX96"></A>
When large lisp expressions are printed they are difficult to read
because of the parentheses.  The function <CODE>pprintf</CODE> prints an
expression to a file description (or <CODE>t</CODE> for standard out).  It
prints so the s-expression is nicely lined up and indented.  This
is often called pretty printing in Lisps.

</P>
<P>
<A NAME="IDX97"></A>
<A NAME="IDX98"></A>
For reading input from terminal or file, there is currently no
equivalent to <CODE>scanf</CODE>.  Items may only be read as Scheme
expressions.  The command

<PRE>
(load FILENAME t)
</PRE>

<P>
will load all s-expressions in <CODE>FILENAME</CODE> and return them,
unevaluated as a list.  Without the third argument  the <CODE>load</CODE>
function will load and evaluate each s-expression in the file.

</P>
<P>
To read individual s-expressions use <CODE>readfp</CODE>.  For
example

<PRE>
(let ((fd (fopen trainfile "r"))
      (entry)
      (count 0))
    (while (not (equal? (set! entry (readfp fd)) (eof-val)))
     (if (string-equal (car entry) "home")
        (set! count (+ 1 count))))
    (fclose fd))
</PRE>

<P>
<A NAME="IDX99"></A>
<A NAME="IDX100"></A>
<A NAME="IDX101"></A>
<A NAME="IDX102"></A>
To convert a symbol whose print name is a number to a number
use <CODE>parse-number</CODE>.  This is the equivalent to <CODE>atof</CODE>
in C.

</P>
<P>
Note that, all i/o from Scheme input files is assumed to be
basically some form of Scheme data (though can be just numbers,
tokens).  For more elaborate analysis of incoming data it is
possible to use the text tokenization functions which offer
a fully programmable method of reading data.

</P>
<P><HR><P>
Go to the <A HREF="festival_1.html">first</A>, <A HREF="festival_7.html">previous</A>, <A HREF="festival_9.html">next</A>, <A HREF="festival_35.html">last</A> section, <A HREF="festival_toc.html">table of contents</A>.
</BODY>
</HTML>