<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

%===================================================================
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_definitions}
\input{common_latex/common_latex_help_format}
%===================================================================

\begin{document}

\begin{labcover}
\labtitle{iSay: Invoking the Linux or OSX Speech Generation Commands from MOOS}
\vspace{0.1in}
\labdate{June 2018}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\labsrc{project-pavlab/appdocs/app\_isay} 
\labtoc{small}
\end{labcover}

\wikidoc{file=IvPTools.ISay}
\wikidoc{auth=mikerb@mit.edu}

%=================================================================
\section{Overview}
%=================================================================
\label{sec_isay}

The \app{iSay} application is a way to invoke the native speech
generation utilities of OSX (the \cmd{say} command) and GNU/Linux (the
\cmd{espeak} command). It may also invoke the \cmd{afplay} commands
available in both OSX and GNU/Linux to play a given wav or mp3 file.
Normally, without MOOS running, one can generate voice from the
command line with these built in commands:

\vspace{0.1in}
\begin{consoleverb}
$ say hello
\end{consoleverb}
\vspace{0.1in}

\noindent 
in OSX, or in GNU/Linux with:

\vspace{0.1in}
\begin{consoleverb}
$ espeak hello
\end{consoleverb}
\vspace{0.1in}

\noindent
When \app{iSay} is running, the same can be accomplished by poking the 
MOOSDB:

\vspace{0.1in}
\begin{consoleverb}
$ uPokeDB SAY_MOOS=hello
\end{consoleverb}
\vspace{0.1in}

\noindent
The advantage being of course that the speech may be generated by an
event in MOOS, e.g. a vehicle returning. The \app{iSay} application
also makes provisions for choosing the voice, the time in between
utterances or in between utterance beginnings, and an utterance
priority if a queue of utterances begins to form due to a backlog of
several utterance requests. The utterance may be either a specified
text of speech, or it may be a sound provide by a named \var{.wav}
file. Presently, if a named \var{.wav} file is not found or if a named
voice is not recognized, no sound will be generated. Future versions
of \app{iSay} may make provisions for fallback sounds in these cases.


%===========================================================
\section{Configuration Parameters for iSay}
%===========================================================

The following parameters are defined for \app{iSay}. A more
detailed description is provided in other parts of this
section. Parameters having default values are indicated.

