Home | History | Annotate | Download | only in intros
      1 <h2 id="overview">Overview</h2>
      2 
      3 <p>Chrome provides native support for speech on Windows (using SAPI
      4 5), Mac OS X, and Chrome OS, using speech synthesis capabilities
      5 provided by the operating system. On all platforms, the user can
      6 install extensions that register themselves as alternative speech
      7 engines.</p>
      8 
      9 <h2 id="generating_speech">Generating speech</h2>
     10 
     11 <p>Call <code>speak()</code> from your extension or
     12 Chrome App to speak. For example:</p>
     13 
     14 <pre>chrome.tts.speak('Hello, world.');</pre>
     15 
     16 <p>To stop speaking immediately, just call <code>stop()</code>:
     17 
     18 <pre>chrome.tts.stop();</pre>
     19 
     20 <p>You can provide options that control various properties of the speech,
     21 such as its rate, pitch, and more. For example:</p>
     22 
     23 <pre>chrome.tts.speak('Hello, world.', {'rate': 2.0});</pre>
     24 
     25 <p>It's also a good idea to specify the language so that a synthesizer
     26 supporting that language (and regional dialect, if applicable) is chosen.</p>
     27 
     28 <pre>chrome.tts.speak(
     29     'Hello, world.', {'lang': 'en-US', 'rate': 2.0});</pre>
     30 
     31 <p>By default, each call to <code>speak()</code> interrupts any
     32 ongoing speech and speaks immediately. To determine if a call would be
     33 interrupting anything, you can call <code>isSpeaking()</code>.  In
     34 addition, you can use the <code>enqueue</code> option to cause this
     35 utterance to be added to a queue of utterances that will be spoken
     36 when the current utterance has finished.</p>
     37 
     38 <pre>chrome.tts.speak(
     39     'Speak this first.');
     40 chrome.tts.speak(
     41     'Speak this next, when the first sentence is done.', {'enqueue': true});
     42 </pre>
     43 
     44 <p>A complete description of all options can be found in the
     45 $ref:tts.speak below.
     46 Not all speech engines will support all options.</p>
     47 
     48 <p>To catch errors and make sure you're calling <code>speak()</code>
     49 correctly, pass a callback function that takes no arguments. Inside
     50 the callback, check
     51 $ref:runtime.lastError
     52 to see if there were any errors.</p>
     53 
     54 <pre>chrome.tts.speak(
     55     utterance,
     56     options,
     57     function() {
     58       if (chrome.runtime.lastError) {
     59         console.log('Error: ' + chrome.runtime.lastError.message);
     60       }
     61     });</pre>
     62 
     63 <p>The callback returns right away, before the engine has started
     64 generating speech. The purpose of the callback is to alert you to
     65 syntax errors in your use of the TTS API, not to catch all possible
     66 errors that might occur in the process of synthesizing and outputting
     67 speech. To catch these errors too, you need to use an event listener,
     68 described below.</p>
     69 
     70 <h2 id="events">Listening to events</h2>
     71 
     72 <p>To get more real-time information about the status of synthesized speech,
     73 pass an event listener in the options to <code>speak()</code>, like this:</p>
     74 
     75 <pre>chrome.tts.speak(
     76     utterance,
     77     {
     78       onEvent: function(event) {
     79         console.log('Event ' + event.type ' at position ' + event.charIndex);
     80         if (event.type == 'error') {
     81           console.log('Error: ' + event.errorMessage);
     82         }
     83       }
     84     },
     85     callback);</pre>
     86 
     87 <p>Each event includes an event type, the character index of the current
     88 speech relative to the utterance, and for error events, an optional
     89 error message. The event types are:</p>
     90 
     91 <ul>
     92   <li><code>'start'</code>: The engine has started speaking the utterance.
     93   <li><code>'word'</code>: A word boundary was reached. Use
     94           <code>event.charIndex</code> to determine the current speech
     95           position.
     96   <li><code>'sentence'</code>: A sentence boundary was reached. Use
     97           <code>event.charIndex</code> to determine the current speech
     98           position.
     99   <li><code>'marker'</code>: An SSML marker was reached. Use
    100           <code>event.charIndex</code> to determine the current speech
    101           position.
    102   <li><code>'end'</code>: The engine has finished speaking the utterance.
    103   <li><code>'interrupted'</code>: This utterance was interrupted by another
    104           call to <code>speak()</code> or <code>stop()</code> and did not
    105           finish.
    106   <li><code>'cancelled'</code>: This utterance was queued, but then
    107           cancelled by another call to <code>speak()</code> or
    108           <code>stop()</code> and never began to speak at all.
    109   <li><code>'error'</code>: An engine-specific error occurred and
    110           this utterance cannot be spoken.
    111           Check <code>event.errorMessage</code> for details.
    112 </ul>
    113 
    114 <p>Four of the event types&mdash;<code>'end'</code>, <code>'interrupted'</code>,
    115 <code>'cancelled'</code>, and <code>'error'</code>&mdash;are <i>final</i>.
    116 After one of those events is received, this utterance will no longer
    117 speak and no new events from this utterance will be received.</p>
    118 
    119 <p>Some voices may not support all event types, and some voices may not
    120 send any events at all. If you do not want to use a voice unless it sends
    121 certain events, pass the events you require in the
    122 <code>requiredEventTypes</code> member of the options object, or use
    123 <code>getVoices()</code> to choose a voice that meets your requirements.
    124 Both are documented below.</p>
    125 
    126 <h2 id="ssml">SSML markup</h2>
    127 
    128 <p>Utterances used in this API may include markup using the
    129 <a href="http://www.w3.org/TR/speech-synthesis">Speech Synthesis Markup
    130 Language (SSML)</a>. If you use SSML, the first argument to
    131 <code>speak()</code> should be a complete SSML document with an XML
    132 header and a top-level <code>&lt;speak&gt;</code> tag, not a document
    133 fragment.</p>
    134 
    135 <p>For example:</p>
    136 
    137 <pre>chrome.tts.speak(
    138     '&lt;?xml version="1.0"?&gt;' +
    139     '&lt;speak&gt;' +
    140     '  The &lt;emphasis&gt;second&lt;/emphasis&gt; ' +
    141     '  word of this sentence was emphasized.' +
    142     '&lt;/speak&gt;');</pre>
    143 
    144 <p>Not all speech engines will support all SSML tags, and some may not support
    145 SSML at all, but all engines are required to ignore any SSML they don't
    146 support and to still speak the underlying text.</p>
    147 
    148 <h2 id="choosing_voice">Choosing a voice</h2>
    149 
    150 <p>By default, Chrome chooses the most appropriate voice for each
    151 utterance you want to speak, based on the language and gender. On most
    152 Windows, Mac OS X, and Chrome OS systems, speech synthesis provided by
    153 the operating system should be able to speak any text in at least one
    154 language. Some users may have a variety of voices available, though,
    155 from their operating system and from speech engines implemented by other
    156 Chrome extensions. In those cases, you can implement custom code to choose
    157 the appropriate voice, or to present the user with a list of choices.</p>
    158 
    159 <p>To get a list of all voices, call <code>getVoices()</code> and pass it
    160 a function that receives an array of <code>TtsVoice</code> objects as its
    161 argument:</p>
    162 
    163 <pre>chrome.tts.getVoices(
    164     function(voices) {
    165       for (var i = 0; i < voices.length; i++) {
    166         console.log('Voice ' + i + ':');
    167         console.log('  name: ' + voices[i].voiceName);
    168         console.log('  lang: ' + voices[i].lang);
    169         console.log('  gender: ' + voices[i].gender);
    170         console.log('  extension id: ' + voices[i].extensionId);
    171         console.log('  event types: ' + voices[i].eventTypes);
    172       }
    173     });</pre>
    174