Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

How to use Text-to-Speech (TTS) and Speech-to-Text (STT)

Purpose. Make the device speak a text (TTS) and transcribe the user’s speech into text (STT). Support: Android and iOS.

APIs used

  • Device.textToVoice(String text) — synthesizes and plays text as speech. The same string is also used to configure the engine via key:value pairs separated by commas.
    • locale:por_BRA — language code (e.g., por_BRA, eng_USA_f00).
    • speech:0.75 — speed multiplier (1.0 = normal, 0.5 = slow, 2.0 = fast).
    • languages — lists the available languages in the logcat (debug). quit — shuts down the TTS engine.
  • Device.voiceToText(VoiceToTextListener listener) — starts speech recognition; results arrive through the callbacks.
  • Device.VoiceToTextListener — onStart(), onFinish(), onResult(String text), onError(int code, String msg).
  • Device.soundToSpeechTimeout (static, ms, default 5000) — recognition timeout.

Yes, textToVoice accepts a configuration string. The first call can configure locale/speech (e.g., "locale:por_BRA,speech:0.75"); subsequent calls with normal text speak the content. The voiceToText callbacks arrive off the paint thread → use Component.onUI(...) when updating the UI. On the first run on Android, installation of HD language packs may be requested.

Complete example (copy, paste and run)

package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Component, Button, Label
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.device.*;               // Device, Device.VoiceToTextListener

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button falar = new Button("Falar (TTS)");
      falar.onAction(c ->
      {
         // TTS — configure language/speed and then speak
         Device.textToVoice("locale:por_BRA,speech:0.9");     // configuration (optional, 1st time)
         Device.textToVoice("Olá! Bem-vindo ao aplicativo.");  // speaks the text
         resultado.setText("Falando...");
      });
      add(LAY_AUTO, falar);

      Button ouvir = new Button("Transcrever (STT)");
      ouvir.onAction(c ->
      {
         // STT — transcribe the user's speech (callbacks outside the paint thread)
         Device.voiceToText(new Device.VoiceToTextListener()
         {
            public void onStart()  { Component.onUI(() -> resultado.setText("Ouvindo...")); }
            public void onFinish() { Component.onUI(() -> resultado.setText("Pronto")); }
            public void onResult(String text)
            {
               Component.onUI(() -> resultado.setText("Reconhecido: " + text));
            }
            public void onError(int code, String msg)
            {
               Component.onUI(() -> resultado.setText("Erro: " + msg));
            }
         });
      });
      add(LAY_AUTO, ouvir);
   }
}

The snippet below shows only the core. To run it, place it inside the MainWindow skeleton above.

Minimal snippet

// verified at source: Device.java (textToVoice line 387, voiceToText line 340, VoiceToTextListener line 397)
import dev.crossfly.device.*;              // Device, Device.VoiceToTextListener
import dev.crossfly.ui.*;                  // Component (onUI)

// 1) TTS — configure language/speed and then speak
Device.textToVoice("locale:por_BRA,speech:0.9");   // configuration (optional, 1st time)
Device.textToVoice("Olá! Bem-vindo ao aplicativo."); // speaks the text

// 2) STT — transcribe the user's speech (callbacks outside the paint thread)
Device.voiceToText(new Device.VoiceToTextListener() {
   public void onStart()  { Component.onUI(() -> mostrarStatus("Ouvindo...")); }
   public void onFinish() { Component.onUI(() -> mostrarStatus("Pronto")); }
   public void onResult(String text) {
      Component.onUI(() -> preencherCampo(text));   // recognized text
   }
   public void onError(int code, String msg) {
      Component.onUI(() -> mostrarErro(msg));
   }
});

Dive deeper

Was this page helpful?