title: How to programmatically send a unix socket command to a system server autospawned by browser or convert JavaScript to C++ souce code for Chromium?
body: <p>Presently the implementation of the <a href="https://w3c.github.io/speech-api/webspeechapi.html" rel="nofollow noreferrer">Web Speech API Specification</a> by <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=795371" rel="nofollow noreferrer">Chromium</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1425523" rel="nofollow noreferrer">Firefox</a> does not support parsing <a href="https://www.w3.org/TR/2010/REC-speech-synthesis11-20100907/" rel="nofollow noreferrer">Speech Synthesis Markup Language</a> (SSML) when SSML is set at <code>text</code> property of <a href="https://w3c.github.io/speech-api/speechapi.html#utterance-attributes" rel="nofollow noreferrer"><code>SpeechSyntheisUtterance</code></a> instance and passed to <a href="https://w3c.github.io/speech-api/webspeechapi.html#dfn-ttsspeak" rel="nofollow noreferrer"><code>window.speechSynthesis.speak()</code></a> call; see <a href="https://lists.w3.org/Archives/Public/www-voice/2017OctDec/0000.html" rel="nofollow noreferrer">SSML parsing implementation at browsers</a>; <a href="https://lists.w3.org/Archives/Public/public-speech-api/2017Dec/0000.html" rel="nofollow noreferrer">5.2.3 SpeechSynthesisUtterance Attributes</a>;  <a href="https://askubuntu.com/questions/991314/how-to-set-options-of-commands-called-by-browser">How to set options of commands called by browser?</a>.</p>
  
  <p>Chromium source code for the unix socket connect to <a href="https://devel.freebsoft.org/doc/speechd/speech-dispatcher.html" rel="nofollow noreferrer"><code>speech-dispatcher</code></a> connection appears to be at <a href="https://cs.chromium.org/chromium/src/chrome/browser/speech/tts_linux.cc?ssfr=1&amp;l=119" rel="nofollow noreferrer">/src/chrome/browser/speech/tts_linux.cc</a></p>
  
  <pre><code>  {
      // spd_open has memory leaks which are hard to suppress.
      // http://crbug.com/317360
      ANNOTATE_SCOPED_MEMORY_LEAK;
      conn_ = libspeechd_loader_.spd_open(
          "chrome", "extension_api", NULL, SPD_MODE_THREADED);
    }
  </code></pre>
  
  <p>which appears to be reflected at <code>/run/user/1000/speech-dispatcher/log</code>  </p>
  
  <pre><code>speechd: Updating client specific settings "linux:chrome:extension_api"
  </code></pre>
  
  <p>Chromium source code at <a href="https://cs.chromium.org/chromium/src/third_party/speech-dispatcher/libspeechd.h?q=SSML&amp;dr=CSs&amp;l=62" rel="nofollow noreferrer">/src/third_party/speech-dispatcher/libspeechd.h</a></p>
  
  <p>appears to define the <code>SSML_DATA_MODE</code> described at <code>speech-dispatcher</code> documentation</p>
  
  <p>The <a href="https://devel.freebsoft.org/doc/speechd/speech-dispatcher.html" rel="nofollow noreferrer"><code>speech-dispatcher</code></a> documentation states that the user configuration file can be used to set parameters for specific clients </p>
  
  <blockquote>
    <p><strong>4.1.6 Parameter Settings Commands</strong></p>
    
    <p>The following parameter setting commands are available. For
    configuration and history clients there are also functions for setting
    the value for some other connection and for all connections. They are
    listed separately below.</p>
    
    <p>C API function: <code>int spd_set_data_mode(SPDConnection *connection,
    SPDDataMode mode)</code> Set Speech Dispatcher data mode. Currently, plain
    text and SSML are supported. SSML is especially useful if you want to
    use index marks or include changes of voice parameters in the text.</p>
    
    <p>mode is the requested data mode: <code>SPD_DATA_TEXT</code> or <code>SPD_DATA_SSML</code>. </p>
  </blockquote>
  
  <p><code>SPD_DATA_SSML</code> is not set to <code>on</code> at the establishment of the <a href="https://devel.freebsoft.org/doc/speechd/ssip.html#Top" rel="nofollow noreferrer">SSIP</a> connection from Chromium to <code>speech-dispatcher</code>, for example as demonstrated by @xmash at <a href="https://stackoverflow.com/questions/14880234/how-to-use-index-marks-in-speech-dispatcher/14896544#14896544">How to use Index Marks in &quot;speech-dispatcher&quot;?</a></p>
  
  <pre><code>spd_execute_command_wo_mutex( m_connection, "SET SELF SSML_MODE on" );
  </code></pre>
  
  <p>nor is it possible to pass options to the default speech synthesis module, <code>m</code> for <a href="http://espeak.sourceforge.net/" rel="nofollow noreferrer"><code>espeak</code></a> or <code>-x</code> for <a href="https://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#spd_002dsay" rel="nofollow noreferrer"><code>spd-say</code></a>.</p>
  
  <p>With <code>LogLevel</code> set to <code>4</code> or <code>5</code> <code>/run/user/1000/speech-dispatcher/log</code> lists the communication between Chromium (client) and <code>speech-dispatcher</code></p>
  
  <pre><code>speechd:    Module set parameters
  </code></pre>
  
  <p>(server) which can also be viewed at <code>stdout</code> using the <code>PID</code> within <code>/run/user/1000/speech-dispatcher/pid</code> and <code>strace</code>, see <a href="https://unix.stackexchange.com/a/1907">Is there a way to intercept interprocess communication in Unix/Linux?</a></p>
  
  <pre><code>$ sudo strace -ewrite -p $PID
  
  write(22, "216 OK OUTPUT MODULE SET\r\n", 26) = 26
  </code></pre>
  
  <p>There does not appear to be an option to set SSML parsing to on from either <code>speechd.conf</code> or <code>espeak.conf</code> following running</p>
  
  <pre><code>$ spd-conf -u
  </code></pre>
  
  <p>While attempting to parse SSML using JavaScript at <a href="https://github.com/guest271314/SpeechSynthesisSSMLParser" rel="nofollow noreferrer">SpeechSynthesisSSMLParser</a> encountered a <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=797624" rel="nofollow noreferrer">bug</a> at Chromium when trying to parse <code>&lt;break&gt;</code> element, where it is not clear whether <code>spd-say</code> is called or the default output module, e.g., <code>espeak</code> is run when <code>window.speechSynthesis.speak()</code> is called by the browser; see <a href="https://cs.chromium.org/chromium/src/out/Debug/gen/library_loaders/libspeechd.h" rel="nofollow noreferrer">/src/out/Debug/gen/library_loaders/libspeechd.h</a>.</p>
  
  <p>Created an approach to use <code>php</code> to call <code>espeak</code> using <code>shell_exec()</code> which returns the expected result</p>
  
  <pre><code>// JavaScript
  async function SSMLStream({ssml="", options=""}) {
    const fd = new FormData();
    fd.append("ssml", ssml);
    fd.append("options", options);
  
    const request = await fetch("speak.php", {method:"POST", body:fd});
    const response = await request.arrayBuffer();
    return response;
  }
  
  let ssml = `&lt;speak version="1.0" xml:lang="en-US"&gt; 
               Here are &lt;say-as interpret-as="characters"&gt;SSML&lt;/say-as&gt; samples. 
               Hello universe, how are you today? 
               Try a date: &lt;say-as interpret-as="date" format="dmy" detail="1"&gt;10-9-1960&lt;/say-as&gt; 
               This is a &lt;break time="2500ms" /&gt; 2.5 second pause. 
               This is a &lt;break /&gt; sentence break&lt;/prosody&gt; &lt;break /&gt;
               &lt;voice name="us-en+f3" rate="x-slow" pitch="0.25"&gt;espeak using&lt;/voice&gt; 
               PHP and &lt;voice name="en-us+f2"&gt; &lt;sub alias="JavaScript"&gt;JS&lt;/sub&gt;&lt;/voice&gt;
             &lt;/speak&gt;`;
  
  SSMLStream({ssml, options:"-v en-us+f1"})
  .then(async(data) =&gt; {
  
      let context = new AudioContext();
      let source = context.createBufferSource();
      source.buffer = await context.decodeAudioData(data);
      source.connect(context.destination);
      source.start()
  
  })
  // PHP
  &lt;?php 
    if(isset($_POST["ssml"])) {
      header("Content-Type: audio/x-wav");
      $options = $_POST["options"];
      echo shell_exec("espeak -m --stdout " . $options . " '" . $_POST["ssml"] . "'");
    };
  </code></pre>
  
  <p>Requirement:</p>
  
  <p>Parse the SSML set at text property of <code>SpeechSynthesisUtterance</code> using the existing capabilities of the native program called to convert text to speech by <code>speech-dispatcher</code> output module using default browser capabilities.</p>
  
  <p>Questions:</p>
  
  <p>1) How to programmatically listen for the the <code>PID</code> when <code>speech-dispatcher --spawn-communication-method unix_socket --socket-path /run/user/1000/speech-dispatcher/speechd.sock</code> is called by Chromium browser, then call <code>spd_execute_command_wo_mutex</code> or <code>spd_execute_command_wo_mutex</code> to the <code>speech-dispatcher</code> server using the established unix socket connection as client (Chromium) with <code>"SET SELF SSML_MODE on"</code> as second parameter to turn on SSML parsing for all calls to <code>window.speechSynthesis.speak()</code> at Chromium browser?</p>
  
  <p>2) If 1) is not possible, what needs to be adjusted at Chromium source code to turn on SSML parsing for the unix socket connection, e.g., at <a href="https://cs.chromium.org/chromium/src/tools/generate_library_loader/generate_library_loader.py?q=tools/generate_library_loader/generate_library_loader.py&amp;ct=rc&amp;cd=1&amp;dr" rel="nofollow noreferrer">tools/generate_library_loader/generate_library_loader.py</a>?</p>
  
  <p>3) If 1) and 2) are not viable options, how to convert the JavaScript and PHP code into C++ code in the format used by Chromium browser; and how to build Chromium with the patch included; for the purpose of exposing a <code>speak</code> function with accepts parameters which can be passed to a native speech synthesis application where SSML is parsed and the resulting audio output is returned to JavaScript caller as an <code>ArrayBuffer</code>?</p>
  
  <p>4) If options other than 1), 2) and 3) are available and capable of meeting requirement how can we resolve the inquiry programmatically; without having to start a local server manually at <code>terminal</code>?</p>