Introducción a la conversión de texto a voz

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de C# en GitHub.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar Speech SDK. Utilice las siguientes instrucciones en función de la plataforma:

Dependencias de importación

Para ejecutar los ejemplos de este artículo, incluya las siguientes instrucciones de using al principio del script.

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

Creación de una configuración de voz

Para llamar al servicio de voz con Speech SDK, debe crear un elemento SpeechConfig. Esta clase incluye información sobre la suscripción, como la clave de voz y la región o ubicación asociada, el punto de conexión, el host, o el token de autorización.

Nota

Debe crear siempre una configuración, independientemente de si va a realizar reconocimiento de voz, síntesis de voz, traducción o reconocimiento de intenciones.

Existen diversas maneras para inicializar un elemento SpeechConfig:

  • Con una suscripción: pase una clave y la región o ubicación asociada.
  • Con un punto de conexión: pase un punto de conexión del servicio de voz. La clave y el token de autorización son opcionales.
  • Con un host: pase una dirección de host. La clave y el token de autorización son opcionales.
  • Con un token de autorización: pase el token de autorización y la región o ubicación asociadas.

En este ejemplo, se crea un elemento SpeechConfig mediante una clave de voz y una región o ubicación. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz. Cree también código reutilizable básico para usarlo en el resto del artículo y que modificará cuando realice distintas personalizaciones.

public class Program
{
    static async Task Main()
    {
        await SynthesizeAudioAsync();
    }

    static async Task SynthesizeAudioAsync()
    {
        var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    }
}

Selección del idioma y la voz de síntesis

El servicio Text to Speech de Azure admite más de 250 voces y más de 70 idiomas y variantes. Puede obtener la lista completa o probarlos en la demostración de texto a voz. Especifique el idioma o la voz de SpeechConfig para que coincida con el texto de entrada y usar la voz que prefiera.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config.SpeechSynthesisLanguage = "<your-synthesis-language>"; // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config.SpeechSynthesisVoiceName = "<your-wanted-voice>";
}

Síntesis de voz en un archivo

A continuación, creará un objeto SpeechSynthesizer, que ejecuta conversiones de texto a voz y envía la salida a altavoces, archivos u otros flujos de salida. SpeechSynthesizer acepta como parámetros tanto el objeto SpeechConfig que se creó creado en el paso anterior y un objeto AudioConfig que especifica cómo se deben controlar los resultados de la salida.

Para empezar, cree un objeto AudioConfig para escribir automáticamente la salida en un archivo .wav, para lo que se usa la función FromWavFileOutput(), y cree las instancias necesarias con una instrucción using. En este contexto, una instrucción using desecha automáticamente los recursos no administrados y hace que el objeto deje de estar dentro del ámbito después de la eliminación.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
}

A continuación, cree una instancia de SpeechSynthesizer con otra instrucción using. Use los objetos config y audioConfig como parámetros. Después, para ejecutar la síntesis de voz y realizar la escritura en un archivo solo hay que ejecutar SpeakTextAsync() con una cadena de texto.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    using var synthesizer = new SpeechSynthesizer(config, audioConfig);
    await synthesizer.SpeakTextAsync("A simple test to write to a file.");
}

Ejecute el programa y se escribirá un archivo .wav sintetizado en la ubicación que haya especificado. Este es un buen ejemplo del uso más básico, pero a continuación puede examinar cómo personalizar la salida y controlar la respuesta de la salida como una secuencia en memoria para trabajar con escenarios personalizados.

Síntesis a la salida de altavoz

En algunos casos, puede que desee enviar la voz sintetizada directamente a un altavoz. Para ello, omita el parámetro AudioConfig al crear SpeechSynthesizer en el ejemplo anterior. De esta forma, se sintetiza en el dispositivo de salida activo actual.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config);
    await synthesizer.SpeakTextAsync("Synthesizing directly to speaker output.");
}

Obtención del resultado en forma de secuencia en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite el bloqueo de AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use null en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar null en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. La propiedad AudioData contiene un byte [] de los datos de salida. Puede trabajar con byte [] manualmente, o bien puede usar la clase AudioDataStream para administrar la secuencia en memoria. En este ejemplo, se usa la función estática AudioDataStream.FromResult() para obtener una secuencia del resultado.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config, null);

    var result = await synthesizer.SpeakTextAsync("Getting the response as an in-memory stream.");
    using var stream = AudioDataStream.FromResult(result);
}

A partir de aquí se puede implementar cualquier comportamiento personalizado mediante el objeto stream resultante.

Personalización del formato de audio

En la siguiente sección se muestra cómo personalizar los atributos de la salida de audio, entre los que se incluyen:

  • Tipo de archivo de audio
  • Frecuencia de muestreo
  • Profundidad de bits

Para cambiar el formato de audio se usa la función SetSpeechSynthesisOutputFormat() en el objeto SpeechConfig. Esta función espera un elemento enum del tipo SpeechSynthesisOutputFormat, que se usa para seleccionar el formato de salida. En los documentos de referencia encontrará una lista de los formatos de audio disponibles.

Hay varias opciones para los distintos tipos de archivo, por lo que puede elegir la que necesite. Tenga en cuenta que, por definición, los formatos sin procesar, como Raw24Khz16BitMonoPcm, no incluyen encabezados de audio. Los formatos sin procesar solo se deben usar cuando se sepa que la implementación de bajada puede descodificar una secuencia de bits sin procesar, o bien si planea crear manualmente encabezados basados en la profundidad de bits, la frecuencia de muestreo, el número de canales, etc.

En este ejemplo, se especifica un formato RIFF de alta fidelidad Riff24Khz16BitMonoPcm, para lo que se establece SpeechSynthesisOutputFormat en el objeto SpeechConfig. Al igual que en el ejemplo de la sección anterior, se usa AudioDataStream para obtener una secuencia en memoria del resultado y, después, escribirla en un archivo.

static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    config.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    using var synthesizer = new SpeechSynthesizer(config, null);
    var result = await synthesizer.SpeakTextAsync("Customizing audio output format.");

    using var stream = AudioDataStream.FromResult(result);
    await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}

Si vuelve a ejecutar el programa, se escribirá un archivo .wav en la ruta de acceso especificada.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función SpeakTextAsync(), se usa SpeakSsmlAsync(). Esta función espera una cadena XML, por lo que lo primero que se debe hacer es cargar la configuración de SSML como una cadena, para lo que se usa File.ReadAllText(). Desde aquí, el objeto de resultado es exactamente el mismo que el de los ejemplos anteriores.

