Home | History | Annotate | Download | only in intros
      1 <h2 id="overview">Overview</h2>
      2 
      3 <p>An extension can register itself as a speech engine. By doing so, it
      4 can intercept some or all calls to functions such as
      5 $ref:tts.speak and
      6 $ref:tts.stop
      7 and provide an alternate implementation.
      8 Extensions are free to use any available web technology
      9 to provide speech, including streaming audio from a server, HTML5 audio,
     10 Native Client, or Flash. An extension could even do something different
     11 with the utterances, like display closed captions in a pop-up window or
     12 send them as log messages to a remote server.</p>
     13 
     14 <h2 id="manifest">Manifest</h2>
     15 
     16 <p>To implement a TTS engine, an extension must
     17 declare the "ttsEngine" permission and then declare all voices
     18 it provides in the extension manifest, like this:</p>
     19 
     20 <pre>{
     21   "name": "My TTS Engine",
     22   "version": "1.0",
     23   <b>"permissions": ["ttsEngine"],
     24   "tts_engine": {
     25     "voices": [
     26       {
     27         "voice_name": "Alice",
     28         "lang": "en-US",
     29         "gender": "female",
     30         "event_types": ["start", "marker", "end"]
     31       },
     32       {
     33         "voice_name": "Pat",
     34         "lang": "en-US",
     35         "event_types": ["end"]
     36       }
     37     ]
     38   },</b>
     39   "background": {
     40     "page": "background.html",
     41     "persistent": false
     42   }
     43 }</pre>
     44 
     45 <p>An extension can specify any number of voices.</p>
     46 
     47 <p>The <code>voice_name</code> parameter is required. The name should be
     48 descriptive enough that it identifies the name of the voice and the
     49 engine used. In the unlikely event that two extensions register voices
     50 with the same name, a client can specify the ID of the extension that
     51 should do the synthesis.</p>
     52 
     53 <p>The <code>gender</code> parameter is optional. If your voice corresponds
     54 to a male or female voice, you can use this parameter to help clients
     55 choose the most appropriate voice for their application.</p>
     56 
     57 <p>The <code>lang</code> parameter is optional, but highly recommended.
     58 Almost always, a voice can synthesize speech in just a single language.
     59 When an engine supports more than one language, it can easily register a
     60 separate voice for each language. Under rare circumstances where a single
     61 voice can handle more than one language, it's easiest to just list two
     62 separate voices and handle them using the same logic internally. However,
     63 if you want to create a voice that will handle utterances in any language,
     64 leave out the <code>lang</code> parameter from your extension's manifest.</p>
     65 
     66 <p>Finally, the <code>event_types</code> parameter is required if the engine can
     67 send events to update the client on the progress of speech synthesis.
     68 At a minimum, supporting the <code>'end'</code> event type to indicate
     69 when speech is finished is highly recommended, otherwise Chrome cannot
     70 schedule queued utterances.</p>
     71 
     72 <p class="note">
     73 <strong>Note:</strong> If your TTS engine does not support
     74 the <code>'end'</code> event type, Chrome cannot queue utterances
     75 because it has no way of knowing when your utterance has finished. To
     76 help mitigate this, Chrome passes an additional boolean <code>enqueue</code>
     77 option to your engine's onSpeak handler, giving you the option of
     78 implementing your own queueing.  This is discouraged because then
     79 clients are unable to queue utterances that should get spoken by different
     80 speech engines.</p>
     81 
     82 <p>The possible event types that you can send correspond to the event types
     83 that the <code>speak()</code> method receives:</p>
     84 
     85 <ul>
     86   <li><code>'start'</code>: The engine has started speaking the utterance.
     87   <li><code>'word'</code>: A word boundary was reached. Use
     88           <code>event.charIndex</code> to determine the current speech
     89           position.
     90   <li><code>'sentence'</code>: A sentence boundary was reached. Use
     91           <code>event.charIndex</code> to determine the current speech
     92           position.
     93   <li><code>'marker'</code>: An SSML marker was reached. Use
     94           <code>event.charIndex</code> to determine the current speech
     95           position.
     96   <li><code>'end'</code>: The engine has finished speaking the utterance.
     97   <li><code>'error'</code>: An engine-specific error occurred and
     98           this utterance cannot be spoken.
     99           Pass more information in <code>event.errorMessage</code>.
    100 </ul>
    101 
    102 <p>The <code>'interrupted'</code> and <code>'cancelled'</code> events are
    103 not sent by the speech engine; they are generated automatically by Chrome.</p>
    104 
    105 <p>Text-to-speech clients can get the voice information from your
    106 extension's manifest by calling
    107 $ref:tts.getVoices,
    108 assuming you've registered speech event listeners as described below.</p>
    109 
    110 <h2 id="handling_speech_events">Handling speech events</h2>
    111 
    112 <p>To generate speech at the request of clients, your extension must
    113 register listeners for both <code>onSpeak</code> and <code>onStop</code>,
    114 like this:</p>
    115 
    116 <pre>var speakListener = function(utterance, options, sendTtsEvent) {
    117   sendTtsEvent({'event_type': 'start', 'charIndex': 0})
    118 
    119   // (start speaking)
    120 
    121   sendTtsEvent({'event_type': 'end', 'charIndex': utterance.length})
    122 };
    123 
    124 var stopListener = function() {
    125   // (stop all speech)
    126 };
    127 
    128 chrome.ttsEngine.onSpeak.addListener(speakListener);
    129 chrome.ttsEngine.onStop.addListener(stopListener);</pre>
    130 
    131 <p class="warning">
    132 <b>Important:</b>
    133 If your extension does not register listeners for both
    134 <code>onSpeak</code> and <code>onStop</code>, it will not intercept any
    135 speech calls, regardless of what is in the manifest.</p>
    136 
    137 <p>The decision of whether or not to send a given speech request to an
    138 extension is based solely on whether the extension supports the given voice
    139 parameters in its manifest and has registered listeners
    140 for <code>onSpeak</code> and <code>onStop</code>. In other words,
    141 there's no way for an extension to receive a speech request and
    142 dynamically decide whether to handle it.</p>
    143