speech-dispatcher: Output Module Functions
5.2.5 Output Module Functions
-----------------------------
-- Output Module Functions: int module_speak (char *data, size_t bytes,
EMessageType msgtype)
This is the function where the actual speech output is produced.
It is called every time Speech Dispatcher decides to send a message
to synthesis. The data of length BYTES are passed in a NULL
terminated string DATA. The argument MSGTYPE defines what type of
message it is (different types should be handled differently, if
the synthesizer supports it).
Each output module should take care of setting the output device to
the parameters from msg_settings (defined in module_utils.h) (See
SPDMsgSettings in 'module_utils.h'). However, it is not an error
if some of these values are ignored. At least rate, pitch and
language should be set correctly.
Speed and pitch are values between -100 and 100 included. 0 is the
default value that represents normal speech flow. So -100 is the
slowest (or lowest) and +100 is the fastest (or highest) speech.
The language parameter is given as a null-terminated string
containing the name of the language according to RFC 1766 (en, cs,
fr, ...). If the requested language is not supported by this
synthesizer, it's ok to abort and return 0, because that's an error
in user settings.
An easy way to set the parameters is using the UPDATE_PARAMETER()
and UPDATE_STRING_PARAMETER() macros. Module Utils Functions
and Macros.
Example from festival:
UPDATE_STRING_PARAMETER(language, festival_set_language);
UPDATE_PARAMETER(voice, festival_set_voice);
UPDATE_PARAMETER(rate, festival_set_rate);
UPDATE_PARAMETER(pitch, festival_set_pitch);
UPDATE_PARAMETER(punctuation_mode, festival_set_punctuation_mode);
UPDATE_PARAMETER(cap_let_recogn, festival_set_cap_let_recogn);
This function should return 0 if it fails and 1 if the delivery to
the synthesizer is successful. It should return immediately,
because otherwise, it would block stopping, priority handling and
other important things in Speech Dispatcher.
If there is a need to stay longer, you should create a separate
thread or process. This is for example the case of some software
synthesizers which use a blocking function (eg. spd_audio_play) or
hardware devices that have to send data to output modules at some
particular speed. Note that if you use threads for this purpose,
you have to set them to ignore all signals. The simplest way to do
this is to call 'set_speaking_thread_parameters()' which is defined
in module_utils.c. Call it at the beginning of the thread code.
-- Output module function: int module_stop (void)
This function should stop the synthesis of the currently spoken
message immediately and throw away the rest of the message.
This function should return immediately. Speech Dispatcher will
not send another command until module_report_event_stop() is
called. Note that you cannot call module_report_event_stop() from
within the call to module_stop(). The best thing to do is emit the
stop event from another thread.
It should return 0 on success, -1 otherwise.
-- Output module function: size_t module_pause (void)
This function should stop speaking on the synthesizer (or sending
data to soundcard) just after sending an '__spd_' index mark so
that Speech Dispatcher knows the position of stop.
The pause can wait for a short time until an index mark is reached.
However, if it's not possible to determine the exact position, this
function should have the same effect as 'module_stop'.
This function should return immediately. Speech Dispatcher will
not send another command until module_report_event_pause() is
called. Note that you cannot call module_report_event_pause() from
within the call to module_pause(). The best thing to do is emit
the pause event from another thread.
For some software synthesizers, the desired effect can be archieved
in this way: When 'module_speak()' is called, you execute a
separate process and pass it the requested message. This process
cuts the message into sentences and then runs in a loop and sends
the pieces to synthesis. If a signal arrives from
'module_pause()', you set a flag and stop the loop at the point
where next piece of text would be synthesized.
It's not an error if this function is called when the device is not
speaking. In this case, it should return 0.
Note there is no module_resume() function. The semantics of
'module_pause()' is the same as 'module_stop()' except that your
module should stop after reaching a '__spd_' index mark. Just like
'module_stop()', it should discard the rest of the message after
pausing. On the next 'module_speak()' call, Speech Dispatcher will
resend the rest of the message after the index mark.