Nota

Si usa Visual Studio, es probable que la configuración de compilación no encuentre el archivo XML de forma predeterminada. Para solucionarlo, haga clic con el botón derecho en el archivo XML y seleccione Propiedades. Cambie Acción de compilación a Contenido y cambie Copiar en el directorio de resultados a Copiar siempre.

public static async Task SynthesizeAudioAsync()
{
    var config = SpeechConfig.FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    using var synthesizer = new SpeechSynthesizer(config, null);

    var ssml = File.ReadAllText("./ssml.xml");
    var result = await synthesizer.SpeakSsmlAsync(ssml);

    using var stream = AudioDataStream.FromResult(result);
    await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante SpeechConfig.SpeechSynthesisVoiceName = "en-US-ChristopherNeural";

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse al evento viseme en Speech SDK. Después, puede aplicar eventos de visema para animar la cara de un personaje mientras se reproduce el audio de voz. Aprenda a obtener eventos de visema.

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de C++ en GitHub.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar Speech SDK. Utilice las siguientes instrucciones en función de la plataforma:

Dependencias de importación

Para ejecutar los ejemplos de este artículo, incluya las siguientes instrucciones using y de importación en el principio del script.

#include <iostream>
#include <fstream>
#include <string>
#include <speechapi_cxx.h>

using namespace std;
using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Audio;

Creación de una configuración de voz

Para llamar al servicio de voz con Speech SDK, debe crear un elemento SpeechConfig. Esta clase incluye información sobre la suscripción, como la clave de voz y la región o ubicación asociada, el punto de conexión, el host, o el token de autorización.

Nota

Debe crear siempre una configuración, independientemente de si va a realizar reconocimiento de voz, síntesis de voz, traducción o reconocimiento de intenciones.

Existen diversas maneras para inicializar un elemento SpeechConfig:

  • Con una suscripción: pase una clave y la región o ubicación asociada.
  • Con un punto de conexión: pase un punto de conexión del servicio de voz. La clave y el token de autorización son opcionales.
  • Con un host: pase una dirección de host. La clave y el token de autorización son opcionales.
  • Con un token de autorización: pase el token de autorización y la región o ubicación asociadas.

En este ejemplo, se crea un elemento SpeechConfig mediante una clave de suscripción y una región. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz. Cree también código reutilizable básico para usarlo en el resto del artículo y que modificará cuando realice distintas personalizaciones.

int wmain()
{
    try
    {
        synthesizeSpeech();
    }
    catch (exception e)
    {
        cout << e.what();
    }
    return 0;
}

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
}

Selección del idioma y la voz de síntesis

El servicio Text to Speech de Azure admite más de 250 voces y más de 70 idiomas y variantes. Puede obtener la lista completa o probarlos en la demostración de texto a voz. Especifique el idioma o la voz de SpeechConfig para que coincida con el texto de entrada y usar la voz que prefiera.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config->SetSpeechSynthesisLanguage("<your-synthesis-language>"); // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config->SetSpeechSynthesisVoiceName("<your-wanted-voice>");
}

Síntesis de voz en un archivo

A continuación, creará un objeto SpeechSynthesizer, que ejecuta conversiones de texto a voz y envía la salida a altavoces, archivos u otros flujos de salida. SpeechSynthesizer acepta como parámetros tanto el objeto SpeechConfig que se creó creado en el paso anterior y un objeto AudioConfig que especifica cómo se deben controlar los resultados de la salida.

Para empezar, cree un objeto AudioConfig para escribir automáticamente la salida en un archivo .wav mediante la función FromWavFileOutput().

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
}

Luego, cree una instancia de SpeechSynthesizer y use los objetos config y audioConfig como parámetros. Después, para ejecutar la síntesis de voz y realizar la escritura en un archivo solo hay que ejecutar SpeakTextAsync() con una cadena de texto.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, audioConfig);
    auto result = synthesizer->SpeakTextAsync("A simple test to write to a file.").get();
}

Ejecute el programa y se escribirá un archivo .wav sintetizado en la ubicación que haya especificado. Este es un buen ejemplo del uso más básico, pero a continuación puede examinar cómo personalizar la salida y controlar la respuesta de la salida como una secuencia en memoria para trabajar con escenarios personalizados.

Síntesis a la salida de altavoz

En algunos casos, puede que desee enviar la voz sintetizada directamente a un altavoz. Para ello, omita el parámetro AudioConfig al crear SpeechSynthesizer en el ejemplo anterior. De esta forma, se sintetiza en el dispositivo de salida activo actual.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config);
    auto result = synthesizer->SpeakTextAsync("Synthesizing directly to speaker output.").get();
}

Obtención del resultado en forma de secuencia en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use NULL en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar NULL en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. El captador GetAudioData devuelve un byte [] de los datos de salida. Puede trabajar con byte [] manualmente, o bien puede usar la clase AudioDataStream para administrar la secuencia en memoria. En este ejemplo, se usa la función estática AudioDataStream.FromResult() para obtener una secuencia del resultado.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);

    auto result = synthesizer->SpeakTextAsync("Getting the response as an in-memory stream.").get();
    auto stream = AudioDataStream::FromResult(result);
}

A partir de aquí se puede implementar cualquier comportamiento personalizado mediante el objeto stream resultante.

Personalización del formato de audio

En la siguiente sección se muestra cómo personalizar los atributos de la salida de audio, entre los que se incluyen:

  • Tipo de archivo de audio
  • Frecuencia de muestreo
  • Profundidad de bits

Para cambiar el formato de audio se usa la función SetSpeechSynthesisOutputFormat() en el objeto SpeechConfig. Esta función espera un elemento enum del tipo SpeechSynthesisOutputFormat, que se usa para seleccionar el formato de salida. En los documentos de referencia encontrará una lista de los formatos de audio disponibles.

Hay varias opciones para los distintos tipos de archivo, por lo que puede elegir la que necesite. Tenga en cuenta que, por definición, los formatos sin procesar, como Raw24Khz16BitMonoPcm, no incluyen encabezados de audio. Los formatos sin procesar solo se deben usar cuando se sepa que la implementación de bajada puede descodificar una secuencia de bits sin procesar, o bien si planea crear manualmente encabezados basados en la profundidad de bits, la frecuencia de muestreo, el número de canales, etc.

