diff --git a/.gitignore b/.gitignore
index 1df2052..14555f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,5 @@ build/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+.env
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Facture_Paiement_43.pdf b/Facture_Paiement_43.pdf
new file mode 100644
index 0000000..482fcfb
Binary files /dev/null and b/Facture_Paiement_43.pdf differ
diff --git a/lib/marytts-5.2.1.zip b/lib/marytts-5.2.1.zip
new file mode 100644
index 0000000..f5f9436
Binary files /dev/null and b/lib/marytts-5.2.1.zip differ
diff --git a/lib/marytts-5.2.1/.gitattributes b/lib/marytts-5.2.1/.gitattributes
new file mode 100644
index 0000000..b03bcca
--- /dev/null
+++ b/lib/marytts-5.2.1/.gitattributes
@@ -0,0 +1,10 @@
+# EOL encoding is LF, but native in working copy
+* text=auto
+
+# batch, markdown, properties, text, and config files should be viewable and user-editable
+# -- even in Windows Notepad, so CRLF EOL
+*.bat text eol=crlf
+*.config text eol=crlf
+*.md text eol=crlf
+*.properties text eol=crlf
+*.txt text eol=crlf
diff --git a/lib/marytts-5.2.1/.gitignore b/lib/marytts-5.2.1/.gitignore
new file mode 100644
index 0000000..6aa8e8b
--- /dev/null
+++ b/lib/marytts-5.2.1/.gitignore
@@ -0,0 +1,18 @@
+# Maven
+target/
+
+# Gradle
+.gradle/
+
+# Eclipse
+.settings/
+.project
+.classpath
+
+# misc. testing
+tmp/
+log/
+test-output/
+
+# OSX
+.DS_Store
diff --git a/lib/marytts-5.2.1/.travis.yml b/lib/marytts-5.2.1/.travis.yml
new file mode 100644
index 0000000..06c4503
--- /dev/null
+++ b/lib/marytts-5.2.1/.travis.yml
@@ -0,0 +1,18 @@
+sudo: false
+
+branches:
+ only:
+ - master
+ - 6.x
+
+language: java
+install: mvn install -DskipTests=true -P!standard-with-extra-repos
+script: mvn verify
+jdk:
+ - openjdk7
+ - oraclejdk7
+ - oraclejdk8
+
+cache:
+ directories:
+ - $HOME/.m2
diff --git a/lib/marytts-5.2.1/LICENSE.md b/lib/marytts-5.2.1/LICENSE.md
new file mode 100644
index 0000000..d5231df
--- /dev/null
+++ b/lib/marytts-5.2.1/LICENSE.md
@@ -0,0 +1,62 @@
+MaryTTS Software User Agreement
+===============================
+
+*26 January 2014*
+
+MaryTTS licensing
+-----------------
+
+MaryTTS is licensed under the following terms.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program. If not, see .
+
+Applicable Licenses
+-------------------
+
+MaryTTS is built upon a number of other open source technologies and
+products. Here is a list of those products with links to their licenses.
+
+* **hts_engine:** the HMM-based speech synthesis code in MaryTTS is based on
+ HTS, ported to Java by DFKI. The original HTS can be obtained from
+ http://hts-engine.sourceforge.net/ -- it is released under the New and
+ Simplified BSD License.
+* **JTok:** The JTok tokenizer from http://heartofgold.dfki.de is distributed
+ under the GNU Lesser General Public License, see http://www.gnu.org or
+ doc/licenses/LGPL.txt.
+* **jsresources.jar:** A few utility classes from http://www.jsresources.org are
+ distributed under the terms of the jsresources license, see
+ doc/licenses/jsresources-license.txt.
+* **log4j:** MaryTTS uses log4j (http://logging.apache.org/log4j) as a logging
+ mechanism. log4j is distributed under the Apache Software License, see
+ http://www.apache.org or doc/licenses/apache-software-license.txt
+* **JUnit:** For unit testing of the java source, MaryTTS uses JUnit
+ (http://junit.org). JUnit is licensed under the Common Public License, see
+ http://junit.org or doc/licenses/CPL.txt.
+* **java-diff:** A java diff implementation from
+ http://www.incava.org/projects/java-diff for input-output-comparisons in the
+ MaryTTS Expert Interface. java-diff is licensed under the GNU Lesser General
+ Public License, see http://www.gnu.org or doc/licenses/LGPL.txt.
+* **fast-md5:** A fast md5 checksum implementation from
+ http://www.twmacinta.com/myjava/fast_md5.php used for computing checksums
+ after downloading voices. fast-md5 is licensed under the GNU Lesser General
+ Public License, see http://www.gnu.org or doc/licenses/LGPL.txt.
+* **mwdumper:** A tool for extracting sets of pages from a MediaWiki dump
+ file. mwdumper is MIT-style like licensed, see
+ http://www.mediawiki.org/wiki/Mwdumper and for the license
+ http://en.wikipedia.org/wiki/MIT_License. (files concerned:
+ **mwdumper-2008-04-13.jar**)
+* **sgt:** The Scientific Graphics Toolkit (sgt) is provided by the
+ NOAA/PMEL/EPIC group (see http://www.epic.noaa.gov/java/sgt/) under the
+ BSD-style EPIC license, see doc/licenses/epic-license.txt.
+
+**IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR
+ TO USE OF THIS CONTENT.**
diff --git a/lib/marytts-5.2.1/README.md b/lib/marytts-5.2.1/README.md
new file mode 100644
index 0000000..aa08f4b
--- /dev/null
+++ b/lib/marytts-5.2.1/README.md
@@ -0,0 +1,124 @@
+[](https://travis-ci.org/marytts/marytts)
+
+# MaryTTS
+
+This is the source code repository for the multilingual open-source MARY text-to-speech platform (MaryTTS).
+MaryTTS is a client-server system written in pure Java, so it runs on many platforms.
+
+**For a downloadable package ready for use, see [the releases page](https://github.com/marytts/marytts/releases).**
+
+Older documentation can also be found at http://mary.dfki.de and https://mary.opendfki.de.
+
+This README is part of the the MaryTTS source code repository.
+It contains information about compiling and developing the MaryTTS sources.
+
+The code comes under the Lesser General Public License LGPL version 3 -- see LICENSE.md for details.
+
+
+## Using MaryTTS in your own Java projects
+
+### Adding the MaryTTS to your dependencies
+
+The easiest way to use MaryTTS in your own Java projects is to declare a dependency on a relevant MaryTTS artifact:
+
+- in the `pom.xml` for Maven:
+```xml
+
+
+ de.dfki.mary
+ voice-cmu-slt-hsmm
+ 5.2.1
+
+
+```
+- in the `build.gradle` for Gradle
+```groovy
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'de.dfki.mary:marytts:5.2.1'
+}
+```
+
+
+### Synthesizing speech
+
+Text to wav basic examples are proposed in this repository
+- Maven: https://github.com/marytts/marytts-txt2wav/tree/maven
+- Gradle: https://github.com/marytts/marytts-txt2wav/tree/gradle
+
+
+## Using MaryTTS for other programming languages
+
+If you want to use MaryTTS for other programming languages (like python for example), you need to achieve 3 steps
+
+1. compiling marytts
+2. starting the server
+3. query synthesis on the server
+
+
+### Compiling MaryTTS on the command line
+
+MaryTTS v5.x builds with Maven 3.0.x.
+If it is not installed on your system, see
+http://maven.apache.org/download.html or install it using your favorite package manager.
+
+Compiling the MARY system itself can be done using
+
+ mvn install
+
+in the top-level folder.
+
+This will compile the system, run all unit and integration tests, package the system to the extent possible, and install it in your local maven repository.
+
+
+### Running the freshly built MaryTTS server
+
+After a successful compile, you should find a ready-to-run unpacked installation of the MaryTTS server system in `target/marytts-`.
+Run the server as
+
+ target/marytts-/bin/marytts-server
+
+Then connect to it with your browser at http://localhost:59125 or using the `marytts-client` in the same folder.
+
+The runtime system is also available as deployable packages:
+
+ target/marytts-.zip
+
+Installation is easy:
+unpack anywhere, and run the scripts in the `bin/` folder.
+
+
+### Synthesize speech using the server
+
+Synthesizing speech, using the server, is pretty easy.
+You need to generate proper HTTP queries and deal with the associated HTTP responses.
+Examples are proposed :
+- python 3: https://github.com/marytts/marytts-txt2wav/tree/python
+- shell: https://github.com/marytts/marytts-txt2wav/tree/sh
+
+
+## Developing MaryTTS
+
+### Working on MaryTTS code
+
+The recommended workflow for making contributions to the MaryTTS source code is to follow the GitHub model:
+
+1. fork the MaryTTS repository into your own profile on GitHub, by navigating to https://github.com/marytts/marytts and clicking "fork" (of course you need a GitHub account);
+
+2. use the `git clone`, `commit`, and `push` commands to make modifications on your own marytts repository;
+ in this process, make sure to `git pull upstream master` regularly to stay in sync with latest developments on the master repo;
+
+3. when you think a reusable contribution is ready, open a "pull request" on GitHub to allow for easy merging into the master repository.
+
+Have a look at the [GitHub documentation](http://help.github.com/) for further details.
+
+
+### IDE configuration
+
+Wiki pages are available to help you to configure your IDE to develop MaryTTS.
+The following IDEs have been tested and documented:
+
+- Eclipse: https://github.com/marytts/marytts/wiki/Eclipse
diff --git a/lib/marytts-5.2.1/build.gradle b/lib/marytts-5.2.1/build.gradle
new file mode 100644
index 0000000..fe20671
--- /dev/null
+++ b/lib/marytts-5.2.1/build.gradle
@@ -0,0 +1,4 @@
+allprojects {
+ version '5.2.1'
+ buildDir 'target'
+}
diff --git a/lib/marytts-5.2.1/doc/ErrorHandling.odp b/lib/marytts-5.2.1/doc/ErrorHandling.odp
new file mode 100644
index 0000000..980c4d2
Binary files /dev/null and b/lib/marytts-5.2.1/doc/ErrorHandling.odp differ
diff --git a/lib/marytts-5.2.1/doc/ErrorHandling.pdf b/lib/marytts-5.2.1/doc/ErrorHandling.pdf
new file mode 100644
index 0000000..cbc55e3
Binary files /dev/null and b/lib/marytts-5.2.1/doc/ErrorHandling.pdf differ
diff --git a/lib/marytts-5.2.1/doc/FSTFormat.odt b/lib/marytts-5.2.1/doc/FSTFormat.odt
new file mode 100644
index 0000000..b83c39c
Binary files /dev/null and b/lib/marytts-5.2.1/doc/FSTFormat.odt differ
diff --git a/lib/marytts-5.2.1/doc/Getting_started_with_CARTAnalyzer.txt b/lib/marytts-5.2.1/doc/Getting_started_with_CARTAnalyzer.txt
new file mode 100644
index 0000000..8c97a6f
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/Getting_started_with_CARTAnalyzer.txt
@@ -0,0 +1,348 @@
+CARTAnalyzer - Getting Started
+------------------------------
+
+This document was written by Maximilian Kwapil
+during an internship at the DFKI language technology lab
+during spring 2007
+
+1.)What is a CART?
+
+A CART is the final part of the unit selection process where
+everything that has been done before by various algorithms
+comes together.
+
+It stands for
+Classification
+And
+Regression
+Tree
+
+For us, the TREE part is the most important one.
+
+2.) ... What?
+
+When you choose any unit selection voice for text input,
+the text is of course thoroughly analysed.
+Each single, smallest part/sound of the speech that is to be spoken
+(a unit) is then selected from the voice recordings
+(thus unit selection) by the CART.
+The CART itself contains all recorded units in its leaves.
+Above the leaves, there are many many decision nodes that
+classify (thus ClassificationTree) a given unit by
+several (phonetic) criteria like
+
+ - what phoneme does the unit represent
+ - is it a vowel or a consonant
+ - is it stressed or accented
+ - how many syllables does the current word contain
+ .
+So, when the text is actually synthesized, MARY knows for every
+unit how it should sound and goes through the CART of the voice,
+using the decision nodes to reach all the way down to the most
+fitting leaf.
+
+3.) What is a leaf? What does a leaf contain?
+
+A leaf contains several units that best fit the desired sound.
+For example a leaf could contain 10 units that should sound like
+an "a", unstressed, with 3 words until the end of the sentence
+(and the sentence is actually a question).
+
+The CARTBuilder makes sure that no leaf contains too many units,
+so usually there are about 50-70 units per leaf average.
+
+4.) So what, the concept of the CART and its usage seem flawless
+ and ideal for unit selection purposes !?
+
+It is, I'm afraid, not that easy.
+After all, nothing is perfect and nor are our algorithms and
+those that we use.
+
+In the audio timeline, the units could have been labelled wrong,
+(unit) durations could have been miscalculated.
+There are many possible causes for errors along the
+voice building way.
+
+One of the consequences of that is that some of the units
+that are stored in the leafs of the CART are in a place
+where they should not be.
+
+For example, we do not want an "a" unit in a leaf that is supposed
+to represent an "o", regardless of their other (phonetic) properties.
+We also would not want any kind of sound where there should be silence,
+etc etc.
+The differences may be really really small sometimes but in a homogenous
+(ideal) leaf, it still matters.
+
+5.) I suppose now that the CARTAnalyzer can help me with that?
+
+Well yes, that's what it was designed for.
+The CARTAnalyzer was programmed to go through the leafs of the tree of
+a unit selection voice and spot and erase those units that do not
+belong there (outliers).
+We hope that the sound of the voice will improve when MARY doesn't even
+have the chance to choose any outliers for the synthesization process.
+
+6.) How can the CARTAnalyzer help?
+
+At the moment, there are two things that can be used for
+detecting and erasing outliers:
+
+- Probability values (or float values):
+
+The FESTVOX Wagon format that we currently use for building our CARTs
+assigns a calculated float value to every single unit in each leaf of
+the tree.
+In the past we just dismissed those values but they seem vital to
+detecting outliers.
+We guess that the floats measure some kind of "acoustic similarity"
+or "acoustic distance".
+We use these in the CARTAnalyzer, since we assume that
+(acoustic) outliers would be the most distant ones to all the other units.
+Thus, those units with an interestingly high float/p-value should be
+cut immediately.
+
+- Energy level (new, under development):
+
+One of the main goals of this tool is finding sounds where there should
+not be any, particularly finding any kind of sound
+in a leaf that should represent silence.
+For this purpose, energy seems to be the best criterion for the units,
+since silence is the absence of energy/sound and the smallest "noise"
+would have significantly high energy levels compared to the
+absolute zero of silence.
+For that, we use our signal processing tools, particularly
+the EnergyAnalyser and the DatagramDoubleDataSource.
+
+7.) I am confused and I do not know how to use this tool. Help!
+
+No problem. That's why this wonderful "Getting started" guide was written.
+Let's go through these few simple steps together, shall we?
+
+Step 1:
+
+Make sure all mary files for the voice that you want to work on
+have already been created by the voice import tool.
+Also, since we want the float values for all units in the leaves,
+the cart.mry file must have been built by the new modified CARTBuilder.
+(When a search for "ExtendedClassificationTree" succeeds in your
+ CARTBuilder.java then that is the right version for our purposes.)
+
+Step 2:
+
+As soon as you have all your voice files ready, you can start the
+program in the main voice directory (i.e. ..../full_voice, ..../arctic_voice etc).
+Make sure to include the proper classpath and give it some memory to use.
+Here is a sample shell script that you can copy to and execute in your
+proper voice directory (replace $MARY_BASE with your openmary directory):
+
+ java -cp $MARY_BASE/java/mary-common.jar:$MARY_BASE/java/log4j-1.2.8.jar:$MARY_BASE/java/jsresources.jar:
+ $MARY_BASE/java/signalproc.jar
+ -ea -Xms40m -Xmx1024m $* de.dfki.lt.mary.gizmos.CARTAnalyzer
+
+Step 3:
+
+Immediately after execution, the program should output something like
+ CARTAnalyzer started.
+ Initializing...
+Depending on the size of the voice, several seconds will pass until
+ CART loaded from ....../xyz_voice/mary_files/cart.mry
+ [some statistical output as to how many leafs and units there are]
+ ca:cL:1 ?>
+
+If you can see all this and you are in the main command line (ca:cL:x ?>):
+Congratulations, the CARTAnalyzer has initialized perfectly.
+
+By default, as you can see, the CARTAnalyzer (ca) loads the cart.mry
+in the mary_files directory (the one usually created by CARTBuilder)
+automatically.
+Also, since we navigate through the leaves of the tree, the index number
+of the current leaf is also shown in every command line (cL:x).
+
+For the next step, you have three options:
+
+Option a)
+
+This is the easiest option of them all. Use it if you don't have the time
+or just want the whole job done by the program itself.
+It is as easy as that: Punch in the following and hit enter:
+
+ ca:cL:1 ?> analyze auto abc.log xyz.mry
+ OR
+ ca:cL:1 ?> a auto abc.log xyz.mry
+
+This command tells the program the following:
+- a[nalyze]: Let's analyze the whole tree...
+- auto: ... but I'll let you do all the work for me...
+- abc.log: ... when you're done, I'll be able to read and check everthing
+ that you did with the tree in the logfile abc.log...
+- xyz.mry: ... and the final CART will be stored in xyz.mry.
+
+After that, hit enter three times in a row, or, if you want to experiment,
+enter "no" for the specified units that you do NOT wish to cut.
+
+Note that of course you may use other names that abc.log and xyz.mry.
+Note also that both the logfile and the cart file are stored in the voice
+directory that you started the program in.
+Thus, if you want the CART to be stored directly in the mary_files directory,
+you may write something like:
+
+ a auto test.log mary_files/testcart.mry
+
+That's all there is to it.
+You won't even have to go get a cup of coffee because the algorithm
+usually takes less than a second to complete.
+(Which of course, if you want to change your copy of the CARTAnalyzer,
+allows for creating dozens and hundreds of different(ly) pruned CARTs...)
+
+PLEASE NOTE THAT WHEN BACK IN THE COMMAND LINE, YOU ARE STILL USING THE
+PRUNED CART (IT IS NOT RESET). BY EXITTING, THE CHANGES WILL NOT BE SAVED
+TO THE ORIGINAL CART, SO IF YOU WANT TO REDO SOMETHING OR HAVE THE ORIGINAL
+CART BACK, JUST a) RESTART THE PROGRAM or b) TYPE "load mary_files/cart.mry"!
+THIS APPLIES TO ALL OPTIONS!
+
+Option b)
+
+If you wish for some more control in the whole process and still do not want
+to touch the ca code, this is the right option for you.
+But be warned: This WILL take some time to get used to, so if you
+just want a quick job, go for option a) instead!
+That said, this option is really neat since you can listen to all the units
+in every leaf (the audio data), you can view every single leaf and have a list
+of the units that the leaf contains and their respective float value
+as described above.
+The command is this:
+
+ ca:cL:1 ?> analyze user abc.log xyz.mry
+ OR
+ ca:cL:1 ?> a user abc.log xyz.mry
+
+This command tells the program the following:
+- a[nalyze]: Let's analyze the whole tree...
+- user: ... and let me be the one to control everything and decide which units
+ should be cut from which leaves ...
+- abc.log: ... when you're done, I'll be able to read and check everthing
+ that I did with the tree in the logfile abc.log...
+- xyz.mry: ... and the final CART will be stored in xyz.mry.
+
+Please note that this mode can take a very, VERY long time depending on the
+size of the voice.
+
+After you hit enter, you will be taken to a second command line which looks
+like this:
+
+ ca:aa:cL:1 ?>
+
+You will also be shown a lot of information, including the main commands you can use
+for viewing the leafs, listening to them and cutting the units.
+Also, the decision path will be shown for each leaf.
+(The decision path tells you the path that MARY would go in this tree for this
+ particular leaf/sound as described at the beginning of this document, it looks
+ something like this: mary_phoneme==A - mary_stressed==1 - mary_xyz==x)
+
+Note that you can resume your work in this mode and therefore it's not really
+necessary to give a cart file when you run this mode for the first time.
+When you type exit in this mode, your current progress will be saved and you
+can resume from there later on or even weeks later by typing
+
+ ca:cL:1 ?> a resume
+
+or by typing "yes" when you repeat the a user abc xyz command.
+
+I used to think that this mode is close to self-explaining but I will now try to
+explain the main point of it to you:
+
+
+IMPORTANT NOTE: Help files
+In the main(!) command line you can type
+ ca:cL:x ?> help [about/command]
+Without parameters, the help file will show you all available commands for the main
+command line, help about will display a short about text and help command goes into
+details for the command that you want help for.
+
+Option c) (not recommended)
+
+This is the option that you probably do not want to use, ever.
+You can, theoretically, do all the work in the main command line.
+As already mentioned, I do not recommend this mode, but it does have
+some nice features like text dumping of the cart, saving it to either
+.mry or in CA format, or have an in-depth statistic about
+the leaves and their units (particularly their float values)
+logged to a file.
+
+If you really want this (or you just want some diagnosis data), type
+"help" in the command line and look what's right for you.
+
+The last step:
+
+If you haven't already had the new CART dumped in something like xyz.mry,
+you can now do by typing "dump xyz.mry", if you want to work on it again
+some time later, type "save xyz" (you can use "load xyz" to load it after that).
+
+So when all is done and the CART has been successfully pruned, you just may
+want to try it out by (for example) renaming the original cart to something
+like cart.mry.bak and your new one to cart.mry in the mary_files directory.
+
+Congratulations!
+That's it.
+If you experience trouble, read the following ultra-short troubleshooting guide or
+contact me at yukido@web.de (also feel free to contact me if you want to further understand
+the code and/or change/improve it, I will be happy to help as much as I can)
+
+TROUBLESHOOTING:
+
+1) The automatic mode didn't cut any units / All units in every leaf have a float value of 0.0
+
+ You are probably using a non-float/old/MARY version of the cart. Try rebuilding the CART of the
+ voice with the new and improved CARTBuilder (search for ExtendedClassificationTree, see above).
+ Note that this program can load both versions of a CART and you can still f.e. print the statistics
+ for the MARY cart or textdump it.
+
+2) When I want to listen to a leaf, the program throws some strange Exception
+
+ For audio playback we are currently using the ClipPlayer by jsresources.org (java sound resources).
+ Sadly, it does have its limits and if there are too many units in the leaf (some hundreds)
+ it just will not play them back.
+ Try playing back the outliers only (see help file) or implement some other method to play back
+ the audio by yourself ;)
+ Also, sometimes, it says something about "could not find a line" which I don't really know about.
+ In that case, check your system's sound configuration and the usual other audio programs stuff.
+
+3) Help! There's a "test.wav" in my voice directory (that I do not want there)!
+
+ I CAN EXPLAIN...!
+ Everytime that you listen to the units of a leaf or just any audio that you can listen to
+ with the CARTAnalyzer, temporary wav data is stored in the test.wav.
+ That's what it is.
+ You can delete it. Nothing bad will happen. I promise.
+
+4) I am still confused by all this.
+
+ Don't panic. Read this and the help files over and over, play with the program
+ (as long as you don't overwrite the mary_files/cart.mry everything should be just fine),
+ read the log files, read the code (it is not that much after all).
+ You'll get used to the program relatively fast with the learning-by-doing method
+ I guess.
+
+5) You suck.
+
+ a) I know.
+ b) Get over it.
+ c) yukido@web.de
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/marytts-5.2.1/doc/HnmTimelineFileFormat.odt b/lib/marytts-5.2.1/doc/HnmTimelineFileFormat.odt
new file mode 100644
index 0000000..ee52f34
Binary files /dev/null and b/lib/marytts-5.2.1/doc/HnmTimelineFileFormat.odt differ
diff --git a/lib/marytts-5.2.1/doc/MachineLearningClasses.odt b/lib/marytts-5.2.1/doc/MachineLearningClasses.odt
new file mode 100644
index 0000000..970eea4
Binary files /dev/null and b/lib/marytts-5.2.1/doc/MachineLearningClasses.odt differ
diff --git a/lib/marytts-5.2.1/doc/MaryReferences.odt b/lib/marytts-5.2.1/doc/MaryReferences.odt
new file mode 100644
index 0000000..945fd5f
Binary files /dev/null and b/lib/marytts-5.2.1/doc/MaryReferences.odt differ
diff --git a/lib/marytts-5.2.1/doc/Model-Permission-Speaker.odt b/lib/marytts-5.2.1/doc/Model-Permission-Speaker.odt
new file mode 100644
index 0000000..f2e522f
Binary files /dev/null and b/lib/marytts-5.2.1/doc/Model-Permission-Speaker.odt differ
diff --git a/lib/marytts-5.2.1/doc/NewLanguageWorkflow.odg b/lib/marytts-5.2.1/doc/NewLanguageWorkflow.odg
new file mode 100644
index 0000000..1195e69
Binary files /dev/null and b/lib/marytts-5.2.1/doc/NewLanguageWorkflow.odg differ
diff --git a/lib/marytts-5.2.1/doc/NewLanguageWorkflow.png b/lib/marytts-5.2.1/doc/NewLanguageWorkflow.png
new file mode 100644
index 0000000..f000306
Binary files /dev/null and b/lib/marytts-5.2.1/doc/NewLanguageWorkflow.png differ
diff --git a/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.odg b/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.odg
new file mode 100644
index 0000000..39dbb35
Binary files /dev/null and b/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.odg differ
diff --git a/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.png b/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.png
new file mode 100644
index 0000000..78a0d31
Binary files /dev/null and b/lib/marytts-5.2.1/doc/SinusoidalHnmFlowchart.png differ
diff --git a/lib/marytts-5.2.1/doc/UnitDatabaseFormat.odt b/lib/marytts-5.2.1/doc/UnitDatabaseFormat.odt
new file mode 100644
index 0000000..0b5a5a2
Binary files /dev/null and b/lib/marytts-5.2.1/doc/UnitDatabaseFormat.odt differ
diff --git a/lib/marytts-5.2.1/doc/UnitSelectionAPI.odt b/lib/marytts-5.2.1/doc/UnitSelectionAPI.odt
new file mode 100644
index 0000000..3df363b
Binary files /dev/null and b/lib/marytts-5.2.1/doc/UnitSelectionAPI.odt differ
diff --git a/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.odg b/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.odg
new file mode 100644
index 0000000..dabd65b
Binary files /dev/null and b/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.odg differ
diff --git a/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.png b/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.png
new file mode 100644
index 0000000..b084d7f
Binary files /dev/null and b/lib/marytts-5.2.1/doc/VoiceConversionFlowchart.png differ
diff --git a/lib/marytts-5.2.1/doc/examples/client/MaryClient.py b/lib/marytts-5.2.1/doc/examples/client/MaryClient.py
new file mode 100644
index 0000000..4656987
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/MaryClient.py
@@ -0,0 +1,367 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import socket, sys, types, getopt
+
+
+languageNames = {'de':'German',
+ 'en':'English',
+ 'en_US':'US English',
+ 'tib':'Tibetan'}
+
+class MaryClient:
+ specificationVersion = "0.1"
+
+ """Python implementation of a MARY TTS client"""
+ def __init__( self, host="cling.dfki.uni-sb.de", port=59125, profile=False, quiet=False ):
+ self.host = host
+ self.port = port
+ self.profile = profile
+ self.quiet = quiet
+ self.allVoices = None # array of Voice objects
+ self.voicesByLocaleMap = {} # Map locale strings to arrays of Voice objects
+ self.allDataTypes = None # array of DataType objects
+ self.inputDataTypes = None # array of DataType objects
+ self.outputDataTypes = None # array of DataType objects
+ self.serverExampleTexts = {}
+ self.voiceExampleTexts = {}
+ self.serverVersionInfo = u''
+
+ if not self.quiet:
+ sys.stderr.write( "MARY TTS Python Client %s\n" % ( self.specificationVersion ) )
+ try:
+ info = self.getServerVersionInfo()
+ except:
+ sys.stderr.write( "Problem connecting to mary server at %s:%i\n" % ( self.host, self.port ) )
+ raise
+ sys.stderr.write( "Connected to %s:%i, " % ( self.host, self.port ) )
+ sys.stderr.write( info )
+ sys.stderr.write( '\n' )
+
+ def __getServerInfo( self, request="", marySocket=None ):
+ """Get answer to request from mary server. Returns a list of unicode strings,
+ each representing a line without the line break.
+ """
+ closeSocket = False
+ if marySocket is None:
+ closeSocket = True
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ assert isinstance(marySocket, socket.SocketType)
+ maryFile = marySocket.makefile( 'rwb', 1 ) # read-write, line-buffered
+ maryFile.write( unicode( request+"\n" ).encode( 'utf-8' ) )
+ result = []
+ while True:
+ got = unicode( maryFile.readline().strip(), 'utf-8' )
+ # read until end of file or an empty line is read:
+ if not got: break
+ result.append(got)
+ if closeSocket:
+ marySocket.close()
+ return result
+
+ def getServerVersionInfo( self ):
+ "Get version info from server. Returns a unicode string"
+ if self.serverVersionInfo == u'':
+ # need to get it from server
+ self.serverVersionInfo = u'\n'.join(self.__getServerInfo("MARY VERSION"))
+ return self.serverVersionInfo
+
+ def getAllDataTypes(self, locale=None):
+ """Obtain a list of all data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of DataType objects
+ """
+ if self.allDataTypes is None:
+ self.__fillDataTypes()
+ assert self.allDataTypes is not None and len( self.allDataTypes ) > 0
+ if locale is None:
+ return self.allDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.allDataTypes if d.locale is None or d.locale == locale]
+
+ def getInputDataTypes(self,locale=None):
+ """Obtain a list of input data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an arry of DataType objects
+ """
+ if self.inputDataTypes is None:
+ self.__fillDataTypes()
+ assert self.inputDataTypes is not None and len( self.inputDataTypes ) > 0
+ if locale is None:
+ return self.inputDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.inputDataTypes if d.locale is None or d.locale == locale]
+
+ def getOutputDataTypes(self, locale=None):
+ """Obtain a list of output data types known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an arry of DataType objects
+ """
+ if self.outputDataTypes is None:
+ self.__fillDataTypes()
+ assert self.outputDataTypes is not None and len( self.outputDataTypes ) > 0
+ if locale is None:
+ return self.outputDataTypes
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ return [d for d in self.outputDataTypes if d.locale is None or d.locale == locale]
+
+
+ def __fillDataTypes( self ):
+ self.allDataTypes = []
+ self.inputDataTypes = []
+ self.outputDataTypes = []
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ # Expect a variable number of lines of the kind
+ # RAWMARYXML INPUT OUTPUT
+ # TEXT_DE LOCALE=de INPUT
+ # AUDIO OUTPUT
+ typeStrings = self.__getServerInfo( "MARY LIST DATATYPES", marySocket )
+ if not typeStrings or len(typeStrings) == 0:
+ raise IOError( "Could not get list of data types from Mary server" )
+ marySocket.close()
+ for typeString in typeStrings:
+ parts = typeString.split()
+ if len( parts ) == 0:
+ continue
+ name = parts[0]
+ isInputType = False
+ isOutputType = False
+ locale = None
+ for part in parts[1:]:
+ if part[:7] == "LOCALE=":
+ locale = part[7:]
+ elif part == "INPUT":
+ isInputType = True
+ elif part == "OUTPUT":
+ isOutputType = True
+ dt = DataType( name, locale, isInputType, isOutputType )
+ self.allDataTypes.append( dt )
+ if dt.isInputType:
+ self.inputDataTypes.append( dt )
+ if dt.isOutputType:
+ self.outputDataTypes.append( dt )
+
+ def getVoices( self, locale=None ):
+ """Obtain a list of voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ if self.allVoices is None:
+ self.__fillVoices()
+ assert self.allVoices is not None and len( self.allVoices ) > 0
+ if locale is None:
+ return self.allVoices
+ else:
+ assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
+ if self.voicesByLocaleMap.has_key(locale):
+ return self.voicesByLocaleMap[locale]
+ else:
+ raise Exception("No voices for locale '%s'" % (locale))
+
+ def __fillVoices( self ):
+ self.allVoices = []
+ self.voicesByLocaleMap = {}
+ marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ marySocket.connect( ( self.host, self.port ) )
+ # Expect a variable number of lines of the kind
+ # de7 de female
+ # us2 en male
+ # dfki-stadium-emo de male limited
+ voiceStrings = self.__getServerInfo( "MARY LIST VOICES", marySocket )
+ if not voiceStrings or len(voiceStrings) == 0:
+ raise IOError( "Could not get list of voices from Mary server" )
+ marySocket.close()
+ for voiceString in voiceStrings:
+ parts = voiceString.split()
+ if len( parts ) < 3:
+ continue
+ name = parts[0]
+ locale = parts[1]
+ gender = parts[2]
+ domain = None
+ if len( parts ) > 3:
+ domain = parts[3]
+ voice = Voice( name, locale, gender, domain )
+ self.allVoices.append( voice )
+ localeVoices = None
+ if self.voicesByLocaleMap.has_key( locale ):
+ localeVoices = self.voicesByLocaleMap[locale]
+ else:
+ localeVoices = []
+ self.voicesByLocaleMap[locale] = localeVoices
+ localeVoices.append( voice )
+
+ def getGeneralDomainVoices( self, locale=None ):
+ """Obtain a list of general domain voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ return [v for v in self.getVoices( locale ) if not v.isLimitedDomain]
+
+ def getLimitedDomainVoices( self, locale=None ):
+ """Obtain a list of limited domain voices known to the server. If the information is not
+ yet available, the server is queried. This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities.
+ Returns an array of Voice objects
+ """
+ return [v for v in self.getVoices( locale ) if v.isLimitedDomain]
+
+ def getAvailableLanguages(self):
+ """ Check available voices and return a list of tuples (abbrev, name)
+ representing the available languages -- e.g. [('en', 'English'),('de', 'German')].
+ """
+ if self.allVoices is None:
+ self.__fillVoices()
+ assert self.allVoices is not None and len( self.allVoices ) > 0
+ languages = []
+ for l in self.voicesByLocaleMap.keys():
+ if languageNames.has_key(l):
+ languages.append((l,languageNames[l]))
+ else:
+ languages.append((l, l))
+ return languages
+
+ def getServerExampleText( self, dataType ):
+ """Request an example text for a given data type from the server.
+ dataType the string representation of the data type,
+ e.g. "RAWMARYXML". This is optional information
+ which is not required for the normal operation of the client, but
+ may help to avoid incompatibilities."""
+ if not self.serverExampleTexts.has_key( dataType ):
+ exampleTexts = self.__getServerInfo( "MARY EXAMPLETEXT %s" % ( dataType ) )
+ if not exampleTexts or len(exampleTexts) == 0:
+ raise IOError( "Could not get example text for type '%s' from Mary server" % (dataType))
+ exampleText = u'\n'.join(exampleTexts)
+ self.serverExampleTexts[dataType] = exampleText
+ return self.serverExampleTexts[dataType]
+
+ def process( self, input, inputType, outputType, audioType=None, defaultVoiceName=None, output=sys.stdout ):
+ assert type( input ) in types.StringTypes
+ assert type( inputType ) in types.StringTypes
+ assert type( outputType ) in types.StringTypes
+ assert audioType is None or type( audioType ) in types.StringTypes
+ assert defaultVoiceName is None or type( defaultVoiceName ) in types.StringTypes
+ assert callable( getattr( output, 'write' ) )
+ if type( input ) != types.UnicodeType:
+ input = unicode( input, 'utf-8' )
+ maryInfoSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ maryInfoSocket.connect( ( self.host, self.port ) )
+ assert type( maryInfoSocket ) is socket.SocketType
+ maryInfo = maryInfoSocket.makefile( 'rwb', 1 ) # read-write, line-buffered
+ maryInfo.write( unicode( "MARY IN=%s OUT=%s" % ( inputType, outputType ), 'utf-8' ) )
+ if audioType:
+ maryInfo.write( unicode( " AUDIO=%s" % ( audioType ), 'utf-8' ) )
+ if defaultVoiceName:
+ maryInfo.write( unicode( " VOICE=%s" % ( defaultVoiceName ), 'utf-8' ) )
+ maryInfo.write( "\r\n" )
+ # Receive a request ID:
+ id = maryInfo.readline()
+ maryDataSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ maryDataSocket.connect( ( self.host, self.port ) )
+ assert type( maryDataSocket ) is socket.SocketType
+ maryDataSocket.sendall( id ) # includes newline
+ maryDataSocket.sendall( input.encode( 'utf-8' ) )
+ maryDataSocket.shutdown( 1 ) # shutdown writing
+ # Set mary info socket to non-blocking, so we only read somthing
+ # if there is something to read:
+ maryInfoSocket.setblocking( 0 )
+ while True:
+ try:
+ err = maryInfoSocket.recv( 8192 )
+ if err: sys.stderr.write( err )
+ except:
+ pass
+ got = maryDataSocket.recv( 8192 )
+ if not got: break
+ output.write( got )
+ maryInfoSocket.setblocking( 1 )
+ while True:
+ err = maryInfoSocket.recv( 8192 )
+ if not err: break
+ sys.stderr.write( err )
+
+
+
+################ data representation classes ##################
+
+class DataType:
+ def __init__( self, name, locale=None, isInputType=False, isOutputType=False ):
+ self.name = name
+ self.locale = locale
+ self.isInputType = isInputType
+ self.isOutputType = isOutputType
+
+ def isTextType( self ):
+ return self.name != "AUDIO"
+
+class Voice:
+
+ def __init__( self, name, locale, gender, domain="general" ):
+ self.name = name
+ self.locale = locale
+ self.gender = gender
+ self.domain = domain
+ if not domain or domain == "general":
+ self.isLimitedDomain = False
+ else:
+ self.isLimitedDomain = True
+
+ def __str__(self):
+ if languageNames.has_key(self.locale):
+ langName = languageNames[self.locale]
+ else:
+ langName = self.locale
+ if self.isLimitedDomain:
+ return "%s (%s, %s %s)" % (self.name, self.domain, langName, self.gender)
+ else:
+ return "%s (%s %s)" % (self.name, langName, self.gender)
+
+##################### Main #########################
+
+if __name__ == '__main__':
+
+ serverHost = "cling.dfki.uni-sb.de"
+ serverPort = 59125
+ inputType = "TEXT"
+ outputType = "AUDIO"
+ audioType = "WAVE"
+ defaultVoice = None
+ inputEncoding = 'utf-8'
+ ( options, rest ) = getopt.getopt( sys.argv[1:], '', \
+ ['server.host=', 'server.port=', 'input.type=', 'output.type=', \
+ 'audio.type=', 'voice.default=', 'input.encoding='] )
+ for ( option, value ) in options:
+ if option == '--server.host': serverHost = value
+ elif option == '--server.port': serverPort = int( value )
+ elif option == '--input.type': inputType = value
+ elif option == '--output.type': outputType = value
+ elif option == '--audio.type': audioType = value
+ elif option == '--voice.default': defaultVoice = value
+ elif option == '--input.encoding': inputEncoding = value
+ if len( rest )>0: # have input file
+ inputFile = file( rest[0] )
+ else:
+ inputFile = sys.stdin
+ input = unicode( ''.join( inputFile.readlines() ), inputEncoding )
+ if len( rest )>1: # also have output file
+ outputFile = file( rest[1] )
+ else:
+ outputFile = sys.stdout
+
+ maryClient = MaryClient( serverHost, serverPort )
+ maryClient.process( input, inputType, outputType, audioType, defaultVoice, outputFile )
diff --git a/lib/marytts-5.2.1/doc/examples/client/c++/Makefile b/lib/marytts-5.2.1/doc/examples/client/c++/Makefile
new file mode 100644
index 0000000..e12c862
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/c++/Makefile
@@ -0,0 +1,44 @@
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+
+CC=g++
+CFLAGS=-Wall -w -O3 -g
+ICUDIR=/usr/local/icu
+ICULIBS=-Wl,-R,$(ICUDIR)/lib -L$(ICUDIR)/lib -licuuc -licui18n -ldl
+
+all: MaryDemo
+
+MaryDemo: MaryClient.o MaryDemo.o
+ $(CC) $(CFLAGS) $^ -o MaryDemo $(LIBS)
+
+%.o: %.cc
+ $(CC) $(CFLAGS) $(RFLAGS) -o $@ -c $<
+
+clean:
+ rm -rf *.o ./MaryDemo
diff --git a/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc b/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc
new file mode 100644
index 0000000..7b11a5c
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc
@@ -0,0 +1,253 @@
+/**
+ * Copyright 2000-2006 DFKI GmbH.
+ * All Rights Reserved. Use is subject to license terms.
+ *
+ * Permission is hereby granted, free of charge, to use and distribute
+ * this software and its documentation without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of this work, and to
+ * permit persons to whom this work is furnished to do so, subject to
+ * the following conditions:
+ *
+ * 1. The code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Any modifications must be clearly marked as such.
+ * 3. Original authors' names are not deleted.
+ * 4. The authors' names are not used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+ * CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * A C++ implementation of a simple client to the MARY TTS system.
+ * result: an empty string serving as the container for the output.
+ * It will return text or audio data; text data will be encoded as UTF-8.
+ * inputText: the UTF-8 encoded text (or XML document) to send as a request
+ * maryInFormat: the input type of the data in inputText, e.g. TEXT
+ * maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
+ * locale: the language of the input, e.g. EN-US, DE
+ * audioType: for AUDIO output, the type of audio data to produce,
+ * e.g. WAVE or MP3.
+ * voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
+ * effects: the list of effects to be generated.
+ * return value: 0 on success, negative on failure.
+ */
+int
+MaryClient::maryQuery( int server_port,
+ string server_host,
+ string& result,
+ string inputText,
+ string maryInFormat,
+ string maryOutFormat,
+ string locale,
+ string audioType,
+ string voice,
+ string effects ) {
+
+ // prepare the request
+ string query = "MARY";
+ query += " IN=" + maryInFormat;
+ query += " OUT=" + maryOutFormat;
+ query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
+ query += " AUDIO=" + audioType;
+ query += " VOICE=" + voice;
+ if (effects != "") {
+ query += " EFFECTS=" + effects;
+ }
+ query += "\012\015";
+
+ //cout << "Constructed query: " << query << endl;
+
+ // declare connection stuff
+ struct sockaddr_in maryServer;
+ struct sockaddr_in maryClient;
+ struct hostent* hostInfo;
+
+ // declare variables
+ int maryInfoSocket;
+ int maryDataSocket;
+
+ // set configuration parameters
+
+ // get host information
+ hostInfo = gethostbyname (server_host.c_str());
+
+ if (hostInfo == NULL)
+ {
+ return -2;
+ }
+
+
+ // create a tcp connection to the mary server
+ maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryInfoSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+ // send request to the Mary server
+ if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // receive the request id
+ char id [32] = "";
+ if (recv (maryInfoSocket, id, 32, 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Read id: " << id << endl;
+
+ // create a tcp connection to the mary server
+ maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryDataSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+
+ // send the request id to the Mary server
+ if (send (maryDataSocket, id, strlen (id), 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Sending request: " << inputText << endl;
+
+ // send the query to the Mary server
+ if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+ if (send (maryDataSocket, "\012\015", 2, 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // shutdown data socket
+ shutdown (maryDataSocket, 1);
+
+
+ //cout << "Reading result" << endl;
+
+ int recv_bytes = 0;
+ char data [1024];
+
+ result.clear();
+
+ // receive the request result
+ do
+ {
+ recv_bytes = recv (maryDataSocket, data, sizeof(data), 0);
+
+ if (recv_bytes == -1)
+ {
+ return -2;
+ }
+ else if (recv_bytes > 0)
+ {
+ result.append(data, recv_bytes);
+ }
+ } while (recv_bytes != 0);
+
+ // receive the request error
+ do
+ {
+ data [0] = '\0';
+
+ recv_bytes = recv (maryInfoSocket, data, 1024, 0);
+
+ if (recv_bytes == -1)
+ {
+ return -2;
+ }
+ else if (recv_bytes > 0)
+ {
+ cerr << endl << "Mary error code: " << data << endl;
+ return -3;
+ }
+ } while (recv_bytes != 0);
+
+ // close all open sockets
+ close (maryInfoSocket);
+ close (maryDataSocket);
+
+ return 0;
+}
diff --git a/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc.win b/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc.win
new file mode 100644
index 0000000..66977c6
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/c++/MaryClient.cc.win
@@ -0,0 +1,290 @@
+/**
+ * Copyright 2000-2006 DFKI GmbH.
+ * All Rights Reserved. Use is subject to license terms.
+ *
+ * Permission is hereby granted, free of charge, to use and distribute
+ * this software and its documentation without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of this work, and to
+ * permit persons to whom this work is furnished to do so, subject to
+ * the following conditions:
+ *
+ * 1. The code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Any modifications must be clearly marked as such.
+ * 3. Original authors' names are not deleted.
+ * 4. The authors' names are not used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+ * CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#ifdef _WIN32
+// use compiler option -L//libwsock32.a
+#include
+#else
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * A C++ implementation of a simple client to the MARY TTS system.
+ * result: an empty string serving as the container for the output.
+ * It will return text or audio data; text data will be encoded as UTF-8.
+ * inputText: the UTF-8 encoded text (or XML document) to send as a request
+ * maryInFormat: the input type of the data in inputText, e.g. TEXT
+ * maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
+ * locale: the language of the input, e.g. EN-US, DE
+ * audioType: for AUDIO output, the type of audio data to produce,
+ * e.g. WAVE or MP3.
+ * voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
+ * effects: the list of effects to be generated.
+ * return value: 0 on success, negative on failure.
+ */
+int
+MaryClient::maryQuery( int server_port,
+ string server_host,
+ string& result,
+ string inputText,
+ string maryInFormat,
+ string maryOutFormat,
+ string locale,
+ string audioType,
+ string voice,
+ string effects ) {
+
+ // prepare the request
+ string query = "MARY";
+ query += " IN=" + maryInFormat;
+ query += " OUT=" + maryOutFormat;
+ query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
+ query += " AUDIO=" + audioType;
+ query += " VOICE=" + voice;
+ if (effects != "") {
+ query += " EFFECTS=" + effects;
+ }
+ query += "\012\015";
+
+ //cout << "Constructed query: " << query << endl;
+
+ // declare connection stuff
+ struct sockaddr_in maryServer;
+ struct sockaddr_in maryClient;
+ struct hostent* hostInfo;
+
+ // declare variables
+ int maryInfoSocket;
+ int maryDataSocket;
+
+ // set configuration parameters
+
+ // get host information
+ hostInfo = gethostbyname (server_host.c_str());
+
+ if (hostInfo == NULL)
+ {
+ return -2;
+ }
+
+
+ // create a tcp connection to the mary server
+ maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryInfoSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+ // send request to the Mary server
+ if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // receive the request id
+ char id [32] = "";
+
+ if (recv (maryInfoSocket, id, 32, 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Read id: " << id << endl;
+
+ // create a tcp connection to the mary server
+ maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
+
+ // verify that the socket could be opened successfully
+ if (maryDataSocket == -1)
+ {
+ return -2;
+ }
+ else
+ // autoflush stdout, bind and connect
+ {
+ maryClient.sin_family = AF_INET;
+ maryClient.sin_port = htons (0);
+ maryClient.sin_addr.s_addr = INADDR_ANY;
+
+ int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+
+ maryServer.sin_family = AF_INET;
+ maryServer.sin_port = htons (server_port);
+ memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
+
+ status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
+
+ if (status != 0)
+ {
+ return -2;
+ }
+ }
+
+
+ // send the request id to the Mary server
+ if (send (maryDataSocket, id, strlen (id), 0) == -1)
+ {
+ return -2;
+ }
+
+ //cout << "Sending request: " << inputText << endl;
+
+ // send the query to the Mary server
+ if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
+ {
+ return -2;
+ }
+
+ if (send (maryDataSocket, "\012\015", 2, 0) == -1)
+ {
+ return -2;
+ }
+
+
+ // shutdown data socket
+ shutdown (maryDataSocket, 1);
+
+
+ //cout << "Reading result" << endl;
+
+ unsigned int total_bytes = 0;
+ int recv_bytes = 0;
+ char data [1024] = "";
+
+ result [0] = '\0';
+
+ // receive the request result
+ do
+ {
+ data [0] = '\0';
+
+ recv_bytes = recv (maryDataSocket, data, 1024, 0);
+
+ if (recv_bytes == -1)
+ {
+ return -2;
+ }
+ else if (recv_bytes > 0)
+ {
+ //cout << "("<
+#include
+#include
+
+#include "MaryClient.h"
+
+using namespace std;
+
+/**
+ * Demonstration code for using the MaryClient.
+ + Call this as:
+ * ./MaryDemo
+ * or
+ * ./MaryDemo > output.wav
+ */
+int main() {
+ int server_port = 59125;
+ string server_host = "localhost";
+ string inputText = "Welcome to the world of speech synthesis!";
+ string maryInFormat = "TEXT";
+ string maryOutFormat = "AUDIO";
+ //string maryOutFormat = "REALISED_DURATIONS";
+ string locale = "en-US";
+ string audioType = "WAV_FILE";
+ string voice = "cmu-slt-hsmm";
+ string effects;
+// effects += "Volume(amount:5.0;)+";
+// effects += "TractScaler(amount:1.5;)+";
+// effects += "F0Scale(f0Scale:2.0;)+";
+// effects += "F0Add(f0Add:50.0;)+";
+// effects += "Rate(durScale:1.5;)+";
+// effects += "Robot(amount:100.0;)+";
+// effects += "Whisper(amount:100.0;)+";
+// effects += "Stadium(amount:100.0)+";
+// effects += "Chorus(delay1:466;amp1:0.54;delay2:600;amp2:-0.10;delay3:250;amp3:0.30)+";
+// effects += "FIRFilter(type:3;fc1:500.0;fc2:2000.0)+";
+// effects += "JetPilot";
+ string result;
+
+ MaryClient maryClient;
+ maryClient.maryQuery( server_port, server_host, result, inputText, maryInFormat, maryOutFormat, locale, audioType, voice, effects);
+
+ if (maryOutFormat == "AUDIO") {
+ // write result into a file
+ const char *filename = "output.wav";
+ ofstream file( filename );
+ file << result;
+
+ // play output
+ //system("play output.wav");
+ } else {
+ cout << "RESULT: " << endl << result << endl;
+ }
+
+ return 0;
+}
+
diff --git a/lib/marytts-5.2.1/doc/examples/client/c++/README.txt b/lib/marytts-5.2.1/doc/examples/client/c++/README.txt
new file mode 100644
index 0000000..d860b70
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/c++/README.txt
@@ -0,0 +1,4 @@
+Start MARY as a socket server:
+
+maryserver -Dserver=socket
+(or change entry 'server' in conf/marybase.config)
diff --git a/lib/marytts-5.2.1/doc/examples/client/maryclient-http.py b/lib/marytts-5.2.1/doc/examples/client/maryclient-http.py
new file mode 100644
index 0000000..cf9782e
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/maryclient-http.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+import httplib, urllib
+
+# A basic mary client in Python,
+# kindly donated to the MARY TTS project
+# by Hugh Sasse. Thanks Hugh!
+
+# A very basic Python class for accessing
+# the MARY TTS system using the modern
+# HTTP server.
+# Warning, this is probably ghastly Python,
+# most of my time of late has been with
+# other languages, so I'm not up to date
+# with all the stylistic conventions of
+# modern Python.
+# This does seem to work OK though.
+
+class maryclient:
+ """A basic handler for MARY-TTS HTTP clients
+
+ At present, there is no checking for
+ allowed voices, locales, and so on.
+ Most of the useful parameters can be
+ accessed by get_ and set_ methods.
+ Relying on winsound, this is Windows
+ specific.
+ """
+ def __init__(self):
+ """Set up useful defaults (for
+ people in England, anyway)"""
+ self.host = "127.0.0.1"
+ self.port = 59125
+ self.input_type = "TEXT"
+ self.output_type = "AUDIO"
+ self.audio = "WAVE_FILE"
+ self.locale = "en_GB"
+ self.voice = "dfki-prudence-hsmm"
+
+ def set_host(self, a_host):
+ """Set the host for the TTS server."""
+ self.host = a_host
+
+ def get_host(self):
+ """Get the host for the TTS server."""
+ self.host
+
+ def set_port(self, a_port):
+ """Set the port for the TTS server."""
+ self.port = a_port
+
+ def get_port(self):
+ """Get the port for the TTS server."""
+ self.port
+
+ def set_input_type(self, type):
+ """Set the type of input being
+ supplied to the TTS server
+ (such as 'TEXT')."""
+ self.input_type = type
+
+ def get_input_type(self):
+ """Get the type of input being
+ supplied to the TTS server
+ (such as 'TEXT')."""
+ self.input_type
+
+ def set_output_type(self, type):
+ """Set the type of input being
+ supplied to the TTS server
+ (such as 'AUDIO')."""
+ self.output_type = type
+
+ def get_output_type(self):
+ """Get the type of input being
+ supplied to the TTS server
+ (such as "AUDIO")."""
+ self.output_type
+
+ def set_locale(self, a_locale):
+ """Set the locale
+ (such as "en_GB")."""
+ self.locale = a_locale
+
+ def get_locale(self):
+ """Get the locale
+ (such as "en_GB")."""
+ self.locale
+
+ def set_audio(self, audio_type):
+ """Set the audio type for playback
+ (such as "WAVE_FILE")."""
+ self.audio = audio_type
+
+ def get_audio(self):
+ """Get the audio type for playback
+ (such as "WAVE_FILE")."""
+ self.audio
+
+ def set_voice(self, a_voice):
+ """Set the voice to speak with
+ (such as "dfki-prudence-hsmm")."""
+ self.voice = a_voice
+
+ def get_voice(self):
+ """Get the voice to speak with
+ (such as "dfki-prudence-hsmm")."""
+ self.voice
+
+ def generate(self, message):
+ """Given a message in message,
+ return a response in the appropriate
+ format."""
+ raw_params = {"INPUT_TEXT": message,
+ "INPUT_TYPE": self.input_type,
+ "OUTPUT_TYPE": self.output_type,
+ "LOCALE": self.locale,
+ "AUDIO": self.audio,
+ "VOICE": self.voice,
+ }
+ params = urllib.urlencode(raw_params)
+ headers = {}
+
+ # Open connection to self.host, self.port.
+ conn = httplib.HTTPConnection(self.host, self.port)
+
+ # conn.set_debuglevel(5)
+
+ conn.request("POST", "/process", params, headers)
+ response = conn.getresponse()
+ if response.status != 200:
+ print response.getheaders()
+ raise RuntimeError("{0}: {1}".format(response.status,
+ response.reason))
+ return response.read()
+
+# If this is invoked as a program, just give
+# a greeting to show it is working.
+# The platform specific code is moved to this
+# part so that this file may be imported without
+# bringing platform specific code in.
+if __name__ == "__main__":
+
+ # For handling command line arguments:
+ import sys
+ import platform
+
+ # check we are on Windows:
+ system = platform.system().lower()
+ if (system == "windows"):
+
+ import winsound
+
+ class Player:
+ def __init__(self):
+ pass
+
+ def play(self, a_sound):
+ winsound.PlaySound(a_sound, winsound.SND_MEMORY)
+
+ #if ("cygwin" in system):
+ else:
+ # Not sure how to do audio on cygwin,
+ # portably for python. So have a sound
+ # player class that doesn't play sounds.
+ # A null object, if you like.
+ class Player:
+ def __init__(self):
+ pass
+
+ def play(self, a_sound):
+ print("Here I would play a sound if I knew how")
+ pass
+
+ # Probably want to parse arguments to
+ # set the voice, etc., here
+
+ client = maryclient()
+ client.set_audio("WAVE_FILE") # for example
+
+ player = Player()
+ the_sound = client.generate("hello from Mary Text to Speech, with Python.")
+ if client.output_type == "AUDIO":
+ player.play(the_sound)
+
+# vi:set sw=4 et:
diff --git a/lib/marytts-5.2.1/doc/examples/client/maryclient.cgi b/lib/marytts-5.2.1/doc/examples/client/maryclient.cgi
new file mode 100644
index 0000000..876a846
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/maryclient.cgi
@@ -0,0 +1,177 @@
+#!/usr/bin/perl -T
+# -*- Mode: Perl -*-
+# MARY Text-to-Speech System
+# CGI Script implementing a simple mary client,
+# can be used for web pages.
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+# Author: Marc Schroeder
+
+use strict;
+use IO::Socket;
+use CGI;
+
+# variables getting their values from form:
+my ($inputtext, $in, $out, $audiotype, $voice);
+
+# little helpers:
+my ($var, $tmp);
+
+# contacting the mary server:
+my ($host, $port, $maryInfoSocket, $maryDataSocket, $id);
+
+# helping with audio output:
+my ($save_to_disk, $audiosubtype, $filename);
+
+
+my $cgi = new CGI;
+my @param = $cgi->param();
+$inputtext = $cgi->param('inputtext');
+$in = $cgi->param('in');
+$out = $cgi->param('out');
+$audiotype = $cgi->param('audiotype');
+$save_to_disk = $cgi->param('save_to_disk');
+$voice = $cgi->param('voice');
+
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
+$year += 1900;
+printf STDERR "[%04i-%02i-%02i %02i:%02i:%02i] ", $year, $mon, $mday, $hour, $min, $sec;
+print STDERR "Request from ",$cgi->remote_user(),"@",$cgi->remote_host(),": \n";
+print STDERR " in=",$in;
+print STDERR " out=",$out;
+print STDERR " audiotype=",$audiotype;
+print STDERR " voice=",$voice;
+print STDERR " save_to_disk=",$save_to_disk,"\n";
+print STDERR " inputtext: ";
+print STDERR $inputtext,"\n";
+
+
+# Limit inputtext length to 5000 bytes:
+if (length $inputtext > 5000) {
+ $inputtext = substr $inputtext, 0, 5000;
+}
+
+
+# set audio subtype
+if ($out eq "AUDIO") {
+ if ($audiotype eq "AU") {
+ $audiosubtype = "basic";
+ $filename = "mary.au";
+ } elsif ($audiotype eq "AIFF") {
+ $audiosubtype = "x-aiff";
+ $filename = "mary.aiff";
+ } elsif ($audiotype eq "WAVE") {
+ $audiosubtype = "x-wav";
+ $filename = "mary.wav";
+ } elsif ($audiotype eq "MP3") {
+ $audiosubtype = "mp3";
+ $filename = "mary.mp3";
+ } else {
+ $audiosubtype = "x-wav";
+ $filename = "mary.wav";
+ }
+}
+
+# announce data type on stdout
+if ($save_to_disk) {
+ print "Content-Type: application/octet-stream";
+} else {
+ print "Content-Type: audio/$audiosubtype";
+}
+print "\nContent-Disposition: filename=\"$filename\"\n\n";
+
+# contact mary server
+$host = "cling.dfki.uni-sb.de";
+$port = 59125;
+
+# create a tcp connection to the specified host and port
+$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+
+# avoid buffering when writing to server:
+$maryInfoSocket->autoflush(1); # so output gets there right away
+
+########## Write input to server: ##########
+# formulate the request:
+print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
+if ($voice && $voice ne 'v') { print $maryInfoSocket " VOICE=$voice"; }
+print $maryInfoSocket " LOG=\"REMOTE_HOST=$ENV{'REMOTE_HOST'}",
+ ", REMOTE_ADDR=$ENV{'REMOTE_ADDR'}\"";
+print $maryInfoSocket "\015\012";
+
+# receive a request ID:
+$id = <$maryInfoSocket>;
+
+# open second socket for the data:
+$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+# identify with request number:
+print $maryDataSocket $id; # $id contains a newline character
+
+# copy $inputtext to mary data socket
+print $maryDataSocket $inputtext;
+
+# mark end-of-request:
+print $maryDataSocket "\015\012"; # that is a \n, actually
+$maryDataSocket->shutdown(1); # we have stopped writing data
+
+########## Read output from server: ##########
+# copy the data socket to standard output
+if ($out ne "AUDIO") { # text output
+ my $line;
+ while (defined ($line = <$maryDataSocket>)) {
+ print STDOUT $line;
+ }
+} else { # audio data output
+ my $nr; # number of bytes read
+ my $buf; # buffer to read into
+ my $outnr; # number of bytes written
+ while($nr = read($maryDataSocket, $buf, 8192)) {
+ # (read returns no. of bytes read, 0 at eof)
+ print STDOUT $buf
+ or die "Write error on stdout";
+ } # while read something from socket
+} # audio output
+
+### Read complaints from server:
+my $line;
+while (defined ($line = <$maryInfoSocket>)) {
+ print STDERR $line;
+}
+
+
+
+
+
+
+
diff --git a/lib/marytts-5.2.1/doc/examples/client/maryclient.pl b/lib/marytts-5.2.1/doc/examples/client/maryclient.pl
new file mode 100644
index 0000000..8b3f5f8
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/maryclient.pl
@@ -0,0 +1,136 @@
+#!/usr/bin/env perl
+#
+# MARY Text-to-Speech System
+# Minimal Socket client (for demonstration)
+##########################################################################
+# Copyright (C) 2000-2006 DFKI GmbH.
+# All rights reserved. Use is subject to license terms.
+#
+# Permission is hereby granted, free of charge, to use and distribute
+# this software and its documentation without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of this work, and to
+# permit persons to whom this work is furnished to do so, subject to
+# the following conditions:
+#
+# 1. The code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+# 2. Any modifications must be clearly marked as such.
+# 3. Original authors' names are not deleted.
+# 4. The authors' names are not used to endorse or promote products
+# derived from this software without specific prior written
+# permission.
+#
+# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
+# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+# THIS SOFTWARE.
+##########################################################################
+# Author: Marc Schroeder
+# This is a minimal version of a socket client for the mary TtS system.
+# It is intended to be used as a model for writing socket clients for
+# particular applications. All input verification, command line options,
+# and other luxury have been omitted.
+#
+# Usage:
+# maryclient.pl infile.txt > outfile.wav
+#
+# Input/output formats and other options must be set in the perl code directly.
+# See also Protocol.html for a description of the Protocol.
+#
+
+use strict;
+use IO::Socket;
+
+############################
+# Package-global variables #
+############################
+# global settings:
+my $maryInfoSocket; # handle to socket server
+my $maryDataSocket; # handle to socket server
+my $host; # string containing host address
+my $port; # socket port on which we listen
+my ($in, $out, $audiotype); # requested input / output format
+my $voice; # default voice
+my $id; # request ID
+
+######################################################################
+################################ main ################################
+######################################################################
+
+STDOUT->autoflush(1);
+
+$host = "cling.dfki.uni-sb.de";
+$port = 59125;
+$in = "TEXT_DE";
+$out = "AUDIO";
+$audiotype = "MP3";
+#$audiotype = "WAVE";
+#$voice = "male";
+$voice = "de3";
+
+# create a tcp connection to the specified host and port
+$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+
+# avoid buffering when writing to server:
+$maryInfoSocket->autoflush(1); # so output gets there right away
+
+########## Write input to server: ##########
+# formulate the request:
+print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
+if ($voice) { print $maryInfoSocket " VOICE=$voice"; }
+print $maryInfoSocket "\015\012";
+
+# receive a request ID:
+$id = <$maryInfoSocket>;
+chomp $id; chomp $id;
+
+# open second socket for the data:
+$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
+ PeerAddr => $host,
+ PeerPort => $port)
+ or die "can't connect to port $port on $host: $!";
+# identify with request number:
+print $maryDataSocket $id, "\015\012";
+
+# copy standard input and/or files given on the command line to the socket
+while (defined (my $line = <>)) {
+ print $maryDataSocket $line;
+}
+# mark end-of-request:
+print $maryDataSocket "\015\012"; # that is a \n, actually
+shutdown($maryDataSocket, 1); # we have stopped writing data
+
+########## Read output from server: ##########
+# copy the data socket to standard output
+if ($out ne "AUDIO") { # text output
+ my $line;
+ while (defined ($line = <$maryDataSocket>)) {
+ print STDOUT $line;
+ }
+} else { # audio data output
+ my $nr; # number of bytes read
+ my $buf; # buffer to read into
+ my $outnr; # number of bytes written
+ while($nr = read($maryDataSocket, $buf, 100000)) {
+ # (read returns no. of bytes read, 0 at eof)
+ print STDOUT $buf
+ or die "Write error on stdout";
+ } # while read something from socket
+} # audio output
+
+### Read complaints from server:
+my $line;
+while (defined ($line = <$maryInfoSocket>)) {
+ print STDERR $line;
+}
+
+
+
diff --git a/lib/marytts-5.2.1/doc/examples/client/maryclient.rb b/lib/marytts-5.2.1/doc/examples/client/maryclient.rb
new file mode 100644
index 0000000..c4156cb
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/maryclient.rb
@@ -0,0 +1,261 @@
+#!/usr/bin/env ruby
+#
+# A basic mary client in Ruby,
+# kindly donated to the MARY TTS project
+# by Hugh Sasse. Thanks Hugh!
+
+
+# Ruby client for the MARY TTS HTTP server.
+# This is for Windows only, and relies on
+# the Win32-Sound gem to access the audio.
+#
+#
+
+require 'rubygems'
+require 'net/http'
+require 'uri'
+
+# A fairly minimal client class for the
+# MARY TTS system. This uses the modern
+# HTTP interface to access the server.
+# At present, this doesn't wrap the methods
+# which provide documentation or lists of
+# voices or features.
+class MaryClient
+ attr_accessor :host, :port
+ attr_accessor :input_type, :output_type
+ attr_accessor :locale, :audio, :voice
+
+ # Set up the defaults for the MARY TTS
+ # server, which is assumed to be running
+ # on the local host, with British voices
+ # installed. These may be modified with
+ # the appropriate methods.
+ # host = 127.0.0.1)
+ # port = 59125
+ # input_type = "TEXT"
+ # output_type = "AUDIO"
+ # audio = "WAVE_FILE"
+ # locale = "en_GB"
+ # voice = "dfki-prudence-hsmm"
+ def initialize
+ @host = "127.0.0.1" # The local machine
+ @port = 59125
+ @input_type = "TEXT"
+ @output_type = "AUDIO"
+ @locale = "en_GB"
+ @audio = "WAVE_FILE"
+ @voice = "dfki-prudence-hsmm"
+ end
+
+ # Process a text message, which with a
+ # new client, will return the audio.
+ # This is so that platform dependent parts
+ # are kept separate.
+ def generate(message)
+ raw_params = {"INPUT_TEXT" => message,
+ "INPUT_TYPE" => @input_type,
+ "OUTPUT_TYPE" => @output_type,
+ "LOCALE" => @locale,
+ "AUDIO" => @audio,
+ "VOICE" => @voice,
+ }
+ res = Net::HTTP.post_form(URI.parse("http://#{@host}:#{@port}/process"), raw_params)
+ res.value # Throw an exception on failure
+ #puts res.body
+ return res.body
+ end
+end
+
+
+# If this invoked as a program with no
+# argumens, just give a greeting to show
+# that it is working. If arguments are
+# supplied, process options to work out
+# what to do with the arguments.
+if __FILE__ == $0
+
+ # These files are only loaded when this is
+ # invoked as a program.
+ require 'rbconfig'
+ require 'getoptlong'
+
+ # PLATFORM SPECIFIC CODE.
+ # Needs more work [!]
+ case Config::CONFIG['host_os']
+ when /darwin/i
+ raise NotImplementedError.new("Don't know how to play audio on a Mac")
+ when /linux/i
+ raise NotImplementedError.new("Far too many ways to play audio on Linux, you'll need to choose something")
+ when /sunos|solaris/i
+ raise NotImplementedError.new("Have not played audio on Suns for too long to implement this.")
+ when /java/i
+ raise NotImplementedError.new("Don't know how to play audio from Java ")
+ when /win32|cygwin|mingw32/i
+ # The various things that can use the Win32
+ # sound gem
+ require 'win32/sound'
+ # Create a player class that will play the
+ # sound that the Mary TTS system returns
+ class Player
+
+ # Play the audio passed in.
+ # Possibly this should receive the audio
+ # type so we can check that we can play it,
+ # but at the moment that is the
+ # responsibility of the user.
+ def self.play(sound)
+ Win32::Sound.play(sound, Win32::Sound::MEMORY)
+ end
+ end
+ else
+ raise NotImplementedError.new("Haven't thought how to support this OS yet")
+ end
+
+
+ client = nil
+ split = ""
+
+ if ARGV.size.zero?
+ client = MaryClient.new()
+ sound = client.generate("Hello from Mary Text to Speech with Ruby.")
+ Player.play(sound)
+ else
+ args_mode = :words
+ stdout_mode = :absorb
+ opts = GetoptLong::new(
+ ["--audio", "-a", GetoptLong::REQUIRED_ARGUMENT],
+ ["--echo", "-e", GetoptLong::NO_ARGUMENT],
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
+ ["--host", "-H", GetoptLong::REQUIRED_ARGUMENT],
+ ["--input-type", "-i", GetoptLong::REQUIRED_ARGUMENT],
+ ["--locale", "-l", GetoptLong::REQUIRED_ARGUMENT],
+ ["--read", "-r", GetoptLong::NO_ARGUMENT],
+
+ ["--split", "-s", GetoptLong::REQUIRED_ARGUMENT],
+ ["--output-type", "-o", GetoptLong::REQUIRED_ARGUMENT],
+ ["--port", "-P", GetoptLong::REQUIRED_ARGUMENT],
+ ["--tee", "-t", GetoptLong::NO_ARGUMENT],
+ ["--voice", "-v", GetoptLong::REQUIRED_ARGUMENT]
+ )
+
+ opts.each do |opt, arg|
+ unless ["--help", "-h"].include?(opt)
+ # skip if we are only getting help
+ client ||= MaryClient.new()
+ end
+ case opt
+ when "--help", "-h"
+ puts <<-EOHELP
+Usage: #{$0} [options] [arguments]
+--audio -a
+ Audio format. Defualt: WAVE_FILE
+--echo -e
+ Act as an echo command and send output
+ arguments to the synthesizer only (not
+ to standard output.
+ Turns off --read|-r
+--help -h
+ Print this help, then exit.
+--host -H
+ The host which is the server.
+ Default: 127.0.0.1
+--input-type -i
+ The type of the input supplied to the
+ TTS system. Default: TEXT
+--locale -l
+ The locale of the input. Default: en_GB
+--output-type -o
+ The output type from the TTS system.
+ Default: AUDIO
+--port -P
+ The port for the TTS server
+ Default: 59125
+--read -r
+ Read the files passed as arguments.
+ Turns off --echo|-e
+--split -s (lines|paragraphs)
+ When reading files, split the input
+ into lines or paragraphs. Paragraphs
+ mean reading up to the next double
+ newline. Note, the argument is literally
+ "lines" or "paragraphs" (or some
+ abbreviation of those) without the
+ quotes.
+ Default is paragraphs.
+--tee -t
+ Act as tee: send the output to the TTS
+ system, and to standard output.
+--voice -v
+ The voice to use.
+ Default: dfki-prudence-hsmm
+ EOHELP
+ exit(0)
+ when "--audio", "-a"
+ client.audio = arg
+ when "--echo", "-e"
+ args_mode = :words
+ when "--host", "-H"
+ client.host = arg
+ when "--input-type", "-i"
+ client.input_type = arg
+ when "--locale", "-l"
+ client.locale = arg
+ when "--output-type", "-o"
+ client.output_type = arg
+ when "--port", "-P"
+ client.port = arg.to_i
+ when "--read", "-r"
+ args_mode = :files
+ when "--split", "-s"
+ case arg
+ when /^p/i
+ split = ""
+ when /^l/i
+ split = $/
+ end
+ when "--tee", "-t"
+ stdout_mode = :emit
+ when "--voice", "-v"
+ client.voice = arg
+ end
+ end
+
+ client ||= MaryClient.new()
+ case args_mode
+ when :words
+ input_text = ARGV.join(" ")
+ unless input_text =~ /\A\s*\Z/m
+ sound = client.generate(input_text)
+ if client.output_type == "AUDIO"
+ Player.play(sound)
+ end
+ end
+ if stdout_mode == :emit
+ puts input_text
+ end
+ when :files
+ # Slurp in paragraphs so sentences
+ # don't get broken in stupid places.
+ $/ = split # paragraph mode
+ ARGF.each do |paragraph|
+ begin
+ unless paragraph =~ /\A\s*\Z/m
+ sound = client.generate(paragraph)
+ if client.output_type == "AUDIO"
+ # and client.audio == "WAVE_FILE"
+ Player.play(sound)
+ end
+ end
+ rescue Exception => e
+ puts "got error #{e} while trying to say #{paragraph.inspect}"
+ raise
+ end
+ if stdout_mode == :emit
+ puts paragraph
+ end # end if
+ end # end ARGF.each
+ end # end case
+ end # if ARGV.size.zero?
+end
+
diff --git a/lib/marytts-5.2.1/doc/examples/client/maryclient.tcl b/lib/marytts-5.2.1/doc/examples/client/maryclient.tcl
new file mode 100644
index 0000000..3a35823
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/maryclient.tcl
@@ -0,0 +1,705 @@
+# Tcl/Tk MARY TTS client.
+
+# This has been tested on Windows, and because
+# of the use of sound there will be portability
+# issues. However, there should be enough here
+# for a reasonable start at a client, for any
+# platform that supports Tcl/Tk. The platform
+# specific code has, as far as possible, been
+# isolated in the part of the code that detects
+# whether this is being run as a program.
+
+# Notes:
+# More work will need to be done with this,
+# in order to make the code clean. It should
+# probably be wrapped in a package, to solve
+# any namespace issues. There are a lot of
+# global variables. It seems that some of
+# these are necessary for the menus to work.
+# Handling of temporary files could be improved.
+
+# TODO:
+# Create modifier sliders, for the effects.
+# Extend the query proc to make use of them.
+# Turn the Help menu into something more useful.
+# Debug the actions for the Edit menu.
+# Provide a means of getting example inputs
+# from the server.
+# Provide a means of re-loading all the
+# dynamically collected information when the
+# server is changed from the menu. This means
+# that we need to delete the existing menu
+# entries in order to add them correctly.
+# How do we ensure temporary files are removed
+# in the event of a problem? if {catch {}} ...?
+# Maybe leaving them around is diagnostic info?
+# Make that an option?
+# Add error handling code for network and disk
+# failures likely to beset such clients.
+# Add sensible defaults for things the user must
+# always set at startup, but these will be
+# platform spacific. Always default to Audio
+# output for example, or is it possible that
+# people have no voices installed?
+
+
+# This is a GUI, so:
+package require Tk
+
+# We are communicating with the Mary server
+# with HTTP.
+package require http
+
+# Use the local machine in preference to the
+# one in Germany.
+set mary_tts_default_host "127.0.0.1"
+set mary_tts_default_port 59125
+
+# Actual host and port, and global old
+# copies to allow revert on cancel in the
+# dialogues. Apparently upvar #0 is the
+# norm for that sort of thing [Tcl Wiki]
+set mary_tts_host $mary_tts_default_host
+set old_mary_tts_host $mary_tts_host
+set mary_tts_port $mary_tts_default_port
+set old_mary_tts_port $mary_tts_port
+
+# Informational URLs
+set informational_urls [ list \
+version datatypes voices \
+audioformats audioeffects ]
+
+#######
+
+# Obtain a static page from the server, i.e.
+# no parameters are needed to get it.
+proc get_page { relative_url } {
+ global mary_tts_host mary_tts_port
+ set url http://$mary_tts_host:$mary_tts_port/$relative_url
+ set result [::http::geturl $url]
+ return [::http::data $result]
+}
+
+proc list_of_lines {str} {
+ return [ split $str "\n" ]
+}
+
+
+# We will need to collect this information
+# when we have the server and port chosen.
+proc get_audioeffects {} {
+ return [list_of_lines [get_page audioeffects] ]
+}
+
+proc get_audioformats {} {
+ return [list_of_lines [get_page audioformats] ]
+}
+
+proc get_datatypes {} {
+ return [ list_of_lines [get_page datatypes] ]
+}
+
+
+proc get_voices {} {
+ return [list_of_lines [get_page voices] ]
+}
+
+# Handling post queries.
+
+# Submit the query to the server, using the
+# http POST method.
+proc make_query {url encoded_params} {
+ set http [::http::geturl $url -query $encoded_params]
+ set result [::http::data $http]
+ return $result
+}
+
+# Get the text from the input text area
+proc get_input_text {} {
+ return [.io.inp.input_area get 1.0 end]
+}
+
+# Get the text from the output text area
+proc get_output_text {} {
+ return [.io.out.output_area get 1.0 end]
+}
+
+# Collect the audio data from the server.
+proc collect_audio_data {text_to_process} {
+ global mary_tts_host mary_tts_port
+ global inputtype outputtype locales
+ global audioformat voice
+ set url "http://$mary_tts_host:$mary_tts_port/process"
+ # ::http::formatQuery converts a list of
+ # key value pairs into the correct format
+ # for http POST.
+ set params [::http::formatQuery INPUT_TEXT $text_to_process INPUT_TYPE $inputtype OUTPUT_TYPE $outputtype LOCALE $locales($voice) AUDIO $audioformat VOICE $voice ]
+ set result [make_query $url $params]
+ return $result
+}
+
+# Pushes the query to the server and gets
+# the results back, displaying or playing
+# them.
+proc generate_output {text_to_process} {
+ global outputtype
+ set result [collect_audio_data $text_to_process]
+ if {$outputtype eq "AUDIO"} {
+ # call the platform dependent implementation.
+ play $result
+ } else {
+ clear_output
+ add_message $result
+ }
+ # Return the result so we can save it if
+ # the user requires it.
+ return $result
+}
+
+
+# These next procs are for handling the
+# lists of data one gets back from the server
+# which possibly have several words per line,
+# separated by spaces.
+
+# If the first word of each listed line is
+# significant, extract the list of first words.
+proc collect_first_words_of_phrase_list {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ return $words
+}
+
+
+# If the second word of each listed line is
+# significant, extract the list of second words.
+proc collect_second_words_of_phrase_list {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ set word [ lindex [split $data " "] 1 ]
+ lappend words $word
+ }
+ return $words
+}
+
+
+# The list of datatypes must be separated into
+# input data types and output data types so that
+# interactions with the server make sense.
+# This handles the inputs.
+proc collect_first_words_of_input_types {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ if {[ string match -nocase "*input*" $data ]} {
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ }
+ return $words
+}
+
+
+# The list of datatypes must be separated into
+# input data types and output data types so that
+# interactions with the server make sense.
+# This handles the outputs.
+proc collect_first_words_of_output_types {a_list} {
+ for {set i 0} {$i < [llength $a_list]} {incr i} {
+ set data [lindex $a_list $i ]
+ if {[string match -nocase "*output*" $data]} {
+ set word [ lindex [split $data " "] 0 ]
+ lappend words $word
+ }
+ }
+ return $words
+}
+
+# setup all the variables to hold voices,
+# audio options, etc., based on what the
+# server can do.
+proc setup_globals {} {
+ global audioeffects audioformats voices
+ global inputtypes outputtypes audioformat voice
+ global inputtype outputtype locales
+
+ set audioeffects [get_audioeffects]
+ set audioformats [get_audioformats]
+ set audioformat [lindex $audioformats 0 ]
+ set datatypes_data [get_datatypes]
+ set inputtypes [collect_first_words_of_input_types $datatypes_data]
+ set inputtype [lindex $inputtypes 0]
+ set outputtypes [collect_first_words_of_output_types $datatypes_data]
+ set outputtype [lindex $outputtypes 0]
+ set voices_data [get_voices]
+ set voices [collect_first_words_of_phrase_list $voices_data]
+ set locales_list [collect_second_words_of_phrase_list $voices_data ]
+ for {set i 0} {$i < [llength $voices]} {incr i} {
+ set locales([lindex $voices $i]) [lindex $locales_list $i]
+ }
+ set voice [lindex $voices 0]
+}
+
+# A general procedure for filling in the
+# elements of a listbox from a list.
+# At present this is unused, but it could
+# be useful later. [It took a while to
+# figure out so I'm not ready to kill it
+# with YAGNI.]
+proc add_listbox_items {a_var a_widget} {
+ upvar $a_var var
+ foreach item $var {
+ $a_widget insert end $item
+ }
+}
+
+# Create the menubuttons along the top.
+# Usual File, Edit and Help menus plus
+# those to set attributes.
+proc create_menubuttons {} {
+ set buttons [ list file File edit Edit \
+ server "Server" \
+ inputtype "Input type" outputtype "Output type" \
+ voice Voice \
+ audioformat "Audio format" \
+ textstyle "Text style" help Help ]
+
+ set count 1
+ foreach { menu_tag string_tag} $buttons {
+ menubutton .menus.$menu_tag -text $string_tag \
+ -menu .menus.${menu_tag}.menu -underline 0 -font ClientFont
+ menu .menus.${menu_tag}.menu -tearoff true
+ grid .menus.$menu_tag -in .menus -row 1 -column $count -sticky w
+ incr count
+ }
+}
+
+# Get the contents of a text file for reading
+# or loading into a text widget, etc.
+proc text_file_contents {what_for} {
+ set a_file [tk_getOpenFile -title $what_for ]
+ set the_text ""
+
+ if {$a_file != ""} {
+ set a_stream [open $a_file r ]
+ set the_text [read $a_stream]
+ close $a_stream
+ }
+
+ return $the_text
+}
+
+
+# Save the_text to a text file specified
+# by the user, for the given reason (what_for).
+# At the moment there is no error handling
+# for this (disk full, write protected, etc).
+proc save_text_file {the_text what_for} {
+ set a_file [tk_getSaveFile -title $what_for -parent .]
+ if {$a_file != ""} {
+ set a_stream [open $a_file w ]
+ puts $a_stream $the_text
+ close $a_stream
+ }
+}
+
+# Save the_data to a binary file specified
+# by the user, for the given reason (what_for),
+# a text string.
+# At the moment there is no error handling
+# for this (disk full, write protected, etc).
+proc save_binary_file {the_data what_for} {
+ set a_file [tk_getSaveFile -title $what_for -parent .]
+ if {$a_file != ""} {
+ set a_stream [open $a_file w ]
+ fconfigure $a_stream -translation binary
+ puts -nonewline $a_stream $the_data
+ close $a_stream
+ }
+}
+
+# Create the menu for File operations
+proc create_menu_file {} {
+ set fmenu .menus.file.menu
+ $fmenu add command -label "New" \
+ -font ClientFont -command {
+ .io.inp.input_area delete 1.0 end
+ }
+ # Replace the contents of the input text
+ # widget by the data from the open file.
+ # YAGNI, but is there any reason
+ # to allow inserting a file, rather than
+ # replacing the text with file contents?
+ #
+ $fmenu add command -label "Open" \
+ -font ClientFont -command {
+ set the_text [text_file_contents "File to load"]
+ if {$the_text != ""} {
+ .io.inp.input_area delete 1.0 end
+ .io.inp.input_area insert end $the_text
+ }
+ }
+
+ $fmenu add command -label "Read" \
+ -font ClientFont -command {
+ generate_output [text_file_contents "File to read"]
+ }
+ # How to make these disabled for now?
+ $fmenu add command -label "Save Input" \
+ -font ClientFont -command {
+ set the_text [get_input_text]
+ save_text_file $the_text "Save Input"
+ }
+ $fmenu add command -label "Save Output" \
+ -font ClientFont -command {
+ set the_text [get_output_text]
+ save_text_file $the_text "Save Output"
+ }
+}
+
+# Create the menu for edit operations
+proc create_menu_edit {} {
+ set emenu .menus.edit.menu
+ $emenu add command -label "Select All from Input Area" \
+ -font ClientFont -command {
+ # This code says copy the selection as well.
+ # May be wrong for some platforms, but is
+ # it more useful?
+ .io.inp.input_area tag add sel 1.0 end
+ event generate .io.inp.input_area <>
+}
+ $emenu add command -label "Select All from Output Area" \
+ -font ClientFont -command {
+ # This code says copy the selection as well.
+ # May be wrong for some platforms, but is
+ # it more useful?
+ .io.out.output_area tag add sel 1.0 end
+ event generate .io.out.output_area <>
+}
+ $emenu add command -label "Copy from Input Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.inp.input_area <>
+ }
+ $emenu add command -label "Copy from Output Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.out.output_area <>
+ }
+ $emenu add command -label "Paste into Input Area" \
+ -font ClientFont -command {
+ # this appears not to work. FIXME
+ event generate .io.inp.input_area <>
+ }
+ $emenu add command \
+ -font ClientFont -label "Insert example text into Input Area"\
+ -command {
+ }
+ # Add specific editing commands here later.
+ # For example, we would like to be able to
+ # add whole tags to the XML based formats,
+ # wrap matching tags around selected text.
+ # Also we need to find out what happens with
+ # copy cut and paste, given that X Windows
+ # is different from MS Windows.
+ # Allow example text to be inserted.
+ # However, my thinking is that this should not
+ # overwrite as it is in the Java application,
+ # because this rubs out edits when switching
+ # voices, and this can be annoying when
+ # exploring the system.
+}
+
+# Set the server properties, mostly just
+# host and port. Maybe later protocol will
+# be possible for https connections?
+proc create_menu_server {} {
+ set smenu .menus.server.menu
+ $smenu add command -label "host" -font ClientFont -command {
+ create_entry_dialog "MARY TTS server name" "hostname/IP Address" mary_tts_host
+ }
+ $smenu add command -label "port" -font ClientFont -command {
+ create_entry_dialog "MARY TTS server port" "pott number" mary_tts_port
+ }
+}
+
+# setup the fonts for the various areas on the dipslay.
+proc setup_font {family size} {
+ foreach win {.io .controls .entry.dialogue } {
+ font configure ClientFont -family $family -size $size
+ }
+}
+
+# Create the menu for changing the text size.
+proc create_menu_textstyle {} {
+ set tmenu .menus.textstyle.menu
+
+ $tmenu add cascade -label "Courier" -underline 0 -menu \
+ $tmenu.courier -font ClientFont
+ $tmenu add cascade -label "Times" -underline 0 -menu \
+ $tmenu.times -font ClientFont
+ $tmenu add cascade -label "Helvetica" -underline 0 -menu \
+ $tmenu.helvetica -font ClientFont
+ foreach {name family} [list $tmenu.courier Courier \
+ $tmenu.times Times $tmenu.helvetica Helvetica ] {
+ set m1 [menu $name]
+ foreach pts {6 7 8 9 10 12 14 16 18 20 24 28 32 36} {
+ $m1 add command -label "$pts" -font ClientFont\
+ -command [list setup_font $family $pts ]
+ }
+ }
+}
+
+
+
+# Create the menu for Help
+proc create_menu_help {} {
+ # This is all pretty much "wet paint"
+ # Is there enough to merit separate menus?
+ set hmenu .menus.help.menu
+ $hmenu add command -label "Introduction" -font ClientFont\
+ -command {
+ tk_messageBox -message "This is a basic Tcl/Tk
+client for the MARY TTS system. Most of the options
+are reached through the menus on the top. Some
+facilities are presently lacking.
+
+Most of the interface should be self-explanatory.
+In the File menu, Read will read a given file aloud
+(or at least take it as input for the present
+form of processing), whereas Open will load it
+into the input area. Save input and Save output
+refer to the contents of the text windows. The
+save button next to the play button will save
+the output to a file; this is assumed to be a
+text file, unless the output is audio, in which
+case it is a binary file.
+
+The Edit menu has cut and paste facilities,
+but these don't seem to work reliably. The
+default key bindings for text areas should
+be useable.
+
+You will need to set the input and output types
+and the audio format before pressing play.
+Code does not yet exist to figure out sensible
+defaults for your platform.
+
+This does not have support for the effects, yet.
+
+Contributions from developers welcome." -type ok
+ }
+ $hmenu add command -label "About" -command {} -font ClientFont
+}
+
+# We need to create menus for the available
+# voices and audio formats, etc.
+# When we have the data for these menus from
+# the server, create them by using the global
+# lists of information.
+proc create_radio_menu_from_list {what} {
+ global $what
+ set plural "${what}s"
+ upvar 1 $plural var
+ foreach item $var {
+ .menus.${what}.menu add radiobutton -label $item -variable $what \
+ -value $item -font ClientFont
+ }
+}
+
+proc reset_entry_and_var {a_variable} {
+ upvar #0 $a_variable var
+ upvar #0 old_$a_variable old_var
+ set var $old_var
+ destroy .entry_dialogue
+}
+# Create the toplevel for choosing a host
+# or port, something taken from an entry.
+proc create_entry_dialog {a_message a_label a_variable} {
+ upvar #0 $a_variable var
+ upvar #0 old_$a_variable old_var
+ toplevel .entry_dialogue
+ label .entry_dialogue.the_message -text $a_message \
+ -font ClientFont
+ label .entry_dialogue.the_label -text $a_label -font ClientFont
+ entry .entry_dialogue.the_entry -textvariable $a_variable \
+ -font ClientFont
+ button .entry_dialogue.ok -text "OK" -font ClientFont -command {
+ destroy .entry_dialogue
+ }
+ button .entry_dialogue.cancel -text "Cancel" -font ClientFont \
+ -command "reset_entry_and_var $a_variable"
+
+ grid .entry_dialogue.the_message -row 1 -column 1
+ grid .entry_dialogue.the_label -row 2 -column 1
+ grid .entry_dialogue.the_entry -row 2 -column 2
+ grid .entry_dialogue.ok -row 3 -column 1
+ grid .entry_dialogue.cancel -row 3 -column 2
+}
+
+# Add a message to the end of the output
+# text widget.
+proc add_message {a_message} {
+ .io.out.output_area configure -state normal
+ .io.out.output_area insert end $a_message
+ .io.out.output_area configure -state disabled
+}
+
+
+# Clear the text in the output text widget.
+proc clear_output {} {
+ .io.out.output_area configure -state normal
+ .io.out.output_area delete 1.0 end
+ .io.out.output_area configure -state disabled
+}
+
+# Sound generation is platform dependent.
+# This provides an "abstract" function to
+# be overridden by the platform dependent
+# code. In this case it alerts the user
+# in the output window that nothing is going
+# to happen.
+proc play {sound} {
+ add_message \
+ "play sound not implemented on this platform apparently"
+}
+
+# Graphical stuff.
+
+# In order to be able to scale the font, define a font.
+font create ClientFont -family [font actual TkDefaultFont -family] \
+ -size [font actual TkDefaultFont -size]
+
+frame .menus
+create_menubuttons
+create_menu_file
+create_menu_edit
+create_menu_server
+create_menu_textstyle
+create_menu_help
+# Fill in the other menus at runtime.
+
+# .io communicates text with the user,
+# through an input and output window.
+frame .io
+frame .io.inp
+frame .io.out
+# .controls will hold the play button and
+# the effects controls.
+frame .controls
+
+# Draw the controls in .io
+label .io.inp.input_label -text "Input Area" -font ClientFont
+text .io.inp.input_area -height 10 -width 40 \
+-xscrollcommand ".io.inp.input_x set" \
+-yscrollcommand ".io.inp.input_y set" -font ClientFont
+scrollbar .io.inp.input_x -orient horizontal \
+-command ".io.inp.input_area xview"
+scrollbar .io.inp.input_y -orient vertical \
+-command ".io.inp.input_area yview"
+
+label .io.out.output_label -text "Output Area" -font ClientFont
+text .io.out.output_area -height 10 -width 40 -state disabled \
+-xscrollcommand ".io.out.output_x set" \
+-yscrollcommand ".io.out.output_y set" -font ClientFont
+scrollbar .io.out.output_x -orient horizontal \
+-command ".io.out.output_area xview"
+scrollbar .io.out.output_y -orient vertical \
+-command ".io.out.output_area yview"
+
+grid .io.inp -in .io -row 1 -column 1
+grid .io.out -in .io -row 1 -column 2
+grid .io.inp.input_label -in .io.inp -row 1 -column 1
+grid .io.inp.input_area -in .io.inp -row 2 -column 1
+grid .io.inp.input_y -in .io.inp -row 2 -column 2 -sticky ns
+grid .io.inp.input_x -in .io.inp -row 3 -column 1 -sticky ew
+
+grid .io.out.output_label -in .io.out -row 1 -column 1
+grid .io.out.output_area -in .io.out -row 2 -column 1
+grid .io.out.output_y -in .io.out -row 2 -column 2 -sticky ns
+grid .io.out.output_x -in .io.out -row 3 -column 1 -sticky ew
+
+button .controls.play -text "play" -font ClientFont -command {
+ generate_output [get_input_text]
+}
+grid .controls.play -in .controls -row 1 -column 1
+
+button .controls.save -text "save" -font ClientFont -command {
+ global outputtype
+ set input_text [get_input_text]
+ if { $outputtype eq "AUDIO" } {
+ save_binary_file [collect_audio_data $input_text ] "Save audio file"
+ } else {
+ save_text_file [collect_audio_data $input_text ] "Save output to file"
+ }
+}
+
+grid .controls.save -in .controls -row 1 -column 2
+
+pack .menus .io .controls -in . -side top
+
+
+
+# Detect whether this is the main program
+# This test was taken from the Tcl Wiki, and
+# seems to work OK.
+
+if {[info exists argv0] && [file tail [info script]] eq [file tail $argv0]} {
+
+ # Try to find the temporary files directory.
+ catch { set tmpdir "/tmp" }
+ catch { set tmpdir $::env(TRASH_FOLDER) }
+ catch { set tmpdir $::env(TMP) }
+ catch { set tmpdir $::env(TEMP) }
+ # This needs better handling of
+ # possible alternatives
+ # This is needed for Windows sound only.
+
+ # Do the platform dependent things.
+ if {$tcl_platform(platform) eq "windows"} {
+ package require twapi
+
+ proc play {sound} {
+ global tmpdir
+ # Write sound to a temporary file
+ set sndfile [file join $tmpdir "MARYTTS_sound.[pid].wav" ]
+ set stream [open $sndfile w]
+ # Make sure the file is binary:
+ fconfigure $stream -translation binary
+ puts -nonewline $stream $sound
+ close $stream
+ # Play the file.
+ ::twapi::play_sound $sndfile
+ # Remove the file.
+ file delete $sndfile
+ }
+ }
+ # Put other platforms here.
+
+ # Setup the globals with reference to the
+ # server, which is assumed to be working.
+ # Since we have options to alter this with
+ # menu items, there probably needs to be
+ # some way to reload all this. But we need
+ # to know how to delete the existing menu
+ # entries to do that.
+ setup_globals
+ create_radio_menu_from_list inputtype
+ create_radio_menu_from_list outputtype
+ create_radio_menu_from_list voice
+ create_radio_menu_from_list audioformat
+
+ # Note, at the moment voices holds locales,
+ # gender, and voice type
+
+ # At the moment this is just diagnostic:
+ ## add_message [ join $voices "\n" ]
+ # it tells us we have a basically working
+ # system and the list of voices has been
+ # picked up and manipulated correctly.
+ # So it is commented out now.
+}
+
+
diff --git a/lib/marytts-5.2.1/doc/examples/client/texttospeechdemo.html b/lib/marytts-5.2.1/doc/examples/client/texttospeechdemo.html
new file mode 100644
index 0000000..e788cf5
--- /dev/null
+++ b/lib/marytts-5.2.1/doc/examples/client/texttospeechdemo.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+