The EULER kernel has been designed so as to make the use and customization of EULER as easy as possible for non specialists. More specifically, EULER exhibits four basic features.
Text-to-speech conversion is generally performed in a serie of steps (typically: text preprocessing, morpho-syntactic analysis, phonetization and speech signal synthesis). In EULER, each processing step is called a module and is implemented as a DLL (dynamically linked library). Modules are defined in the initialization file, by declaring their symbolic name and associating it with the corresponding DLL file name (with optional relative or absolute path; relative paths are given from the directory of the main application) and a set of initialization arguments. Arguments are typically used to specify database file names. The use of DLLs for EULER modules is a very specific feature of EULER. It makes the use and customization of EULER as easy as possible, since no recompilation or linking is needed for adding, replacing, or suppressing modules.
An EULER system is defined as a
sequence of modules in the EULER initialization file (see
customization). If you want an application to be able to produce
various languages, voices, or speaking styles, you need to declare
several systems. Modules (and databases) can be shared between
systems (only the MBROLA synthesizer still needs to be duplicated for
each new system; this will change in the future).
The EULER kernel lets the calling application switch between systems at run-time.
NB: The efficient module sharing capabilities of EULER make it possible to minimize the memory space needed to use multiple TTS systems simulaneously, since shared modules and databases are only instanciated once.
All modules in a TTS system need to acces
(i.e., read/write) shared data in a common workspace. For example,
the preprocessor isolates all words from the input text, the
morpho-syntactic analyzer assigns a part-of-speech tag to each word,
the phonetizer produces the phonetic transcription for each word
according its part-of-speech tag, and so on until the synthesis
module finally produces a speech signal. A classical software
engineering problem for such sequentially embedded systems is that of
data comunication between modules. The EULER kernel provides a
unified data structure (and corresponding data management methods)
for all modules in a system : the multi-layer container (MLC).
Every piece of data stored in the MLC is called an item. Items are simple C++ objects. The multi-layer container is composed of a set of layers containing items. Each layer contains only one type of item, typically one type of language unit used in natural language processing: text, utterance, word, grammar unit, syllable, phoneme, prosodic feature, etc.
Because there is usually a correspondence between data items in several layers for a natural language processing application (see the figure below), the MLC also provides a unified way to defining links between any couple of items in different layers. By following links from a given item, modules can examine several layers of the MLC simultaneously.
EULER was designed to let TTS developers create their own EULER modules or databases. It also encourages them to make these new modules publicly available, by legally protecting their contributions through the EULER license. This document organizes the general transfer and usage rights of EULER. It makes it possible to developers who do not wish to release their modules as free GNU components to restrain the transfer and usage rights for their modules or databases to non-commercial, non military usage.
In order to ensure that EULER users are aware of the transfer and usage conditions on the software components they are using, the EULER kernel has been designed in such a way that an EULER disclaimer needs to be launched by the application, and accepted by its users, before EULER can start.
The EULER disclaimer is itself a DLL. It is the only EULER component whose source code is not provided.
To use the EULER kernel in your application, you need to instanciate:
Then you need to initialize:
You also need to run special methods provided by the disclaimer DLL (DisclaimerCreate and DisclaimerSetCallBack), which will launch the EULER disclaimer to show the permissions for using the modules and databases mentioned in the current initialization file(s).
After this instanciation and initialization stage, you have to create a run-time loop. Inside this loop, you have to lauch the run() method of your instance of CSystem and empty your instance of CMlc (because it will be filled by modules in each pass through the loop). Each call to the run() method of the CSystem object will read a sentence from the input text file (specified via the instance of CmdLine) and synthesize it. The loop should stop when this method returns false, which means that synthesis of the input text has been completed.
All EULER modules launch an exception when an error is found. An EULER-based application should therefore enable exception handling (with a simple C++ try...catch).
Take a look at the demo application files: euler\apps\cmdeuler\cmdeuler.cpp (the simplest possible application) or euler\apps\wineuler\eulerbar.cpp and euler\apps\wineuler\eulerbar.h (the basis of the wineuler application)
You may also take a look at the EULER reference guide for further details.
Copyright © 1999 TCTS LAB, Faculté Polytechnique de Mons, Belgium