En este ejemplo, se especifica un formato RIFF de alta fidelidad Riff24Khz16BitMonoPcm, para lo que se establece SpeechSynthesisOutputFormat en el objeto SpeechConfig. Al igual que en el ejemplo de la sección anterior, se usa AudioDataStream para obtener una secuencia en memoria del resultado y, después, escribirla en un archivo.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    config->SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat::Riff24Khz16BitMonoPcm);

    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);
    auto result = synthesizer->SpeakTextAsync("A simple test to write to a file.").get();

    auto stream = AudioDataStream::FromResult(result);
    stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}

Si vuelve a ejecutar el programa, se escribirá un archivo .wav en la ruta de acceso especificada.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función SpeakTextAsync(), se usa SpeakSsmlAsync(). Esta función espera una cadena XML, por lo que lo primero que se debe hacer es cargar la configuración de SSML como una cadena. Desde aquí, el objeto de resultado es exactamente el mismo que el de los ejemplos anteriores.

void synthesizeSpeech()
{
    auto config = SpeechConfig::FromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    auto synthesizer = SpeechSynthesizer::FromConfig(config, NULL);

    std::ifstream file("./ssml.xml");
    std::string ssml, line;
    while (std::getline(file, line))
    {
        ssml += line;
        ssml.push_back('\n');
    }
    auto result = synthesizer->SpeakSsmlAsync(ssml).get();

    auto stream = AudioDataStream::FromResult(result);
    stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante SpeechConfig.SetSpeechSynthesisVoiceName("en-US-ChristopherNeural")

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse al evento viseme en Speech SDK. Después, puede aplicar eventos de visema para animar la cara de un personaje mientras se reproduce el audio de voz. Aprenda a obtener eventos de visema.

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz.

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de Go en GitHub.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar el SDK de Voz para Go.

Texto a voz para altavoz

Use el siguiente ejemplo de código para ejecutar la síntesis de voz para el dispositivo de salida de audio predeterminado. Reemplace las variables subscription y region por la clave de voz y la suscripción o región. La ejecución del script generará el texto de entrada hablado para el altavoz predeterminado.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Synthesis started.")
}

func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}

func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}

func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Received a cancellation.")
}

func main() {
    subscription := "<paste-your-speech-key-here>"
    region := "<paste-your-speech-location/region-here>"

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(config, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        task := speechSynthesizer.SpeakTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        if outcome.Result.Reason == common.SynthesizingAudioCompleted {
            fmt.Printf("Speech synthesized to speaker for text [%s].\n", text)
        } else {
            cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
            fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)

            if cancellation.Reason == common.Error {
                fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you update the subscription info?\n",
                    cancellation.ErrorCode,
                    cancellation.ErrorDetails)
            }
        }
    }
}

Ejecute los siguientes comandos para crear un archivo go.mod que vincule a los componentes hospedados en GitHub.

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Compile y ejecute ahora el código.

go build
go run quickstart

Vea los documentos de referencia para obtener información detallada sobre las clases SpeechConfig y SpeechSynthesizer.

Texto a voz para emisión en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use nil en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar nil en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. La propiedad AudioData devuelve un []byte de los datos de salida. Puede trabajar con []byte manualmente, o bien puede usar la clase AudioDataStream para administrar la secuencia en memoria. En este ejemplo, se usa la función estática NewAudioDataStreamFromSpeechSynthesisResult() para obtener una secuencia del resultado.

Reemplace las variables subscription y region por la clave de voz y la suscripción o región.

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func main(subscription string, region string) {
    subscription := "<paste-your-speech-key-here>"
    region := "<paste-your-speech-location/region-here>"

    config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer config.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(config, nil)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        // StartSpeakingTextAsync sends the result to channel when the synthesis starts.
        task := speechSynthesizer.StartSpeakingTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        // in most case we want to streaming receive the audio to lower the latency,
        // we can use AudioDataStream to do so.
        stream, err := speech.NewAudioDataStreamFromSpeechSynthesisResult(outcome.Result)
        defer stream.Close()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }

        var all_audio []byte
        audio_chunk := make([]byte, 2048)
        for {
            n, err := stream.Read(audio_chunk)

            if err == io.EOF {
                break
            }

            all_audio = append(all_audio, audio_chunk[:n]...)
        }

        fmt.Printf("Read [%d] bytes from audio data stream.\n", len(all_audio))
    }
}

Ejecute los siguientes comandos para crear un archivo go.mod que vincule a los componentes hospedados en GitHub.

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Compile y ejecute ahora el código.

go build
go run quickstart

Vea los documentos de referencia para obtener información detallada sobre las clases SpeechConfig y SpeechSynthesizer.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función SpeakTextAsync(), se usa SpeakSsmlAsync(). Esta función espera una cadena XML, por lo que lo primero que se debe hacer es cargar la configuración de SSML como una cadena. Desde aquí, el objeto de resultado es exactamente el mismo que el de los ejemplos anteriores.

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante speechConfig.SetSpeechSynthesisVoiceName("en-US-ChristopherNeural")

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse al evento viseme en Speech SDK. Después, puede aplicar eventos de visema para animar la cara de un personaje mientras se reproduce el audio de voz. Aprenda a obtener eventos de visema.

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de Java en GitHub.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar Speech SDK. Utilice las siguientes instrucciones en función de la plataforma:

Dependencias de importación

Para ejecutar los ejemplos de este artículo, incluya las siguientes instrucciones de importación en la parte superior del script.

import com.microsoft.cognitiveservices.speech.AudioDataStream;
import com.microsoft.cognitiveservices.speech.SpeechConfig;
import com.microsoft.cognitiveservices.speech.SpeechSynthesizer;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisOutputFormat;
import com.microsoft.cognitiveservices.speech.SpeechSynthesisResult;
import com.microsoft.cognitiveservices.speech.audio.AudioConfig;

import java.io.*;
import java.util.Scanner;

Creación de una configuración de voz

Para llamar al servicio de voz con Speech SDK, debe crear un elemento SpeechConfig. Esta clase incluye información sobre la suscripción, como la clave de voz y la región o ubicación asociada, el punto de conexión, el host, o el token de autorización.

Nota

Debe crear siempre una configuración, independientemente de si va a realizar reconocimiento de voz, síntesis de voz, traducción o reconocimiento de intenciones.

Existen diversas maneras para inicializar un elemento SpeechConfig:

  • Con una suscripción: pase una clave de voz y la región o ubicación asociadas.
  • Con un punto de conexión: pase un punto de conexión del servicio de voz. La clave de voz y el token de autorización son opcionales.
  • Con un host: pase una dirección de host. La clave de voz y el token de autorización son opcionales.
  • Con un token de autorización: pase el token de autorización y la región o ubicación asociadas.

