Speech Synthesis

make it talk!

by Frank Taylor

HTML

<input id="textToSpeech" type="text" placeholder="type another message"/>

<label for="textRate">Text Rate</label>
<input id="textRate" min=".1" max="2" step=".05" type="range" value=".8" data-speech="rate" data-val=".8"/>

<label for="textPitch">Text Pitch</label>
<input id="textPitch" min="0" max="2" step=".1" value="0" type="range" data-speech="pitch" data-val="0"/>

<label for="textRate">Volume</label>
<input id="textRate" min=".1" max="1" step=".1" value=".4" type="range" data-speech="volume" data-val=".4"/>

CSS

body {font-family: Helvetica, arial, sans-serif}
input{
    font-size: 2em;
    padding: .25em;
    border: 1px solid #445686;
    color: #333;
}

label {
  font-weight: bold;
  display: block;
  margin: .618em;
}

input {
  width: 80%;
}

input[type="range"] {
  position: relative;
}

input[type="range"]::after {
  content: attr(data-val);
  display: inline-block;
  font-weight: bold;
  position: absolute;
  top: 0;
  right: -2.5ch;
}

Babel + JSX

console.clear();



/**
 * @typedef SpeakerDefaults
 * @type {object}
 * @property  {string} voiceURI voice that the browser uses
 * @property  {Number} volume loudness. Between 0 and 1.0
 * @property  {Number} rate  speed at which words are spoken. Between 0 and 2.
 * @property  {Number} pitch Between 0 and 2
 * @property  {string} lang ISO language
 */

const SpeakerDefaults = {
    voiceURI: 'native',
    volume: .4,
    rate: 0.8,
    pitch: 0.0,
    lang: 'en-EN'
};

/**
 * Class for getting the browser to "talk"
 * @example //Create an instance
 * const mySpeaker = new Speaker();
 * @example //Get it to talk
 * mySpeaker.say('something sooper cool');
 */
class Speaker {
    /** Create an interface for the browser to speak
     * @param  {SpeakerDefaults} defaults=SpeakerDefaults
     * @param  {string} defaults.voiceURI
     * @param  {Number} defaults.volume loudness. Between 0 and 1.0
     * @param  {Number} defaults.rate  speed at which words are spoken. Between 0 and 2.
     * @param  {Number} defaults.pitch Between 0 and 2
     * @param  {string} defaults.lang ISO language
     * 
     */

    constructor(defaults = SpeakerDefaults) {
    	this.defaults = Object.assign({},defaults); // make a copy of the defaults
        Object.freeze(this.defaults); // freeze the defaults; that way we can return to them at any time

        this.config = defaults;
        this.messageHistory = [];
    }

    /**
     * Creates a new SpeechSynthesisUtterance
     * @return SpeechSynthesisUtterance
     */
    utterance() {
        const speech = new SpeechSynthesisUtterance();

        speech.voiceURI = this.config.voiceURI;
        speech.volume = this.config.volume;
        speech.rate = this.config.rate;
        speech.pitch = this.config.pitch;
        speech.lang = this.config.lang;

        return speech;
    }

    utteranceHistory(utterance) {
        const obj = {
            timestamp: Date.now()
        };
        // screwy object aliasing
        ({
       ...