\vspace{0.15in}
\begin{listing}{Configuration Parameters for \app{iSay}}
\label{lst_params_isay}
\renewcommand{\arraystretch}{1.1}
\begin{longtable}{rp{0.76\textwidth}} 

  \pvar{audio\_dir}: &amp; Names a system directory to be added to path of 
  directories to search for audio files named in a particular utterance
  request. \\ 

  \pvar{default\_rate}: &amp; The speech rate to be used, in words per minute, 
  if left unspecified for a particular utterance request (200). \\

  \pvar{default\_voice}: &amp; The default voice to be used if left 
  unspecified for a particular utterance request. \\

  \pvar{interval\_policy}: &amp; Either \var{"from\_start"} or
  \var{"from\_end"}, indicating whether the interval of time between
  utterances is marked from the start of the previous utterance or the
  end of the previous utterance (\var{"from\_end"}). \\

  \pvar{os\_mode}: &amp; Either \var{"osx} or \var{"linux"} or \var{"both"}. The 
  default is \var{"both"}\\ 
  
  \pvar{min\_utter\_interval}: &amp; The minimum time (in seconds) between
  utterances before a next queued utterance will commence (1.0). \\
  
\end{longtable}
\end{listing}
  

%=================================================================
\section{Publications and Subscriptions of iSay}
%=================================================================
\label{sec_isay_interface}

The interface for \app{iSay}, in terms of publications and
subscriptions, is described below. This same information may also be
obtained from the terminal with:

\vspace{0.1in}
\begin{consoleverb}
 $ iSay --interface or -i
\end{consoleverb}
\vspace{0.05in}

%=================================================================
\subsection{Variables Published by iSay}
\label{sec_isay_pubs}

The only output of \app{iSay} is: 

\begin{packed_itemize}[2]
\item \mvar{APPCAST}: Contains an appcast report identical to the
  terminal output. Appcasts are posted only after an appcast request
  is received from an appcast viewing utility. Section
  \ref{sec_isay_appcast}.
\end{packed_itemize}

%=================================================================
\subsection{Variables Subscribed for by iSay}
\label{sec_uts_subs}

The \app{iSay} application will subscribe for the following
four MOOS variables:

\begin{packed_itemize}[2]
\item \mvar{APPCAST\_REQ}: A request to generate and post a new
  apppcast report, with reporting criteria, and expiration. Section
  \ref{sec_ac_requests}.

\item \mvar{SAY\_MOOS}: A description of an utterance to be made. Section
  \ref{sec_isay_utter}. 

\item \mvar{SAY\_FILTER}: Either \var{"none"}, \var{"hold"}, or
  \var{"ignore"} (\var{"none"}). Section \ref{sec_isay_filter}.

\item \mvar{SAY\_VOLUME}: Either \var{"mute"}, \var{"vsoft"},
  \var{"soft"}, \var{"normal"}, \var{"loud"}, \var{"vlou"}, or a
  number in the range \var{"[0,2]"}.  This will only affect the volume
  of wav files only on MacOS, relative to the prevailing output volume
  on the computer. Text to speech (MacOS,Linux) and wav files on
  Linux, are not affected.

\end{packed_itemize}


%=================================================================
\section{Specifying an Utterance}
%=================================================================
\label{sec_isay_utter}

The \app{iSay} app works by receiving utterance requests through incoming 
MOOS mail via the \mvar{SAY\_MOOS} variable. This mail has the following
format by a couple examples:

\prevgreen
\begin{verbatim}
 SAY_MOOS = "say={hello world}, priority=100, voice=Albert, rate=250, source=henry"
 SAY_MOOS = "file=file.wav"
\end{verbatim}
\postverb

The \var{source} component is optional and by default will be set to a
string comprised of the MOOS community and the MOOS application that
generated the utterance request, separated by a colon. See, for
example, line 24 in Listing \ref{lst_isay_appcast}. This component
provides an opportunity to be more specific about the source, as in
line 25 in the same example.


\vspace{0.1in}
\noindent
The \var{rate} component specifies the speech rate in words per second. The 
default rate is 200. The \var{priority} component specifies the priority 
of the utterence request when the request is pushed onto the priority queue. 
See Section \ref{sec_isay_queue} for more on this.

\vspace{0.1in}
\noindent
The \var{voice} component allows one to request a voice different from
the default voice. The options for this component depend on the
options supported by the OSX \cmd{say} command and the GNU/Linux
\cmd{espeak} command.  These options may be found by typing \var{"say
  -v ?"} on the command line or \var{"espeak --voices"} on the command
line in GNU/Linux.

%=================================================================
\section{The iSay Priority Queue}
%=================================================================
\label{sec_isay_queue}

The \app{iSay} priority queue holds all received utterance requests
before they are eventually popped and processed. The priority queue is
popped (if non-empty) once on each iteration of \app{iSay}, and no
more frequently than the allowed by the setting of
\mvar{min\_utter\_interval} and the time it took to process the system
command of the previous utterance.

\vspace{0.1in}
\noindent
By default, all uttterances have a priority of zero, and are simply
processed first-come first-served. An utterance request may instead be
specified with a higher (or lower) priority to affect the order in
which it is popped from the queue. Requests of equal priority are
processed first-come first-served. A request may also be made with
\var{"top"} priority. These requests go immediatedly to the top of the
priority queue. If multiple top priority requests are received, the
latest one received will be handled first.

%=================================================================
\section{The iSay Filter}
%=================================================================
\label{sec_isay_filter}

The \app{iSay} filter may be set to one of three values. The default
is \pvar{"none"} and all utterances are received and processed
normally. When the filter is set to \pvar{"ignore"}, it's as if the
mute button is hit. Any received utterances will be immediately put on
the queue and any utterances popped from the queue will be handled
according to the normal interval specifications. But the actual system
command to generate the utterance will not be made. When the filter is
set to \pvar{"hold"}, all received utterances will be put in the queue
and nothing will be popped from the queue until the hold is
released. At some point the maximume queue size (100) may be
exceeded.


%=================================================================
\section{Terminal and AppCast Output}
%=================================================================
\label{sec_isay_appcast}

The \app{iSay} application produces some useful information to
the terminal on every iteration of the application. An example is
shown in Listing \ref{lst_isay_appcast} below. This application is also
appcast enabled, meaning its reports are published to the MOOSDB and
viewable from any \app{uMAC} application or \app{pMarineViewer}. See
Section \ref{sec_umac_utils} for more on appcasting and viewing
appcasts.  The counter on the end of line 2 is incremented on each
iteration of \app{iSay}, and serves a bit as a heartbeat
indicator.  The \var{"0/0"} also on line 2 indicates there are no
configuration or run warnings detected.

\vspace{0.1in}
\noindent
The output in the below example comes from the example described in 
Section \ref{sec_isay_example}. 

\vspace{0.1in}
\begin{listing}{Example terminal or appcast output for \app{iSay}}
\label{lst_isay_appcast}
\footnotesize
\begin{verbatim}
  1  ===================================================================
  2  iSay alpha                                                  0/0(96)
  3  ===================================================================
  4  Configuration Parameters:
  5  -------------------------
  6     Default Voice: alex
  7      Default Rate: 200
  8   Max Utter Queue: 100
  9   Min Utter Inter: 1
 10   Interval Policy: from_end
 11  
 12  Status:
 13  -------------------------
 14    Utter Queue Size: 36
 15    Unhandled Audios: 0
 16              Filter: none
 17  
 18  Source              Time  Time  Utterance
 19                      Recd  Post           
 20  ------------------  ----  ----  ---------
 21  alpha:uTimerScript  12.8  13.7  five     
 22  alpha:uTimerScript  1.4   12.1  four     
 23  alpha:uTimerScript  10.0  10.4  five     
 24  alpha:uTimerScript  7.7   8.7   five     
 25  james               1.2   7.1   three    
 26  alpha:uTimerScript  4.4   5.4   five     
 27  alpha:uTimerScript  1.2   3.9   two      
 28  alpha:uTimerScript  1.6   2.2   five     
 29  alpha:uTimerScript  0.7   0.7   one      
 30  
 31  ===================================================================
 32  Most Recent Events (8):
 33  ===================================================================
 34  [14.33]: Utter Rec'd:say={nine}
 35  [13.66]: Say:five
 36  [13.46]: Utter Rec'd:say={eight}
 37  [13.26]: Utter Rec'd:say={seven}
 38  [12.96]: Utter Rec'd:say={six}
 39  [12.76]: Utter Rec'd:say={five},priority=100
 40  [12.66]: Utter Rec'd:say={four}
 41  [12.66]: Utter Rec'd:say={three},source=james
\end{verbatim}
\end{listing}
\normalsize
\vspace{0.1in}

\noindent
The first few lines (4-10) show the configuration settings for
\app{iSay}.  The status of \app{iSay} is shown in Lines 12-16. In this
case the queue is growing fairly quickly (line 14) since the utterance
requests are being received about four times per second, but the
minimum time between utterances is set to be one second (line 9).
Processed utterances are shown in reverse order starting on line
21. This block has a maximum length of ten items, to keep the size of
the AppCast report in check. 

\vspace{0.1in}
\noindent
Recent events are shown in the block beginning on line 34. Events may
be either a received or processed utterance. This block has a maximum
length of eight items, to keep the size of the AppCast report in check.

%=================================================================
\section{A Simple Example}
%=================================================================
\label{sec_isay_example}

The below is a simple example, using the \app{uTimerScript}
application to generate inputs to \app{iSay}. You can try this example
by adding these to blocks to an existing example mission and adding
\app{iSay} and \app{uTimerScript} to the Antler block. The script
should generate spoken utterances of the numbers one through nine
pretty much in sequence except that fives are handled with a high
priority and spoken almost immediately. Since the
\pvar{min\_utterance\_interval} is set to one second, fives are spoke
almost half the time, and the utterance queue also grows fairly
quickly. Try changing this parameter to 0.1 seconds instead and note
the change in behavior.

\vspace{0.1in}
\begin{listing}{A Simple \app{iSay} Example}
\label{lst_isay_example}
\footnotesize
\begin{verbatim}
//------------------------------------------                                    
ProcessConfig = iSay
{
  AppTick   = 4
  CommsTick = 4

  min_utter_interval = 1
  interval_policy    = from_end
  volume             = soft
}

//------------------------------------------                                    
ProcessConfig = uTimerScript
{
  AppTick   = 4
  CommsTick = 4

  paused       = false
  reset_max    = nolimit
  reset_time   = all-posted
  delay_reset  = 0.25

  event        = var=SAY_MOOS, val="say={one}",   time=0.25
  event        = var=SAY_MOOS, val="say={two}",   time=0.5
  event        = var=SAY_MOOS, val="say={three},source=james", time=0.75
  event        = var=SAY_MOOS, val="say={four}",  time=1
  event        = var=SAY_MOOS, val="say={five},priority=100",  time=1.25
  event        = var=SAY_MOOS, val="say={six}",   time=1.5
  event        = var=SAY_MOOS, val="say={seven}", time=1.75
  event        = var=SAY_MOOS, val="say={eight}", time=2
  event        = var=SAY_MOOS, val="say={nine}",  time=2.25
}
\end{verbatim}
\end{listing}
\normalsize

\end{document}

</pre></body></html>