# Cómo usar Text-to-Speech (TTS) y Speech-to-Text (STT)

> Pronunciar un texto en voz alta y transcribir el habla del usuario a texto, con configuración de locale/velocidad.

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

# Cómo usar Text-to-Speech (TTS) y Speech-to-Text (STT)

**Propósito.** Hacer que el dispositivo **hable** un texto (TTS) y **transcriba** el habla del usuario a
texto (STT). Soporte: Android e iOS.

## APIs usadas
- `Device.textToVoice(String text)` — sintetiza y reproduce `text` como habla. **La misma cadena sirve para configurar** el motor mediante pares `clave:valor` separados por comas.
  - `locale:por_BRA` — código de idioma (ej.: `por_BRA`, `eng_USA_f00`).
  - `speech:0.75` — multiplicador de velocidad (`1.0` = normal, `0.5` = lento, `2.0` = rápido).
  - `languages` — lista los idiomas disponibles en el logcat (debug). `quit` — apaga el motor TTS.
- `Device.voiceToText(VoiceToTextListener listener)` — inicia el reconocimiento de habla; los resultados llegan por los callbacks.
- `Device.VoiceToTextListener` — `onStart()`, `onFinish()`, `onResult(String text)`, `onError(int code, String msg)`.
- `Device.soundToSpeechTimeout` (estático, ms, por defecto `5000`) — timeout del reconocimiento.

> **Sí, `textToVoice` acepta una cadena de configuración.** La primera llamada puede configurar
> `locale`/`speech` (ej.: `"locale:por_BRA,speech:0.75"`); las llamadas siguientes con texto normal pronuncian el
> contenido. Los callbacks de `voiceToText` llegan **fuera de la paint thread** → usa `Component.onUI(...)`
> al actualizar la UI. En la primera ejecución en Android puede solicitarse la instalación de paquetes de
> idioma HD.

## Ejemplo completo (copiar, pegar y ejecutar)

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: 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 — configurar idioma/velocidad y luego hablar
         Device.textToVoice("locale:por_BRA,speech:0.9");     // configuración (opcional, 1ª vez)
         Device.textToVoice("Olá! Bem-vindo ao aplicativo.");  // habla el texto
         resultado.setText("Falando...");
      });
      add(LAY_AUTO, falar);

      Button ouvir = new Button("Transcrever (STT)");
      ouvir.onAction(c ->
      {
         // STT — transcribir el habla del usuario (callbacks fuera de la 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);
   }
}
```

> El fragmento de abajo muestra **solo el núcleo**. Para ejecutarlo, colócalo en el esqueleto `MainWindow` de arriba.

## Fragmento mínimo

```java
// verificado en la fuente: Device.java (textToVoice línea 387, voiceToText línea 340, VoiceToTextListener línea 397)
import dev.crossfly.device.*;              // Device, Device.VoiceToTextListener
import dev.crossfly.ui.*;                  // Component (onUI)

// 1) TTS — configurar idioma/velocidad y luego hablar
Device.textToVoice("locale:por_BRA,speech:0.9");   // configuración (opcional, 1ª vez)
Device.textToVoice("Olá! Bem-vindo ao aplicativo."); // habla el texto

// 2) STT — transcribir el habla del usuario (callbacks fuera de la 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));   // texto reconocido
   }
   public void onError(int code, String msg) {
      Component.onUI(() -> mostrarErro(msg));
   }
});
```

## Profundiza
- Guía de sonido y varios: [Sonido y varios](/docs/data-and-services/device-sound-and-misc)
- Receta hermana: [vibrar-beep-clipboard.md](/docs/cookbook/device/vibrar-beep-clipboard)