En este ejemplo, se crea un elemento SpeechConfig mediante una clave de voz y una región o ubicación. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz. Cree también código reutilizable básico para usarlo en el resto del artículo y que modificará cuando realice distintas personalizaciones.

public class Program
{
    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    }
}

Selección del idioma y la voz de síntesis

El servicio Text to Speech de Azure admite más de 250 voces y más de 70 idiomas y variantes. Puede obtener la lista completa o probarlos en la demostración de texto a voz. Especifique el idioma o la voz de SpeechConfig para que coincida con el texto de entrada y usar la voz que prefiera.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    config.setSpeechSynthesisLanguage("<your-synthesis-language>"); // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    config.setSpeechSynthesisVoiceName("<your-wanted-voice>");
}

Síntesis de voz en un archivo

A continuación, creará un objeto SpeechSynthesizer, que ejecuta conversiones de texto a voz y envía la salida a altavoces, archivos u otros flujos de salida. SpeechSynthesizer acepta como parámetros tanto el objeto SpeechConfig que se creó creado en el paso anterior y un objeto AudioConfig que especifica cómo se deben controlar los resultados de la salida.

Para empezar, cree un objeto AudioConfig para escribir automáticamente la salida en un archivo .wav mediante la función estática fromWavFileOutput().

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
}

Luego, cree una instancia de SpeechSynthesizer y use los objetos speechConfig y audioConfig como parámetros. Después, para ejecutar la síntesis de voz y realizar la escritura en un archivo solo hay que ejecutar SpeakText() con una cadena de texto.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.SpeakText("A simple test to write to a file.");
}

Ejecute el programa y se escribirá un archivo .wav sintetizado en la ubicación que haya especificado. Este es un buen ejemplo del uso más básico, pero a continuación puede examinar cómo personalizar la salida y controlar la respuesta de la salida como una secuencia en memoria para trabajar con escenarios personalizados.

Síntesis a la salida de altavoz

En algunos casos, puede que desee enviar la voz sintetizada directamente a un altavoz. Para ello, cree una instancia de AudioConfig mediante la función estática fromDefaultSpeakerOutput(). De esta forma, la salida s realiza a través del dispositivo de salida activo actual.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    AudioConfig audioConfig = AudioConfig.fromDefaultSpeakerOutput();

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.SpeakText("Synthesizing directly to speaker output.");
}

Obtención del resultado en forma de secuencia en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite el bloqueo de AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use null en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar null en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. La función SpeechSynthesisResult.getAudioData() devuelve un byte [] de los datos de salida. Puede trabajar con byte [] manualmente, o bien puede usar la clase AudioDataStream para administrar la secuencia en memoria. En este ejemplo, se usa la función estática AudioDataStream.fromResult() para obtener una secuencia del resultado.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);

    SpeechSynthesisResult result = synthesizer.SpeakText("Getting the response as an in-memory stream.");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    System.out.print(stream.getStatus());
}

A partir de aquí se puede implementar cualquier comportamiento personalizado mediante el objeto stream resultante.

Personalización del formato de audio

En la siguiente sección se muestra cómo personalizar los atributos de la salida de audio, entre los que se incluyen:

  • Tipo de archivo de audio
  • Frecuencia de muestreo
  • Profundidad de bits

Para cambiar el formato de audio se usa la función setSpeechSynthesisOutputFormat() en el objeto SpeechConfig. Esta función espera un elemento enum del tipo SpeechSynthesisOutputFormat, que se usa para seleccionar el formato de salida. En los documentos de referencia encontrará una lista de los formatos de audio disponibles.

Hay varias opciones para los distintos tipos de archivo, por lo que puede elegir la que necesite. Tenga en cuenta que, por definición, los formatos sin procesar, como Raw24Khz16BitMonoPcm, no incluyen encabezados de audio. Los formatos sin procesar solo se deben usar cuando se sepa que la implementación de bajada puede descodificar una secuencia de bits sin procesar, o bien si planea crear manualmente encabezados basados en la profundidad de bits, la frecuencia de muestreo, el número de canales, etc.

En este ejemplo, se especifica un formato RIFF de alta fidelidad Riff24Khz16BitMonoPcm, para lo que se establece SpeechSynthesisOutputFormat en el objeto SpeechConfig. Al igual que en el ejemplo de la sección anterior, se usa AudioDataStream para obtener una secuencia en memoria del resultado y, después, escribirla en un archivo.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");

    // set the output format
    speechConfig.setSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);
    SpeechSynthesisResult result = synthesizer.SpeakText("Customizing audio output format.");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

Si vuelve a ejecutar el programa, se escribirá un archivo .wav en la ruta de acceso especificada.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función SpeakText(), se usa SpeakSsml(). Esta función espera una cadena XML, por lo que primero debe crear una función para cargar un archivo XML y devolverlo como una cadena.

private static String xmlToString(String filePath) {
    File file = new File(filePath);
    StringBuilder fileContents = new StringBuilder((int)file.length());

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString().trim();
    } catch (FileNotFoundException ex) {
        return "File not found.";
    }
}

Desde aquí, el objeto del resultado es exactamente el mismo que el de los ejemplos anteriores.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    SpeechSynthesizer synthesizer = new SpeechSynthesizer(speechConfig, null);

    String ssml = xmlToString("ssml.xml");
    SpeechSynthesisResult result = synthesizer.SpeakSsml(ssml);
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante SpeechConfig.setSpeechSynthesisVoiceName("en-US-ChristopherNeural");

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse a eventos de visema en el SDK de voz para obtener datos de animaciones faciales y, luego, aplicar los datos a un personaje durante la animación facial. Aprenda a obtener eventos de visema.

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de JavaScript en GitHub.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio Voz. Si no dispone de una cuenta y un recurso, pruebe el servicio Voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar Speech SDK para JavaScript. Utilice las siguientes instrucciones en función de la plataforma:

Además, en función del entorno de destino, use una de las siguientes:

Descargue y extraiga el archivo microsoft.cognitiveservices.speech.sdk.bundle.js de Speech SDK para JavaScript y colóquelo en una carpeta accesible para el archivo HTML.

<script src="microsoft.cognitiveservices.speech.sdk.bundle.js"></script>;

Sugerencia

Si el destino es un explorador web y usa la etiqueta <script>, el prefijo sdk no es necesario. El prefijo sdk es un alias que se usa para asignar un nombre al módulo require.

Creación de una configuración de voz

Para llamar al servicio de voz con Speech SDK, debe crear un elemento SpeechConfig. Esta clase incluye información sobre el recurso, como la clave de voz y la región o ubicación asociada, el punto de conexión, el host, o el token de autorización.

