1

Javafx:How can text-to speech is done on animated text; I have applied a typewriter effect on text to make animated text, and now i want that it will speak word by word as typed. P.S. for Text-to-Speech iam using the "FreeTTS is a speech synthesis engine"

here is code snippet of my project

    public void AnimattedTextToSpeech()
{       
        // Text to Speech
        Voice voice;
         VoiceManager vm=VoiceManager.getInstance();
         voice=vm.getVoice("kevin16");
         voice.allocate();

         // TypeWritter Effect to the text
         String str="Welcome! This is the Lesson number one";
         final IntegerProperty i = new SimpleIntegerProperty(0);
             Timeline timeline = new Timeline();
            KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
                        if (i.get() > str.length()) {
                            timeline.stop();
                        } else {
                            textArea.setText(str.substring(0, i.get()));    
                            i.set(i.get() + 1);
                            textArea.requestFocus();
                            textArea.end();
                        }
                    });
            voice.speak(str);
            timeline.getKeyFrames().add(keyFrame);
            timeline.setCycleCount(Animation.INDEFINITE);
            timeline.play();    
}

But it is speaking every character as it is typing. But i want it speak word by word.

Itian
  • 123
  • 8

2 Answers2

2

This works but it seems like you need to run the speech on a different thread.

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 *
 * @author blj0011
 */
public class FreeTTTS extends Application
{

    @Override
    public void start(Stage primaryStage)
    {
        TextArea textArea = new TextArea();
        // Text to Speech
        Voice voice;
        VoiceManager vm = VoiceManager.getInstance();
        voice = vm.getVoice("kevin16");
        voice.allocate();

        // TypeWritter Effect to the text
        String str = "Welcome! This is the Lesson number one";
        final IntegerProperty i = new SimpleIntegerProperty(0);
        Timeline timeline = new Timeline();
        AtomicInteger startIndex = new AtomicInteger();
        AtomicInteger endIndex = new AtomicInteger();

        KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
            if (i.get() >= str.length()) {
                timeline.stop();
                startIndex.set(endIndex.get());
                endIndex.set(i.get());

                String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
                System.out.println(word);
                voice.speak(word);
            }
            else {
                textArea.appendText(Character.toString(str.charAt(i.get())));
                if (str.charAt(i.get()) == ' ') {
                    if (endIndex.get() == 0) {
                        endIndex.set(i.get());

                        String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
                        System.out.println(word);
                        voice.speak(word);
                    }
                    else {
                        startIndex.set(endIndex.get());
                        endIndex.set(i.get());

                        String word = str.substring(startIndex.get(), endIndex.get()).trim().replaceAll("[^a-zA-Z ]", "");
                        System.out.println(word);
                        voice.speak(word);
                    }
                }

                i.set(i.get() + 1);

            }
        });
        //voice.speak(str);

        StackPane root = new StackPane(textArea);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();

        timeline.getKeyFrames().add(keyFrame);
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
        //voice.speak("Hello World");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}
SedJ601
  • 12,173
  • 3
  • 41
  • 59
0

I imagine you should divide text into strings, and start TTS the moment you start TypeWritter effect for each string. Like this:

 String str1 = "Welcome! This is the Lesson number one";
    String[] temp = str1.split(" ");
    final IntegerProperty i = new SimpleIntegerProperty(0);
    Timeline timeline = new Timeline();
    for (String str : temp) {
        KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.1), event2 -> {
            if (i.get() > str.length()) {
                timeline.stop();
            } else {
                textArea.setText(str.substring(0, i.get()));
                i.set(i.get() + 1);
                textArea.requestFocus();
                textArea.end();
            }
        });
        voice.speak(str);
        timeline.getKeyFrames().add(keyFrame);

        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }
Lukas Novicky
  • 921
  • 1
  • 19
  • 44
  • Thank you! It works fine for TTS but the animation effect is no more working; its showing only the second last word of the string "Number" without applying the animation effect – Itian Mar 04 '19 at 11:37
  • try now. just play with it a bit - this is what I did. Understand what must be done, and adapt code to it - in moment when you start animating string from array you must also start TTS for whole word. – Lukas Novicky Mar 04 '19 at 11:43
  • Thanks but the animation effects is no working at all – Itian Mar 04 '19 at 11:52