@c $Id$
@node TTS Servers
@chapter TTS Servers

Emacspeak produces spoken output by communicating with one of many
speech servers.  This section documents the communication protocol
between the client application i.e. Emacspeak, and the Text to Speech
(@acronym{TTS}) server. This section is primarily intended for
developers wishing to:

@itemize @bullet
@item
Create new speech servers that comply with this communication protocol

@item
Developers of other client applications who wish to use the various
Emacspeak speech servers.
@end itemize

For additional notes on how to log and view @acronym{TTS} server
commands when developing a speech server, see
@url{http://emacspeak.blogspot.com/2015/04/howto-log-speech-server-output-to-aid.html}.

@section High-level Overview

The @acronym{TTS} server reads commands from standard input.
Script @strong{speech-server} can be used to cause a @acronym{TTS}
server to communicate via a @acronym{TCP} socket. Speech server
commands are used by the client application to make specific requests
of the server; the server listens for these requests in a non-blocking
read-eval-print (REPL)  loop and executes requests as they become available. Requests can
be classified as follows:

@itemize @bullet
@item
Commands that send text to be spoken.

@item
Commands that set @strong{state} of the @acronym{TTS} server.
@end itemize

All commands are of the form

@example
commandWord @{arguments@}
@end example

The braces are optional if the command argument contains no white
space.  The speech server maintains a @strong{current state} that
determines various characteristics of spoken output such as speech
rate, punctuations mode etc. (see set of commands that manipulate
speech state for complete list).  The client application
@strong{queues} The text and non-speech audio output to be produced
before asking the server to @strong{dispatch} the set of queued
requests, i.e. start producing output.

Once the server has been asked to produce output, it removes items
from the front of the queue, sends the requisite commands to the
underlying @acronym{TTS} engine, and waits for the engine to
acknowledge that the request has been completely processed. This is a
non-blocking operation, i.e., if the client application generates
additional requests, these are processed @strong{immediately}.

The above design allows the Emacspeak @acronym{TTS} server to be
@strong{highly} responsive; Client applications can queue large
amounts of text (typically queued a clause at a time to achieve the
best prosody), ask the @acronym{TTS} server to start speaking, and
interrupt the spoken output at any time.

@subsection Commands That Queue Output.

This section documents commands that either produce spoken output, or
queue output to be produced on demand.  Commands that place the
request on the queue are clearly marked.

@example
version
@end example

Speaks the @strong{version} of the @acronym{TTS} engine. Produces
output immediately.

@example
tts_say text
@end example

Speaks the specified @strong{text} immediately. The text is not
pre-processed in any way, contrast this with the primary way of
speaking text which is to queue text before asking the server to
process the queue.

Note that this command needs to handle the special syntax for morpheme
boundaries @samp{[*]}.  The @samp{[*]} syntax is specific to the
Dectalk family of synthesizers; servers for other @acronym{TTS}
engines need to map this pattern to the engine-specific code for each
engine. As an example, see @file{servers/outloud} A morpheme boundary
results in synthesizing compound words such as @strong{left bracket}
with the right intonation; using a space would result in that phrase
being synthesized as two separate words.

@example
l c
@end example

Speak @strong{c} a single character, as a letter.  The character is
spoken immediately. This command uses the @acronym{TTS} engine's
capability to speak a single character with the ability to flush
speech @strong{immediately}.  Client applications wishing to produce
character-at-a-time output, e.g., when providing character echo during
keyboard input should use this command.

@example
d
@end example

This command is used to @strong{dispatch} all queued requests.  It was
renamed to a single character command (like many of the commonly used
@acronym{TTS} server commands) to work more effectively over slow
(9600) dialup lines.  The effect of calling this command is for the
@acronym{TTS} server to start processing items that have been queued
via earlier requests.

@example
s
@end example

Stop speech @strong{immediately}.  Spoken output is interrupted, and
all pending requests are flushed from the queue.

@example
q text
@end example

Queues text to be spoken. No spoken output is produced until a
@strong{dispatch} request is received via execution of command
@strong{d}.


@example
c codes
@end example

Queues synthesis codes to be sent to the @acronym{TTS} engine.  Codes
are sent to the engine with no further transformation or processing.
The codes are inserted into the output queue and will be dispatched to
the @acronym{TTS} engine at the appropriate point in the output
stream.

@example
a filename
@end example

Cues the audio file identified by filename for playing,
an @code{ogg} file.

@example
p filename
@end example

@strong{dispatch} play the audio file identified by filename for
playing  --- @code{ogg} file.


@example
t freq length
@end example

Queues a tone to be played at the specified frequency and having the
specified length.  Frequency is specified in hertz and length is
specified in milliseconds.

@example
sh duration
@end example

Queues the specified duration of silence. Silence is specified in
milliseconds.

@subsection Commands That Set State

@example
tts_reset
@end example

@strong{Immediately} reset @acronym{TTS} engine to default settings.
Stops all speech and clears the queue.

@example
tts_set_punctuations mode
@end example

Queues setting @acronym{TTS} engine to the specified punctuation
mode. Typically, @acronym{TTS} servers provide at least three modes:

@itemize @bullet
@item
None: Do not speak punctuation characters.

@item
Some: Speak some punctuation characters. Used for English prose.

@item
All: Speak out @strong{all} punctuation characters; useful in
programming modes.
@end itemize

@example
tts_set_speech_rate rate
@end example

@strong{Immediately} change speech rate. The interpretation of this
value is typically engine specific.

@example
tts_set_character_scale factor
@end example

Queues changing the scale factor.  Scale factor applied to speech rate
when speaking individual characters.Thus, setting speech rate to 500
and character scale to 1.2 will cause command @strong{l} to use a
speech rate of @strong{500 * 1.2 = 600}.

@example
tts_split_caps flag
@end example

Queues changing of the state of @strong{split caps} processing.  Turn
this on to speak mixed-case (@acronym{AKA} Camel Case) identifiers.

@example
tts_sync_state punct splitcaps caps rate
@end example

@strong{Immediately} apply the passed settings.

This ensures @strong{atomicity} i.e., all state settings in the TTS
engine happen at one shot. Note that failure to do this might result
in some utterances being spoken with a partially set state.
@itemize @bullet
@item
punct: see tts_set_punctuations

@item
splitcaps: see tts_split_caps

@item
caps: engine specific implementation of capital letter handling

@item
rate: see tts_set_speech_rate
@end itemize

@example
set_next_lang say_it
@end example

@strong{Immediately} switch to the next language on the server,
maintained internally on the TTS server. If say_it is non-nil say the
language change via the TTS.

@example
set_previous_lang say_it
@end example

@strong{Immediately} switch to the previous language on the server,
maintained internally on the TTS server. If say_it is non-nil say the
language change via the TTS.

@example
set_lang language:voice say_it
@end example

@strong{Immediately} switch to the requested language and/or voice,
separated by a colon. Examples

@itemize @bullet
@item
set_lang "en"

@item
set_lang "en:whisper"

@item
set_lang ":whisper"
@end itemize

If say_it is non-nil, speak via the TTS the language and voice
selected.


@example
set_preferred_lang alias lang
@end example

@strong{Immediately} set an alias in the TTS server mapping for
example "en" to "en_GB". This can later be used by set_lang.