Nota

Debe crear siempre una configuración, independientemente de si va a realizar reconocimiento de voz, síntesis de voz, traducción o reconocimiento de intenciones.

Existen diversas maneras para inicializar un elemento SpeechConfig:

  • Con un recurso: pase una clave de voz y la región o ubicación asociada.
  • Con un punto de conexión: pase un punto de conexión del servicio de voz. La clave de voz y el token de autorización son opcionales.
  • Con un host: pase una dirección de host. La clave de voz y el token de autorización son opcionales.
  • Con un token de autorización: pase el token de autorización y la región o ubicación asociadas.

En este ejemplo, se crea un elemento SpeechConfig mediante una clave de voz y una región o ubicación. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz. Cree también código reutilizable básico para usarlo en el resto del artículo y que modificará cuando realice distintas personalizaciones.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
}

synthesizeSpeech();

Selección del idioma y la voz de síntesis

El servicio Text to Speech de Azure admite más de 250 voces y más de 70 idiomas y variantes. Puede obtener la lista completa o probarlos en la demostración de texto a voz. Especifique el idioma o la voz de SpeechConfig para que coincida con el texto de entrada y usar la voz que prefiera.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    // Note: if only language is set, the default voice of that language is chosen.
    speechConfig.speechSynthesisLanguage = "<your-synthesis-language>"; // e.g. "de-DE"
    // The voice setting will overwrite language setting.
    // The voice setting will not overwrite the voice element in input SSML.
    speechConfig.speechSynthesisVoiceName = "<your-wanted-voice>";
}

synthesizeSpeech();

Síntesis de voz en un archivo

A continuación, creará un objeto SpeechSynthesizer, que ejecuta conversiones de texto a voz y envía la salida a altavoces, archivos u otros flujos de salida. SpeechSynthesizer acepta como parámetros tanto el objeto SpeechConfig que se creó creado en el paso anterior y un objeto AudioConfig que especifica cómo se deben controlar los resultados de la salida.

Para empezar, cree un objeto AudioConfig para escribir automáticamente la salida en un archivo .wav mediante la función estática fromAudioFileOutput().

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput("path/to/file.wav");
}

