Voz humana en español con Azure Neural TTS y C# en .NET 10

  1. .NET
  2. in 6 hours
  3. 4 min read

Este es el episodio 3 de 6 del curso: le damos voz humana en español al agente que arrancamos en el episodio anterior. El objetivo es simple de enunciar y sorprendentemente corto de implementar: diez líneas de C# que convierten un texto en audio con Azure Neural TTS, sin instalar librerías de audio adicionales.

El recurso de Azure y las credenciales

Todo empieza en el portal de Azure. Buscas “Speech” en la barra superior y seleccionas Speech services. En el formulario de creación:

Subscription: tu suscripción
Resource Group: rg-voiceagent (nuevo)
Region: East US
Name: speech-voiceagent-tuNombre
Pricing tier: Free F0 (500.000 caracteres/mes)

El tier Free F0 alcanza de sobra para desarrollo. Una vez creado el recurso, entras a Keys and Endpoint y copias la Key 1 y la región (en minúsculas, sin espacios: eastus).

Esas dos claves van a User Secrets, el mismo mecanismo que configuramos en el episodio 2:

{
"Azure": {
"SpeechKey": "tu-key-1",
"SpeechRegion": "eastus"
}
}

Las credenciales viven en tu máquina y nunca llegan al repositorio.

Diez líneas para escuchar una voz humana

Con las claves listas, el código en Program.cs es corto y se lee de arriba a abajo sin saltos:

using Microsoft.Extensions.Configuration;
using Microsoft.CognitiveServices.Speech;
var config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.Build();
var speechConfig = SpeechConfig.FromSubscription(
config["Azure:SpeechKey"]!,
config["Azure:SpeechRegion"]!
);
speechConfig.SpeechSynthesisVoiceName = "es-ES-Ximena:DragonHDLatestNeural";
using var synthesizer = new SpeechSynthesizer(speechConfig);
Console.WriteLine("Generando voz...");
var result = await synthesizer.SpeakTextAsync(
"Hola, soy el asistente de Clínica Dental Sonrisa. ¿En qué puedo ayudarte hoy?"
);
if (result.Reason == ResultReason.SynthesizingAudioCompleted)
Console.WriteLine("Audio reproducido correctamente.");
else
Console.WriteLine($"Error: {result.Reason}");

SpeechConfig.FromSubscription toma la key y la región, leídas directamente del secrets.json con la notación de dos puntos para navegar la jerarquía. SpeechSynthesisVoiceName le dice a Azure qué voz usar. SpeakTextAsync hace el trabajo real: envía el texto, recibe el audio generado y lo reproduce. El await espera a que todo el proceso termine antes de continuar, y result.Reason confirma si la síntesis se completó o falló.

F5, y la consola imprime:

Generando voz...
Audio reproducido correctamente.

Sin archivos temporales, sin NAudio, sin dependencias extra para reproducir sonido.

Qué voz elegir

es-ES-Ximena:DragonHDLatestNeural es la línea Dragon de Azure: la de mayor calidad disponible. es-ES es el locale (español de España), Ximena el nombre de la voz, y DragonHDLatestNeural indica alta definición apuntando siempre a la versión más reciente de esa voz. La diferencia de calidad se nota cuando el destinatario escucha la nota de voz en Telegram.

Si tu público es LATAM y prefieres un acento neutro, Azure ofrece alternativas estándar:

VozLocalePerfil
es-ES-Ximena:DragonHDLatestNeuralEspañaHD, máxima calidad (la usada en el video)
es-EC-AndreaNeuralEcuadorEstándar, femenina
es-MX-DaliaNeuralMéxicoEstándar, femenina
es-CO-SalomeNeuralColombiaEstándar, femenina

El catálogo completo de voces y locales está en la documentación oficial de Azure. Para este curso, la clínica dental del proyecto termina usando es-EC-AndreaNeural como voz configurada en Azure:VoiceName, pensada para un público ecuatoriano.

Los tres errores que vas a ver

Si algo falla, hay tres mensajes que vas a reconocer rápido:

AuthorizationFailure: la key está mal copiada o la región no coincide con la del recurso. Revisa SpeechKey y SpeechRegion en User Secrets.

SynthesisVoiceNameInvalid: el nombre de la voz tiene un error de escritura. Cópialo exacto, respetando mayúsculas y los dos puntos antes de DragonHDLatestNeural.

Sin audio y sin error: revisa que el dispositivo de salida de audio por defecto del sistema esté configurado y funcionando; el SDK reproduce ahí directamente.

Qué sigue

El proyecto ya tiene voz, pero todavía no tiene cerebro: el texto que se sintetiza está escrito a mano en el código. En el episodio 4 conectamos Microsoft Agent Framework para que el agente lea business-info.md y genere esas respuestas él mismo, en lugar de que las escribamos nosotros.

Si estás siguiendo el curso: crea el recurso de Speech, guarda las credenciales y corre este código una vez antes de seguir. Es la forma más rápida de confirmar que tu región y tu key están bien antes de construir algo más grande encima.

Mira el video del episodio

Azure Neural TTS C# .NET 10 Text-to-Speech Agentes de IA