7c – Text to Speech

Now that you have the hang of using strings, chars and arrays to manage text – what else can you do with these tools?

How can you make the computer speak?

If possible use a mac, as it is slightly easier. But for those who are using PCs you can use the Speech to Text library here. This uses the Google Speech API – you have to register for keys.

However at this stage, I recommend you use the school mac computers as you can use the great text to speech program on them. You saw in class how to use the terminal. To revise, open up the terminal and run through this guide on the mac text to speech engine:
http://www.maclife.com/article/columns/terminal_101_making_your_mac_talk_%E2%80%9Csay%E2%80%9D

We can send terminal commands from Processing to the terminal to make use of engines like these. Lucky for us, there is an easy to use class that Erica Mika has written. Details here. So take this code for a text to speech class and add it either below draw or in a new tab.

// the text to speech class
import java.io.IOException;
 
static class TextToSpeech extends Object {
 
  // Store the voices, makes for nice auto-complete in Eclipse
 
  // male voices
  static final String ALEX = "Alex";
  static final String BRUCE = "Bruce";
  static final String FRED = "Fred";
  static final String JUNIOR = "Junior";
  static final String RALPH = "Ralph";
 
  // female voices
  static final String AGNES = "Agnes";
  static final String KATHY = "Kathy";
  static final String PRINCESS = "Princess";
  static final String VICKI = "Vicki";
  static final String VICTORIA = "Victoria";
 
  // novelty voices
  static final String ALBERT = "Albert";
  static final String BAD_NEWS = "Bad News";
  static final String BAHH = "Bahh";
  static final String BELLS = "Bells";
  static final String BOING = "Boing";
  static final String BUBBLES = "Bubbles";
  static final String CELLOS = "Cellos";
  static final String DERANGED = "Deranged";
  static final String GOOD_NEWS = "Good News";
  static final String HYSTERICAL = "Hysterical";
  static final String PIPE_ORGAN = "Pipe Organ";
  static final String TRINOIDS = "Trinoids";
  static final String WHISPER = "Whisper";
  static final String ZARVOX = "Zarvox";
 
  // throw them in an array so we can iterate over them / pick at random
  static String[] voices = {
    ALEX, BRUCE, FRED, JUNIOR, RALPH, AGNES, KATHY,
    PRINCESS, VICKI, VICTORIA, ALBERT, BAD_NEWS, BAHH,
    BELLS, BOING, BUBBLES, CELLOS, DERANGED, GOOD_NEWS,
    HYSTERICAL, PIPE_ORGAN, TRINOIDS, WHISPER, ZARVOX
  };
 
  // this sends the "say" command to the terminal with the appropriate args
  static void say(String script, String voice, int speed) {
    try {
      Runtime.getRuntime().exec(new String[] {"say", "-v", voice, "[[rate " + speed + "]]" + script});
    }
    catch (IOException e) {
      System.err.println("IOException");
    }
  }
 
  // Overload the say method so we can call it with fewer arguments and basic defaults
  static void say(String script) {
    // 200 seems like a resonable default speed
    say(script, ALEX, 200);
  }
 
}

This class basically sets up our sketch so we can use the function

  TextToSpeech.say(script, TextToSpeech.voices[voiceIndex], voiceSpeed);

The arguments are as follows: ‘script’ is the string that you want the computer to say, the voice index is a number that ranges from (0-23) and calls the different voices in the computer and the voiceSpeed sets voice speed.
She has a simple example available here.

To introduce voice to speech to the last text example, set up variables for voiceIndex and voiceSpeed. And add this function that will speak your answer (the string phrase) when you click.

void mousePressed() {
 TextToSpeech.say(phrase, TextToSpeech.voices[voiceIndex], voiceSpeed);
 }

Challenge:
How can you vary the voices and the voiceSpeed with mouse position?
How can you get the computer to say when you are right or wrong?

Importing text from an external file
For this sketch to work you will need to create a text file in textEdit and put it into your sketch folder, inside a data folder.

When you import text files you import them into an array of Strings with each line of text as a new entry in the array.

String [] textIn; 
void setup(){
  size(200, 200);
  textIn = loadStrings("textFile.txt");
}
 
void draw(){
  background(0); 
  fill(200); 
  text(textIn [0], 20, 100); 
}

This sketch would allow someone who has no programming ability at all write content for your program.

String [] textIn;
String phrase; 
int phraseNum; 
int fade = 255; 
PFont font; 
void setup() {
  size(800, 160);
  textIn = loadStrings("textFile.txt");
  font = createFont("Handwriting-Dakota", 60); 
  textFont(font); 
  phrase = textIn[0];
  textAlign(CENTER);
}
void draw() {
  fade-=2; 
  if (fade==0) {
    fade = 255; 
    phraseNum ++; 
    if (phraseNum == textIn.length) {
      phraseNum = 0;
    }
  }
  phrase = textIn[phraseNum];
  background(0); 
  fill(200, fade); 
  if (phraseNum==textIn.length-1){
    fill(255, 100, 20, fade);
  }
  else {
    fill(200,fade);
}
  text(phrase,width/2,100);
}

Here is an example with textFromFileVoice