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

> Speak a text aloud and transcribe the user's speech into text, with locale/speed configuration.

Source: https://crossfly.dev/docs/cookbook/device/tts-stt — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 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)

```java
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

```java
// 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
- Sound and miscellaneous guide: [Sound and miscellaneous](/docs/data-and-services/device-sound-and-misc)
- Sibling recipe: [vibrar-beep-clipboard.md](/docs/cookbook/device/vibrar-beep-clipboard)