Luego, cree una instancia de SpeechSynthesizer y use los objetos speechConfig y audioConfig como parámetros. Después, para ejecutar la síntesis de voz y realizar la escritura en un archivo solo hay que ejecutar speakTextAsync() con una cadena de texto. La devolución de llamada de resultados es una excelente ubicación para llamar a synthesizer.close(); de hecho, esta llamada es necesaria para que la síntesis funcione correctamente.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput("path-to-file.wav");

    const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.speakTextAsync(
        "A simple test to write to a file.",
        result => {
            synthesizer.close();
            if (result) {
                // return result as stream
                return fs.createReadStream("path-to-file.wav");
            }
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

Ejecute el programa y se escribirá un archivo .wav sintetizado en la ubicación que haya especificado. Este es un buen ejemplo del uso más básico, pero a continuación puede examinar cómo personalizar la salida y controlar la respuesta de la salida como una secuencia en memoria para trabajar con escenarios personalizados.

Síntesis a la salida de altavoz (solo explorador)

En algunos casos, puede que desee enviar la voz sintetizada directamente a un altavoz. Para ello, cree una instancia de AudioConfig mediante la función estática fromDefaultSpeakerOutput(). De esta forma, la salida s realiza a través del dispositivo de salida activo actual.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();

    const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    synthesizer.speakTextAsync(
        "Synthesizing directly to speaker output.",
        result => {
            if (result) {
                synthesizer.close();
                return result.audioData;
            }
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

Obtención del resultado en forma de secuencia en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite el bloqueo de AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use undefined en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar undefined en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. La propiedad SpeechSynthesisResult.audioData devuelve un ArrayBuffer de los datos de salida, el tipo de flujo de datos del explorador predeterminado. En el caso del código de servidor, convierta arrayBuffer en un flujo del búfer.

El código siguiente funciona para el código del lado cliente.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig);

    synthesizer.speakTextAsync(
        "Getting the response as an in-memory stream.",
        result => {
            synthesizer.close();
            return result.audioData;
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

A partir de aquí se puede implementar cualquier comportamiento personalizado mediante el objeto ArrayBuffer resultante. ArrayBuffer es un tipo común que se recibe en un explorador y se reproduce desde este formato.

En el caso de cualquier código basado en servidor, si necesita trabajar con los datos como un flujo, en lugar de un ArrayBuffer, debe convertir el objeto en un flujo.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig);

    synthesizer.speakTextAsync(
        "Getting the response as an in-memory stream.",
        result => {
            const { audioData } = result;

            synthesizer.close();

            // convert arrayBuffer to stream
            // return stream
            const bufferStream = new PassThrough();
            bufferStream.end(Buffer.from(audioData));
            return bufferStream;
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

Personalización del formato de audio

En la siguiente sección se muestra cómo personalizar los atributos de la salida de audio, entre los que se incluyen:

  • Tipo de archivo de audio
  • Frecuencia de muestreo
  • Profundidad de bits

Para cambiar el formato de audio, se usa la propiedad speechSynthesisOutputFormat en el objeto SpeechConfig. Esta propiedad espera un elemento enum del tipo SpeechSynthesisOutputFormat, que se usa para seleccionar el formato de salida. En los documentos de referencia encontrará una lista de los formatos de audio disponibles.

Hay varias opciones para los distintos tipos de archivo, por lo que puede elegir la que necesite. Tenga en cuenta que, por definición, los formatos sin procesar, como Raw24Khz16BitMonoPcm, no incluyen encabezados de audio. Los formatos sin procesar solo se deben usar cuando se sepa que la implementación de bajada puede descodificar una secuencia de bits sin procesar, o bien si planea crear manualmente encabezados basados en la profundidad de bits, la frecuencia de muestreo, el número de canales, etc.

En este ejemplo, se especifica un formato RIFF de alta fidelidad Riff24Khz16BitMonoPcm, para lo que se establece speechSynthesisOutputFormat en el objeto SpeechConfig. De forma similar al ejemplo de la sección anterior, obtenga los datos de ArrayBuffer de audio e interactúe con ellos.

function synthesizeSpeech() {
    const speechConfig = SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");

    // Set the output format
    speechConfig.speechSynthesisOutputFormat = SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm;

    const synthesizer = new sdk.SpeechSynthesizer(speechConfig, undefined);
    synthesizer.speakTextAsync(
        "Customizing audio output format.",
        result => {
            // Interact with the audio ArrayBuffer data
            const audioData = result.audioData;
            console.log(`Audio data byte size: ${audioData.byteLength}.`)

            synthesizer.close();
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

Si vuelve a ejecutar el programa, se escribirá un archivo .wav en la ruta de acceso especificada.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función speakTextAsync(), se usa speakSsmlAsync(). Esta función espera una cadena XML, por lo que primero debe crear una función para cargar un archivo XML y devolverlo como una cadena.

function xmlToString(filePath) {
    const xml = readFileSync(filePath, "utf8");
    return xml;
}

Para más información sobre readFileSync, consulte Node.js file system (Sistema de archivos de Node.js). Desde aquí, el objeto del resultado es exactamente el mismo que el de los ejemplos anteriores.

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("<paste-your-speech-key-here>", "<paste-your-speech-location/region-here>");
    const synthesizer = new sdk.SpeechSynthesizer(speechConfig, undefined);

    const ssml = xmlToString("ssml.xml");
    synthesizer.speakSsmlAsync(
        ssml,
        result => {
            if (result.errorDetails) {
                console.error(result.errorDetails);
            } else {
                console.log(JSON.stringify(result));
            }

            synthesizer.close();
        },
        error => {
            console.log(error);
            synthesizer.close();
        });
}

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante SpeechConfig.speechSynthesisVoiceName = "en-US-ChristopherNeural";

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse al evento viseme en Speech SDK. Después, puede aplicar eventos de visema para animar la cara de un personaje mientras se reproduce el audio de voz. Aprenda a obtener eventos de visema.

Puede sintetizar la voz a partir del texto mediante el SDK de Voz para Swift y Objective-C.

Requisitos previos

En los ejemplos siguientes se da por sentado que tiene una cuenta de Azure y una suscripción al servicio Voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación del SDK de Voz y ejemplos

El SDK de Voz de Cognitive Services contiene ejemplos escritos en escritos en Swift y Objective-C para iOS y Mac. Haga clic en un vínculo para ver las instrucciones de instalación de cada ejemplo:

También proporcionamos un SDK de Voz de referencia de Objective-C en línea.

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Pasar a los ejemplos en GitHub

Si quiere pasar directamente al código de ejemplo, consulte los ejemplos del inicio rápido de Python en GitHub.

Prerrequisitos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Instalación de Speech SDK

En primer lugar, deberá instalar Speech SDK.

pip install azure-cognitiveservices-speech

Si trabaja en macOS y tiene problemas de instalación, puede que tenga que ejecutar este comando primero.

python3 -m pip install --upgrade pip

Una vez que se haya instalado el SDK de voz, incluya las siguientes instrucciones de importación en la parte superior del script.

from azure.cognitiveservices.speech import AudioDataStream, SpeechConfig, SpeechSynthesizer, SpeechSynthesisOutputFormat
from azure.cognitiveservices.speech.audio import AudioOutputConfig

Creación de una configuración de voz

Para llamar al servicio de voz con Speech SDK, debe crear un elemento SpeechConfig. Esta clase incluye información sobre la suscripción, como la clave de voz y la región o ubicación asociada, el punto de conexión, el host, o el token de autorización.

Nota

Debe crear siempre una configuración, independientemente de si va a realizar reconocimiento de voz, síntesis de voz, traducción o reconocimiento de intenciones.

Existen diversas maneras para inicializar un elemento SpeechConfig:

  • Con una suscripción: pase una clave de voz y la región o ubicación asociadas.
  • Con un punto de conexión: pase un punto de conexión del servicio de voz. La clave de voz y el token de autorización son opcionales.
  • Con un host: pase una dirección de host. La clave de voz y el token de autorización son opcionales.
  • Con un token de autorización: pase el token de autorización y la región o ubicación asociadas.

En este ejemplo, se crea un elemento SpeechConfig mediante una clave de voz y una región o ubicación. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz.

speech_config = SpeechConfig(subscription="<paste-your-speech-key-here>", region="<paste-your-speech-location/region-here>")

Selección del idioma y la voz de síntesis

El servicio Text to Speech de Azure admite más de 250 voces y más de 70 idiomas y variantes. Puede obtener la lista completa o probarlos en la demostración de texto a voz. Especifique el idioma o la voz de SpeechConfig para que coincida con el texto de entrada y usar la voz que prefiera.

# Note: if only language is set, the default voice of that language is chosen.
speech_config.speech_synthesis_language = "<your-synthesis-language>" # e.g. "de-DE"
# The voice setting will overwrite language setting.
# The voice setting will not overwrite the voice element in input SSML.
speech_config.speech_synthesis_voice_name ="<your-wanted-voice>"

Síntesis de voz en un archivo

A continuación, creará un objeto SpeechSynthesizer, que ejecuta conversiones de texto a voz y envía la salida a altavoces, archivos u otros flujos de salida. SpeechSynthesizer acepta como parámetros tanto el objeto SpeechConfig que se creó creado en el paso anterior y un objeto AudioOutputConfig que especifica cómo se deben controlar los resultados de la salida.

Para empezar, cree un objeto AudioOutputConfig para escribir automáticamente la salida en un archivo .wav mediante el parámetro de constructor filename.

audio_config = AudioOutputConfig(filename="path/to/write/file.wav")

Luego, cree una instancia de SpeechSynthesizer y use los objetos speech_config y audio_config como parámetros. Después, para ejecutar la síntesis de voz y realizar la escritura en un archivo solo hay que ejecutar speak_text_async() con una cadena de texto.

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
synthesizer.speak_text_async("A simple test to write to a file.")

Ejecute el programa y se escribirá un archivo .wav sintetizado en la ubicación que haya especificado. Este es un buen ejemplo del uso más básico, pero a continuación puede examinar cómo personalizar la salida y controlar la respuesta de la salida como una secuencia en memoria para trabajar con escenarios personalizados.

Síntesis a la salida de altavoz

En algunos casos, puede que desee enviar la voz sintetizada directamente a un altavoz. Para ello, use el ejemplo de la sección anterior, pero cambie AudioOutputConfig, para lo que debe quitar el parámetro filename y establecer use_default_speaker=True. De esta forma, la salida s realiza a través del dispositivo de salida activo actual.

audio_config = AudioOutputConfig(use_default_speaker=True)

Obtención del resultado en forma de secuencia en memoria

Para muchos de los escenarios del desarrollo de aplicaciones de voz, es probable que necesite los datos de audio resultantes en forma de secuencia en memoria, en lugar de que se escriban directamente en un archivo. Esto le permitirá crear un comportamiento personalizado, lo que incluye:

  • Abstraer la matriz de bytes resultante como una secuencia que permita la búsqueda para los servicios de bajada personalizados.
  • Integrar el resultado con otros servicios o API.
  • Modificar los datos de audio, escribir encabezados .wav personalizados, etc.

Es sencillo hacer este cambio en el ejemplo anterior. En primer lugar, quite AudioConfig, porque a partir de este momento administrará el comportamiento de la salida de forma manual, ya que así obtiene mayor control. Después, use None en AudioConfig en el constructor SpeechSynthesizer.

Nota

Al usar None en AudioConfig, en lugar de omitirlo como en el ejemplo de salida del altavoz anterior, el audio no se reproducirá de forma predeterminada en el dispositivo de salida activo actual.

Esta vez se guarda el resultado en una variable SpeechSynthesisResult. La propiedad audio_data contiene un objeto bytes de los datos de salida. Puede trabajar con este objeto manualmente, o bien puede usar la clase AudioDataStream para administrar la secuencia en memoria. En este ejemplo, se usa el constructor AudioDataStream para obtener una secuencia del resultado.

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)
result = synthesizer.speak_text_async("Getting the response as an in-memory stream.").get()
stream = AudioDataStream(result)

A partir de aquí se puede implementar cualquier comportamiento personalizado mediante el objeto stream resultante.

Personalización del formato de audio

En la siguiente sección se muestra cómo personalizar los atributos de la salida de audio, entre los que se incluyen:

  • Tipo de archivo de audio
  • Frecuencia de muestreo
  • Profundidad de bits

Para cambiar el formato de audio se usa la función set_speech_synthesis_output_format() en el objeto SpeechConfig. Esta función espera un elemento enum del tipo SpeechSynthesisOutputFormat, que se usa para seleccionar el formato de salida. En los documentos de referencia encontrará una lista de los formatos de audio disponibles.

Hay varias opciones para los distintos tipos de archivo, por lo que puede elegir la que necesite. Tenga en cuenta que, por definición, los formatos sin procesar, como Raw24Khz16BitMonoPcm, no incluyen encabezados de audio. Los formatos sin procesar solo se deben usar cuando se sepa que la implementación de bajada puede descodificar una secuencia de bits sin procesar, o bien si planea crear manualmente encabezados basados en la profundidad de bits, la frecuencia de muestreo, el número de canales, etc.

En este ejemplo, se especifica un formato RIFF de alta fidelidad Riff24Khz16BitMonoPcm, para lo que se establece SpeechSynthesisOutputFormat en el objeto SpeechConfig. Al igual que en el ejemplo de la sección anterior, se usa AudioDataStream para obtener una secuencia en memoria del resultado y, después, escribirla en un archivo.

speech_config.set_speech_synthesis_output_format(SpeechSynthesisOutputFormat["Riff24Khz16BitMonoPcm"])
synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)

result = synthesizer.speak_text_async("Customizing audio output format.").get()
stream = AudioDataStream(result)
stream.save_to_wav_file("path/to/write/file.wav")

Si vuelve a ejecutar el programa, se escribirá un archivo .wav personalizado en la ruta de acceso especificada.

Uso de SSML para personalizar las características de la voz

El lenguaje de marcado de síntesis de voz (SSML) permite ajustar el tono, la pronunciación, la velocidad del habla, el volumen, etc. de la salida de texto a voz mediante el envío de solicitudes desde un lenguaje de definición de esquema XML. En esta sección se muestra un ejemplo de cambio de voz, pero para obtener una guía más detallada, consulte el artículo de procedimientos de SSML.

Para empezar a usar SSML para la personalización, realice un cambio sencillo que cambie la voz. En primer lugar, cree un archivo XML para la configuración de SSML en el directorio raíz del proyecto, en este ejemplo ssml.xml. El elemento raíz es siempre <speak> y si se ajusta el texto en un elemento <voice>, se puede cambiar la voz mediante el parámetro name. Consulte la lista completa de voces neuronales admitidas.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-ChristopherNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

A continuación, debe cambiar la solicitud de síntesis de voz para que haga referencia al archivo XML. La solicitud es básicamente la misma, pero en lugar de usar la función speak_text_async(), se usa speak_ssml_async(). Esta función espera una cadena XML, por lo que lo primero que se debe hacer es leer la configuración de SSML como una cadena. Desde aquí, el objeto de resultado es exactamente el mismo que el de los ejemplos anteriores.

Nota

Si ssml_string contiene  al principio de la cadena, debe quitar el formato de BOM o el servicio devolverá un error. Para ello, establezca el parámetro encoding como sigue: open("ssml.xml", "r", encoding="utf-8-sig").

synthesizer = SpeechSynthesizer(speech_config=speech_config, audio_config=None)

ssml_string = open("ssml.xml", "r").read()
result = synthesizer.speak_ssml_async(ssml_string).get()

stream = AudioDataStream(result)
stream.save_to_wav_file("path/to/write/file.wav")

Nota

Para cambiar la voz sin usar SSML, puede establecer la propiedad en SpeechConfig mediante SpeechConfig.speech_synthesis_voice_name = "en-US-ChristopherNeural"

Obtención de eventos de postura facial

La voz puede ser una buena forma de dotar de animación a las expresiones faciales. Para representar las posiciones principales en el habla observada, como la colocación de los labios, la mandíbula y la lengua al producir un fonema determinado, con frecuencia se usan visemas. Puede suscribirse al evento viseme en Speech SDK. Después, puede aplicar eventos de visema para animar la cara de un personaje mientras se reproduce el audio de voz. Aprenda a obtener eventos de visema.

En este inicio rápido, aprenderá a convertir texto a voz mediante el servicio de voz y cURL.

Para obtener una visión general de los conceptos de la conversión de texto a voz, consulte el artículo en el que se proporciona información general.

Requisitos previos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Conversión de texto en voz

En el símbolo del sistema, ejecute el siguiente comando. Tendrá que insertar los siguientes valores en el comando.

  • Clave de suscripción del servicio de voz.
  • Región del servicio de voz.

Es posible que también quiera cambiar los siguientes valores.

  • El valor del encabezado X-Microsoft-OutputFormat, que controla el formato de la salida de audio. Puede encontrar una lista de formatos de salida de audio compatibles en la referencia de la API REST de texto a voz.
  • Voz de salida. Para obtener una lista de las voces disponibles para el punto de conexión de Voz, consulte la sección siguiente.
  • Archivo de salida. En este ejemplo, la respuesta del servidor se dirige a un archivo denominado output.wav.
curl --location --request POST 'https://INSERT_REGION_HERE.tts.speech.microsoft.com/cognitiveservices/v1' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: application/ssml+xml' \
--header 'X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3' \
--header 'User-Agent: curl' \
--data-raw '<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
    <voice xml:lang='\''en-US'\'' xml:gender='\''Female'\'' name='\''en-US-JennyNeural'\''>
        my voice is my passport verify me
    </voice>
</speak>' > output.mp3

Enumeración de las voces disponibles para el punto de conexión de Voz

Para enumerar las voces disponibles para el punto de conexión de Voz, ejecute el siguiente comando.

curl --location --request GET 'https://INSERT_ENDPOINT_HERE.tts.speech.microsoft.com/cognitiveservices/voices/list' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE'

Debería recibir una respuesta similar a la siguiente.

[
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (ar-EG, Hoda)",
        "DisplayName": "Hoda",
        "LocalName": "هدى",
        "ShortName": "ar-EG-Hoda",
        "Gender": "Female",
        "Locale": "ar-EG",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (ar-SA, Naayf)",
        "DisplayName": "Naayf",
        "LocalName": "نايف",
        "ShortName": "ar-SA-Naayf",
        "Gender": "Male",
        "Locale": "ar-SA",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        "Name": "Microsoft Server Speech Text to Speech Voice (bg-BG, Ivan)",
        "DisplayName": "Ivan",
        "LocalName": "Иван",
        "ShortName": "bg-BG-Ivan",
        "Gender": "Male",
        "Locale": "bg-BG",
        "SampleRateHertz": "16000",
        "VoiceType": "Standard"
    },
    {
        // This response is truncated. The response will include 
        // a complete list of supported languages and specific 
        // details like short name, gender, etc. 
    }
]

En este inicio rápido aprenderá patrones de diseño comunes para realizar la síntesis de texto a voz mediante el SDK de voz. Para empezar, puede realizar una configuración y síntesis básicas y, después, pasar a ejemplos más avanzados para el desarrollo de aplicaciones personalizadas, entre las que se incluyen:

  • Obtención de respuestas como flujos de datos en memoria
  • Personalización de la frecuencia de muestreo y la velocidad de bits de salida
  • Envío de solicitudes de síntesis mediante SSML (lenguaje de marcado de síntesis de voz)
  • Uso de voces neuronales

Prerrequisitos

En este artículo se da por sentado que tiene una cuenta de Azure y una suscripción al servicio de voz. Si no dispone de una cuenta y una suscripción, pruebe el servicio de voz de forma gratuita.

Descargar e instalar

Siga estos pasos para instalar la CLI de Voz en Windows:

  1. En Windows, necesita Microsoft Visual C++ Redistributable para Visual Studio 2019 para su plataforma. Durante la primera instalación es posible que deba reiniciar.

  2. Instale el SDK de .NET Core 3.1.

  3. Para instalar la CLI de Voz para que use NuGet, escriba este comando:

    dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
    

Escriba spx para ver la ayuda de la CLI de Voz.

Nota

Como alternativa a NuGet, puede descargar y extraer la CLI de Voz para Windows como un archivo ZIP.

Limitaciones de fuentes

En Windows, la CLI de Voz solo puede mostrar las fuentes disponibles para el símbolo del sistema en el equipo local. El terminal de Windows admite todas las fuentes que genera de forma interactiva la CLI de Voz.

Si se genera la salida a un archivo, un editor de texto como el Bloc de notas o un explorador Web como Microsoft Edge también pueden mostrar todas las fuentes.

Creación de la configuración de la suscripción

Si desea empezar a usar la CLI de Voz, debe especificar la clave de la suscripción al servicio de voz y la información de la región. Para obtener estas credenciales, siga los pasos descritos en Prueba gratuita del servicio Voz. Una vez que tenga la clave de suscripción y el identificador de región (p. ej., eastus, westus), ejecute los comandos siguientes.

spx config @key --set SUBSCRIPTION-KEY
spx config @region --set REGION

La autenticación de la suscripción se almacena ahora para futuras solicitudes de SPX. Si tiene que quitar cualquiera de estos valores almacenados, ejecute spx config @region --clear o spx config @key --clear.

Síntesis de voz en un altavoz

Ahora está listo para ejecutar la CLI de Voz para sintetizar voz a partir de texto. Desde la línea de comandos, cambie al directorio que contiene el archivo binario de la CLI de Voz. Luego, ejecute el siguiente comando.

spx synthesize --text "The speech synthesizer greets you!"

La CLI de Voz creará un lenguaje natural en inglés a través del altavoz del equipo.

Síntesis de voz en un archivo

Ejecute el siguiente comando para cambiar la salida del altavoz a un archivo .wav.

spx synthesize --text "The speech synthesizer greets you!" --audio output greetings.wav

La CLI de Voz generará lenguaje natural en inglés en el archivo de audio greetings.wav. En Windows, puede reproducir el archivo de audio escribiendo start greetings.wav.

Obtención de información de posición

Es posible que el proyecto necesite saber cuándo se pronuncia una palabra mediante la conversión de texto a voz para que pueda llevar a cabo acciones específicas en función de ese tiempo. Por ejemplo, si desea resaltar palabras a medida que se pronuncian, debe saber qué resaltar, cuándo hacerlo y durante cuánto tiempo se debe resaltar.

Para ello, puede usar el evento WordBoundary disponible en SpeechSynthesizer. Este evento se desencadena al principio de cada nuevo texto oral y proporcionará un desfase de tiempo dentro del flujo hablado, así como un desplazamiento de texto dentro del indicador de entrada.

  • AudioOffset informa del tiempo transcurrido del audio de salida entre el inicio de la síntesis y el inicio de la siguiente palabra. Se mide en unidades de centenares de nanosegundos (SNP)y 10 000 SNP equivalen a 1 milisegundo.
  • WordOffset notifica la posición de un carácter en la cadena de entrada (texto original o SSML) inmediatamente antes de la palabra que se va a pronunciar.

Nota

Los eventos WordBoundary se generan cuando los datos de audio de salida están disponibles, lo que será más rápido que la reproducción en un dispositivo de salida. El autor de la llamada debe llevar a cabo una sincronización correcta del tiempo de la transmisión con el "tiempo real".

En GitHub, se pueden encontrar ejemplos de uso de WordBoundary en los ejemplos de conversión de texto a voz.

Pasos siguientes