Partilhar via


Como sintetizar a fala a partir do texto

Pacote de documentação | de referência (NuGet) | Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Pode obter a lista completa ou experimentá-los na Galeria de Vozes.

Especifique o idioma ou a voz de para corresponder ao texto de SpeechConfig entrada e use a voz especificada. O trecho de código a seguir mostra como essa técnica funciona:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.SpeechSynthesisLanguage = "en-US"; 
    speechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto é falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especifica usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Sintetizar fala em um arquivo

Crie um objeto SpeechSynthesizer . Esse objeto mostrado nos trechos a seguir executa conversões de texto para fala e saídas para alto-falantes, arquivos ou outros fluxos de saída. SpeechSynthesizer aceita como parâmetros:

  1. Crie uma AudioConfig instância para gravar automaticamente a saída em um arquivo .wav usando a FromWavFileOutput() função. Instancie-o com uma using instrução.

    static async Task SynthesizeAudioAsync()
    {
        var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
        using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    }
    

    Uma using instrução nesse contexto descarta automaticamente recursos não gerenciados e faz com que o objeto saia do escopo após a eliminação.

  2. Instancie uma SpeechSynthesizer instância com outra using instrução. Passe seu speechConfig objeto e o audioConfig objeto como parâmetros. Para sintetizar fala e gravar em um arquivo, execute SpeakTextAsync() com uma cadeia de caracteres de texto.

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}

Quando você executa o programa, ele cria um arquivo .wav sintetizado, que é gravado no local que você especificar. Este resultado é um bom exemplo do uso mais básico. Em seguida, você pode personalizar a saída e manipular a resposta de saída como um fluxo na memória para trabalhar com cenários personalizados.

Sintetizar para saída de alto-falante

Para exportar a fala sintetizada para o dispositivo de saída ativo atual, como um alto-falante, omita o AudioConfig parâmetro ao criar a SpeechSynthesizer instância. Eis um exemplo:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig);
    await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}

Obter um resultado como um fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos de .wav personalizados e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Primeiro, remova o AudioConfig bloco, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o controle. Passe null para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar null por AudioConfig, em vez de omiti-lo como no exemplo de saída de alto-falante anterior, não reproduz o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma variável SpeechSynthesisResult . A AudioData propriedade contém uma byte [] instância para os dados de saída. Você pode trabalhar com essa byte [] instância manualmente ou pode usar a classe AudioDataStream para gerenciar o fluxo na memória.

Neste exemplo, você usa a AudioDataStream.FromResult() função estática para obter um fluxo do resultado:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);

    var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
    using var stream = AudioDataStream.FromResult(result);
}

Neste ponto, você pode implementar qualquer comportamento personalizado usando o objeto resultante stream .

Personalizar formato de áudio

Você pode personalizar atributos de saída de áudio, incluindo:

  • Tipo de ficheiro de áudio
  • Taxa de amostragem
  • Profundidade de bits

Para alterar o formato de áudio, use a SetSpeechSynthesisOutputFormat() SpeechConfig função no objeto. Esta função espera uma enum instância do tipo SpeechSynthesisOutputFormat. Use o enum para selecionar o formato de saída. Para formatos disponíveis, consulte a lista de formatos de áudio.

Existem várias opções para diferentes tipos de ficheiros, dependendo dos seus requisitos. Por definição, formatos brutos como Raw24Khz16BitMonoPcm não incluem cabeçalhos de áudio. Use formatos brutos somente em uma destas situações:

  • Você sabe que sua implementação downstream pode decodificar um fluxo de bits bruto.
  • Você planeja criar cabeçalhos manualmente com base em fatores como profundidade de bits, taxa de amostragem e número de canais.

Este exemplo especifica o formato Riff24Khz16BitMonoPcm RIFF de alta fidelidade definindo SpeechSynthesisOutputFormat no SpeechConfig objeto. Semelhante ao exemplo na seção anterior, você usa AudioDataStream para obter um fluxo na memória do resultado e, em seguida, gravá-lo em um arquivo.

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    speechConfig.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");

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

Quando você executa o programa, ele grava um arquivo de .wav no caminho especificado.

Usar o SSML para personalizar as características de fala

Você pode usar o SSML para ajustar o tom, a pronúncia, a taxa de fala, o volume e outros aspetos na saída de texto para fala enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte Visão geral da linguagem de marcação de síntese de fala.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterna a voz.

  1. Crie um novo arquivo XML para a configuração do SSML no diretório raiz do projeto.

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

    Neste exemplo, o arquivo é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

  2. Altere a solicitação de síntese de fala para fazer referência ao arquivo XML. A solicitação é basicamente a mesma, mas em vez de usar a SpeakTextAsync() função, você usa SpeakSsmlAsync(). Esta função espera uma cadeia de caracteres XML. Primeiro, carregue a configuração do SSML como uma cadeia de caracteres usando File.ReadAllText()o . A partir deste ponto, o objeto result é exatamente o mesmo que os exemplos anteriores.

    Nota

    Se você estiver usando o Visual Studio, sua configuração de compilação provavelmente não encontrará seu arquivo XML por padrão. Clique com o botão direito do mouse no arquivo XML e selecione Propriedades. Altere a ação de compilação para o conteúdo. Altere Copiar para o diretório de saída para Copiar sempre.

    public static async Task SynthesizeAudioAsync()
    {
        var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
        using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    
        var ssml = File.ReadAllText("./ssml.xml");
        var result = await speechSynthesizer.SpeakSsmlAsync(ssml);
    
        using var stream = AudioDataStream.FromResult(result);
        await stream.SaveToWaveFileAsync("path/to/write/file.wav");
    }
    

Nota

Para alterar a voz sem usar SSML, você pode definir a propriedade usando SpeechConfig SpeechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";.

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substituir o conteúdo desse arquivo Program.cs pelo seguinte código C#:

using Microsoft.CognitiveServices.Speech;

class Program 
{
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    static string speechKey = Environment.GetEnvironmentVariable("SPEECH_KEY");
    static string speechRegion = Environment.GetEnvironmentVariable("SPEECH_REGION");

    async static Task Main(string[] args)
    {
        var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
         
        var speechSynthesisVoiceName  = "en-US-AvaMultilingualNeural";  
        var ssml = @$"<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
            <voice name='{speechSynthesisVoiceName}'>
                <mstts:viseme type='redlips_front'/>
                The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
            </voice>
        </speak>";

        // Required for sentence-level WordBoundary events
        speechConfig.SetProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

        using (var speechSynthesizer = new SpeechSynthesizer(speechConfig))
        {
            // Subscribe to events

            speechSynthesizer.BookmarkReached += (s, e) =>
            {
                Console.WriteLine($"BookmarkReached event:" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tText: \"{e.Text}\".");
            };

            speechSynthesizer.SynthesisCanceled += (s, e) =>
            {
                Console.WriteLine("SynthesisCanceled event");
            };

            speechSynthesizer.SynthesisCompleted += (s, e) =>
            {                
                Console.WriteLine($"SynthesisCompleted event:" +
                    $"\r\n\tAudioData: {e.Result.AudioData.Length} bytes" +
                    $"\r\n\tAudioDuration: {e.Result.AudioDuration}");
            };

            speechSynthesizer.SynthesisStarted += (s, e) =>
            {
                Console.WriteLine("SynthesisStarted event");
            };

            speechSynthesizer.Synthesizing += (s, e) =>
            {
                Console.WriteLine($"Synthesizing event:" +
                    $"\r\n\tAudioData: {e.Result.AudioData.Length} bytes");
            };

            speechSynthesizer.VisemeReceived += (s, e) =>
            {
                Console.WriteLine($"VisemeReceived event:" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tVisemeId: {e.VisemeId}");
            };

            speechSynthesizer.WordBoundary += (s, e) =>
            {
                Console.WriteLine($"WordBoundary event:" +
                    // Word, Punctuation, or Sentence
                    $"\r\n\tBoundaryType: {e.BoundaryType}" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tDuration: {e.Duration}" +
                    $"\r\n\tText: \"{e.Text}\"" +
                    $"\r\n\tTextOffset: {e.TextOffset}" +
                    $"\r\n\tWordLength: {e.WordLength}");
            };

            // Synthesize the SSML
            Console.WriteLine($"SSML to synthesize: \r\n{ssml}");
            var speechSynthesisResult = await speechSynthesizer.SpeakSsmlAsync(ssml);

            // Output the results
            switch (speechSynthesisResult.Reason)
            {
                case ResultReason.SynthesizingAudioCompleted:
                    Console.WriteLine("SynthesizingAudioCompleted result");
                    break;
                case ResultReason.Canceled:
                    var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult);
                    Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

                    if (cancellation.Reason == CancellationReason.Error)
                    {
                        Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                        Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
                        Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
                    }
                    break;
                default:
                    break;
            }
        }

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

Você pode encontrar mais exemplos de texto para fala no GitHub.

Usar um ponto de extremidade personalizado

O ponto de extremidade personalizado é funcionalmente idêntico ao ponto de extremidade padrão usado para solicitações de texto para fala.

Uma diferença é que o EndpointId deve ser especificado para usar sua voz personalizada por meio do SDK de fala. Você pode começar com o início rápido de texto para fala e, em seguida, atualizar o código com o EndpointId e SpeechSynthesisVoiceName.

var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);     
speechConfig.SpeechSynthesisVoiceName = "YourCustomVoiceName";
speechConfig.EndpointId = "YourEndpointId";

Para usar uma voz personalizada por meio do SSML (Speech Synthesis Markup Language), especifique o nome do modelo como o nome da voz. Este exemplo usa a YourCustomVoiceName voz.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (NuGet) | Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Consulte a lista completa de locais de texto para fala suportados ou experimente-os na Galeria de voz.

Especifique o idioma ou a voz da classe SpeechConfig para corresponder ao texto de entrada e use a voz especificada. O trecho de código a seguir mostra como essa técnica funciona:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig->SetSpeechSynthesisLanguage("en-US"); 
    speechConfig->SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto será falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especifica usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Sintetizar fala em um arquivo

Crie um objeto SpeechSynthesizer . Esse objeto mostrado nos trechos a seguir executa conversões de texto para fala e saídas para alto-falantes, arquivos ou outros fluxos de saída. SpeechSynthesizer aceita como parâmetros:

  1. Crie uma AudioConfig instância para gravar automaticamente a saída em um arquivo .wav usando a FromWavFileOutput() função:

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
    }
    
  2. Instanciar uma SpeechSynthesizer instância. Passe seu speechConfig objeto e o audioConfig objeto como parâmetros. Para sintetizar fala e gravar em um arquivo, execute SpeakTextAsync() com uma cadeia de caracteres de texto.

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
        auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig, audioConfig);
        auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get();
    }
    

Quando você executa o programa, ele cria um arquivo .wav sintetizado, que é gravado no local que você especificar. Este resultado é um bom exemplo do uso mais básico. Em seguida, você pode personalizar a saída e manipular a resposta de saída como um fluxo na memória para trabalhar com cenários personalizados.

Sintetizar para saída de alto-falante

Para exportar a fala sintetizada para o dispositivo de saída ativo atual, como um alto-falante, omita o AudioConfig parâmetro ao criar a SpeechSynthesizer instância. Eis um exemplo:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    auto result = speechSynthesizer->SpeakTextAsync("I'm excited to try text to speech").get();
}

Obter um resultado como um fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos de .wav personalizados e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Primeiro, remova o AudioConfig bloco, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o controle. Passe NULL para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar NULL por AudioConfig, em vez de omiti-lo como no exemplo de saída de alto-falante anterior, não reproduz o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma variável SpeechSynthesisResult . O GetAudioData getter retorna uma byte [] instância para os dados de saída. Você pode trabalhar com essa byte [] instância manualmente ou pode usar a classe AudioDataStream para gerenciar o fluxo na memória.

Neste exemplo, use a AudioDataStream.FromResult() função estática para obter um fluxo do resultado:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);

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

Neste ponto, você pode implementar qualquer comportamento personalizado usando o objeto resultante stream .

Personalizar formato de áudio

Você pode personalizar atributos de saída de áudio, incluindo:

  • Tipo de ficheiro de áudio
  • Taxa de amostragem
  • Profundidade de bits

Para alterar o formato de áudio, use a SetSpeechSynthesisOutputFormat() SpeechConfig função no objeto. Esta função espera uma enum instância do tipo SpeechSynthesisOutputFormat. Use o enum para selecionar o formato de saída. Para formatos disponíveis, consulte a lista de formatos de áudio.

Existem várias opções para diferentes tipos de ficheiros, dependendo dos seus requisitos. Por definição, formatos brutos como Raw24Khz16BitMonoPcm não incluem cabeçalhos de áudio. Use formatos brutos somente em uma destas situações:

  • Você sabe que sua implementação downstream pode decodificar um fluxo de bits bruto.
  • Você planeja criar cabeçalhos manualmente com base em fatores como profundidade de bits, taxa de amostragem e número de canais.

Este exemplo especifica o formato Riff24Khz16BitMonoPcm RIFF de alta fidelidade definindo SpeechSynthesisOutputFormat no SpeechConfig objeto. Semelhante ao exemplo na seção anterior, você usa AudioDataStream para obter um fluxo na memória do resultado e, em seguida, gravá-lo em um arquivo.

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    speechConfig->SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat::Riff24Khz16BitMonoPcm);

    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get();

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

Quando você executa o programa, ele grava um arquivo de .wav no caminho especificado.

Usar o SSML para personalizar as características de fala

Você pode usar o SSML para ajustar o tom, a pronúncia, a taxa de fala, o volume e outros aspetos na saída de texto para fala enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte Visão geral da linguagem de marcação de síntese de fala.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterne a voz.

  1. Crie um novo arquivo XML para a configuração do SSML no diretório raiz do projeto.

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

    Neste exemplo, o arquivo é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

  2. Altere a solicitação de síntese de fala para fazer referência ao arquivo XML. O pedido é praticamente o mesmo. Em vez de usar a SpeakTextAsync() função, você usa SpeakSsmlAsync(). Esta função espera uma cadeia de caracteres XML. Primeiro, carregue a configuração do SSML como uma cadeia de caracteres. A partir deste ponto, o objeto result é exatamente o mesmo que os exemplos anteriores.

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    
        std::ifstream file("./ssml.xml");
        std::string ssml, line;
        while (std::getline(file, line))
        {
            ssml += line;
            ssml.push_back('\n');
        }
        auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get();
    
        auto stream = AudioDataStream::FromResult(result);
        stream->SaveToWavFileAsync("path/to/write/file.wav").get();
    }
    

Nota

Para alterar a voz sem usar SSML, você pode definir a propriedade usando SpeechConfig SpeechConfig.SetSpeechSynthesisVoiceName("en-US-AndrewMultilingualNeural").

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substitua o conteúdo desse arquivo main.cpp pelo seguinte código:

#include <iostream> 
#include <stdlib.h>
#include <speechapi_cxx.h>

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

std::string getEnvironmentVariable(const char* name);

int main()
{
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    auto speechKey = getEnvironmentVariable("SPEECH_KEY");
    auto speechRegion = getEnvironmentVariable("SPEECH_REGION");

    if ((size(speechKey) == 0) || (size(speechRegion) == 0)) {
        std::cout << "Please set both SPEECH_KEY and SPEECH_REGION environment variables." << std::endl;
        return -1;
    }

    auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);

    // Required for WordBoundary event sentences.
    speechConfig->SetProperty(PropertyId::SpeechServiceResponse_RequestSentenceBoundary, "true");

    const auto ssml = R"(<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
        <voice name = 'en-US-AvaMultilingualNeural'>
            <mstts:viseme type = 'redlips_front' />
            The rainbow has seven colors : <bookmark mark = 'colors_list_begin' />Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark = 'colors_list_end' />.
        </voice>
        </speak>)";

    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);

    // Subscribe to events

    speechSynthesizer->BookmarkReached += [](const SpeechSynthesisBookmarkEventArgs& e)
    {
        std::cout << "Bookmark reached. "
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tText: " << e.Text << std::endl;
    };

    speechSynthesizer->SynthesisCanceled += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "SynthesisCanceled event" << std::endl;
    };

    speechSynthesizer->SynthesisCompleted += [](const SpeechSynthesisEventArgs& e)
    {
        auto audioDuration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Result->AudioDuration).count();

        std::cout << "SynthesisCompleted event:"
            << "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes"
            << "\r\n\tAudioDuration: " << audioDuration << std::endl;
    };

    speechSynthesizer->SynthesisStarted += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "SynthesisStarted event" << std::endl;
    };

    speechSynthesizer->Synthesizing += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "Synthesizing event:"
            << "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes" << std::endl;
    };

    speechSynthesizer->VisemeReceived += [](const SpeechSynthesisVisemeEventArgs& e)
    {
        std::cout << "VisemeReceived event:"
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tVisemeId: " << e.VisemeId << std::endl;
    };

    speechSynthesizer->WordBoundary += [](const SpeechSynthesisWordBoundaryEventArgs& e)
    {
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Duration).count();
        
        auto boundaryType = "";
        switch (e.BoundaryType) {
        case SpeechSynthesisBoundaryType::Punctuation:
            boundaryType = "Punctuation";
            break;
        case SpeechSynthesisBoundaryType::Sentence:
            boundaryType = "Sentence";
            break;
        case SpeechSynthesisBoundaryType::Word:
            boundaryType = "Word";
            break;
        }

        std::cout << "WordBoundary event:"
            // Word, Punctuation, or Sentence
            << "\r\n\tBoundaryType: " << boundaryType
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tDuration: " << duration
            << "\r\n\tText: \"" << e.Text << "\""
            << "\r\n\tTextOffset: " << e.TextOffset
            << "\r\n\tWordLength: " << e.WordLength << std::endl;
    };

    auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get();

    // Checks result.
    if (result->Reason == ResultReason::SynthesizingAudioCompleted)
    {
        std::cout << "SynthesizingAudioCompleted result" << std::endl;
    }
    else if (result->Reason == ResultReason::Canceled)
    {
        auto cancellation = SpeechSynthesisCancellationDetails::FromResult(result);
        std::cout << "CANCELED: Reason=" << (int)cancellation->Reason << std::endl;

        if (cancellation->Reason == CancellationReason::Error)
        {
            std::cout << "CANCELED: ErrorCode=" << (int)cancellation->ErrorCode << std::endl;
            std::cout << "CANCELED: ErrorDetails=[" << cancellation->ErrorDetails << "]" << std::endl;
            std::cout << "CANCELED: Did you set the speech resource key and region values?" << std::endl;
        }
    }

    std::cout << "Press enter to exit..." << std::endl;
    std::cin.get();
}

std::string getEnvironmentVariable(const char* name)
{
#if defined(_MSC_VER)
    size_t requiredSize = 0;
    (void)getenv_s(&requiredSize, nullptr, 0, name);
    if (requiredSize == 0)
    {
        return "";
    }
    auto buffer = std::make_unique<char[]>(requiredSize);
    (void)getenv_s(&requiredSize, buffer.get(), requiredSize, name);
    return buffer.get();
#else
    auto value = getenv(name);
    return value ? value : "";
#endif
}

Você pode encontrar mais exemplos de texto para fala no GitHub.

Usar um ponto de extremidade personalizado

O ponto de extremidade personalizado é funcionalmente idêntico ao ponto de extremidade padrão usado para solicitações de texto para fala.

Uma diferença é que o EndpointId deve ser especificado para usar sua voz personalizada por meio do SDK de fala. Você pode começar com o início rápido de texto para fala e, em seguida, atualizar o código com o EndpointId e SpeechSynthesisVoiceName.

auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
speechConfig->SetSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig->SetEndpointId("YourEndpointId");

Para usar uma voz personalizada por meio do SSML (Speech Synthesis Markup Language), especifique o nome do modelo como o nome da voz. Este exemplo usa a YourCustomVoiceName voz.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (Go) | Amostras adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Pré-requisitos

  • Uma subscrição do Azure. Você pode criar um gratuitamente.
  • Crie um recurso de Fala no portal do Azure.
  • Obtenha a chave de recurso de Fala e a região. Depois que o recurso de Fala for implantado, selecione Ir para o recurso para exibir e gerenciar chaves.

Instalar o SDK de Fala

Antes de poder fazer qualquer coisa, você precisa instalar o SDK de Fala para Go.

Conversão de texto em voz para orador

Use o exemplo de código a seguir para executar a síntese de fala no dispositivo de saída de áudio padrão. Substitua as variáveis subscription e region pela sua chave de fala e localização/região. A execução do script fala o texto de entrada para o alto-falante padrão.

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 := "YourSpeechKey"
    region := "YourSpeechRegion"

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, 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 set the speech resource key and region values?\n",
                    cancellation.ErrorCode,
                    cancellation.ErrorDetails)
            }
        }
    }
}

Execute os seguintes comandos para criar um arquivo go.mod vinculado a componentes hospedados no GitHub:

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

Agora compile e execute o código:

go build
go run quickstart

Para obter informações detalhadas sobre as classes, consulte os SpeechConfig documentos de referência e SpeechSynthesizer .

Conversão de texto em fala para fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos de .wav personalizados e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Remova o bloco, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o AudioConfig controle. Em seguida, passe nil para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar nil por AudioConfig, em vez de omiti-lo como fez no exemplo de saída de alto-falante anterior, não reproduzirá o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma SpeechSynthesisResult variável. A AudioData propriedade retorna uma []byte instância para os dados de saída. Você pode trabalhar com essa []byte instância manualmente ou pode usar a AudioDataStream classe para gerenciar o fluxo na memória. Neste exemplo, você usa a NewAudioDataStreamFromSpeechSynthesisResult() função estática para obter um fluxo do resultado.

Substitua as variáveis subscription e region pela sua chave de fala e localização/região:

package main

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

    "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 := "YourSpeechKey"
    region := "YourSpeechRegion"

    speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, 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 cases, 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))
    }
}

Execute os seguintes comandos para criar um arquivo go.mod vinculado a componentes hospedados no GitHub:

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

Agora compile e execute o código:

go build
go run quickstart

Para obter informações detalhadas sobre as classes, consulte os SpeechConfig documentos de referência e SpeechSynthesizer .

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Pode obter a lista completa ou experimentá-los na Galeria de Vozes.

Especifique o idioma ou a voz de para corresponder ao texto de SpeechConfig entrada e use a voz especificada:

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

speechConfig.SetSpeechSynthesisLanguage("en-US")
speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto será falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especifica usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Usar o SSML para personalizar as características de fala

Você pode usar a SSML (Speech Synthesis Markup Language) para ajustar o tom, a pronúncia, a taxa de fala, o volume e muito mais na saída de texto para fala, enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte Visão geral da linguagem de marcação de síntese de fala.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterna a voz.

Primeiro, crie um novo arquivo XML para a configuração do SSML no diretório do projeto raiz. Neste exemplo, é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

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

Em seguida, você precisa alterar a solicitação de síntese de fala para fazer referência ao seu arquivo XML. A solicitação é basicamente a mesma, mas em vez de usar a SpeakTextAsync() função, você usa SpeakSsmlAsync(). Esta função espera uma cadeia de caracteres XML, para que você primeiro carregue sua configuração SSML como uma cadeia de caracteres. A partir deste ponto, o objeto result é exatamente o mesmo que os exemplos anteriores.

Nota

Para definir a voz sem usar SSML, você pode definir a propriedade usando SpeechConfig speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural").

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substitua o conteúdo desse speech-synthesis.go arquivo pelo seguinte código Go:

package main

import (
    "fmt"
    "os"
    "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 bookmarkReachedHandler(event speech.SpeechSynthesisBookmarkEventArgs) {
    defer event.Close()
    fmt.Println("BookmarkReached event")
}

func synthesisCanceledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisCanceled event")
}

func synthesisCompletedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisCompleted event")
    fmt.Printf("\tAudioData: %d bytes\n", len(event.Result.AudioData))
    fmt.Printf("\tAudioDuration: %d\n", event.Result.AudioDuration)
}

func synthesisStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisStarted event")
}

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

func visemeReceivedHandler(event speech.SpeechSynthesisVisemeEventArgs) {
    defer event.Close()
    fmt.Println("VisemeReceived event")
    fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
    fmt.Printf("\tVisemeID %d\n", event.VisemeID)
}

func wordBoundaryHandler(event speech.SpeechSynthesisWordBoundaryEventArgs) {
    defer event.Close()
    boundaryType := ""
    switch event.BoundaryType {
    case 0:
        boundaryType = "Word"
    case 1:
        boundaryType = "Punctuation"
    case 2:
        boundaryType = "Sentence"
    }
    fmt.Println("WordBoundary event")
    fmt.Printf("\tBoundaryType %v\n", boundaryType)
    fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
    fmt.Printf("\tDuration %d\n", event.Duration)
    fmt.Printf("\tText %s\n", event.Text)
    fmt.Printf("\tTextOffset %d\n", event.TextOffset)
    fmt.Printf("\tWordLength %d\n", event.WordLength)
}

func main() {
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    speechKey := os.Getenv("SPEECH_KEY")
    speechRegion := os.Getenv("SPEECH_REGION")

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    speechConfig, err := speech.NewSpeechConfigFromSubscription(speechKey, speechRegion)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()

    // Required for WordBoundary event sentences.
    speechConfig.SetProperty(common.SpeechServiceResponseRequestSentenceBoundary, "true")

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

    speechSynthesizer.BookmarkReached(bookmarkReachedHandler)
    speechSynthesizer.SynthesisCanceled(synthesisCanceledHandler)
    speechSynthesizer.SynthesisCompleted(synthesisCompletedHandler)
    speechSynthesizer.SynthesisStarted(synthesisStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.VisemeReceived(visemeReceivedHandler)
    speechSynthesizer.WordBoundary(wordBoundaryHandler)

    speechSynthesisVoiceName := "en-US-AvaMultilingualNeural"

    ssml := fmt.Sprintf(`<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
            <voice name='%s'>
                <mstts:viseme type='redlips_front'/>
                The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
            </voice>
        </speak>`, speechSynthesisVoiceName)

    // Synthesize the SSML
    fmt.Printf("SSML to synthesize: \n\t%s\n", ssml)
    task := speechSynthesizer.SpeakSsmlAsync(ssml)

    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.Println("SynthesizingAudioCompleted result")
    } 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 set the speech resource key and region values?\n",
                cancellation.ErrorCode,
                cancellation.ErrorDetails)
        }
    }
}

Você pode encontrar mais exemplos de texto para fala no GitHub.

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Documentação | de referência Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Pode obter a lista completa ou experimentá-los na Galeria de Vozes.

Especifique o idioma ou a voz de SpeechConfig para corresponder ao texto de entrada e use a voz especificada. O trecho de código a seguir mostra como essa técnica funciona:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.setSpeechSynthesisLanguage("en-US"); 
    speechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto será falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especificou usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Sintetizar fala em um arquivo

Crie um SpeechSynthesizer objeto. Este objeto executa conversões de texto para fala e saídas para alto-falantes, arquivos ou outros fluxos de saída. SpeechSynthesizer aceita como parâmetros:

  • O SpeechConfig objeto que você criou na etapa anterior.
  • Um AudioConfig objeto que especifica como os resultados de saída devem ser tratados.
  1. Crie uma AudioConfig instância para gravar automaticamente a saída em um arquivo .wav usando a fromWavFileOutput() função estática:

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
    }
    
  2. Instanciar uma SpeechSynthesizer instância. Passe seu speechConfig objeto e o audioConfig objeto como parâmetros. Para sintetizar fala e gravar em um arquivo, execute SpeakText() com uma cadeia de caracteres de texto.

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
    
        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
        speechSynthesizer.SpeakText("I'm excited to try text to speech");
    }
    

Quando você executa o programa, ele cria um arquivo .wav sintetizado, que é gravado no local que você especificar. Este resultado é um bom exemplo do uso mais básico. Em seguida, você pode personalizar a saída e manipular a resposta de saída como um fluxo na memória para trabalhar com cenários personalizados.

Sintetizar para saída de alto-falante

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Para exportar a fala sintetizada para o dispositivo de saída ativo atual, como um alto-falante, instancie AudioConfig usando a fromDefaultSpeakerOutput() função estática. Eis um exemplo:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    AudioConfig audioConfig = AudioConfig.fromDefaultSpeakerOutput();

    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    speechSynthesizer.SpeakText("I'm excited to try text to speech");
}

Obter um resultado como um fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos de .wav personalizados e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Primeiro, remova o AudioConfig bloco, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o controle. Em seguida, passe null para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar null para AudioConfig, em vez de omiti-lo como fez no exemplo de saída de alto-falante anterior, não reproduz o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma SpeechSynthesisResult variável. A SpeechSynthesisResult.getAudioData() função retorna uma byte [] instância dos dados de saída. Você pode trabalhar com essa byte [] instância manualmente ou pode usar a AudioDataStream classe para gerenciar o fluxo na memória.

Neste exemplo, use a AudioDataStream.fromResult() função estática para obter um fluxo do resultado:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);

    SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    System.out.print(stream.getStatus());
}

Neste ponto, você pode implementar qualquer comportamento personalizado usando o objeto resultante stream .

Personalizar formato de áudio

Você pode personalizar atributos de saída de áudio, incluindo:

  • Tipo de ficheiro de áudio
  • Taxa de amostragem
  • Profundidade de bits

Para alterar o formato de áudio, use a setSpeechSynthesisOutputFormat() SpeechConfig função no objeto. Esta função espera uma enum instância do tipo SpeechSynthesisOutputFormat. Use o enum para selecionar o formato de saída. Para formatos disponíveis, consulte a lista de formatos de áudio.

Existem várias opções para diferentes tipos de ficheiros, dependendo dos seus requisitos. Por definição, formatos brutos como Raw24Khz16BitMonoPcm não incluem cabeçalhos de áudio. Use formatos brutos somente em uma destas situações:

  • Você sabe que sua implementação downstream pode decodificar um fluxo de bits bruto.
  • Você planeja criar cabeçalhos manualmente com base em fatores como profundidade de bits, taxa de amostragem e número de canais.

Este exemplo especifica o formato Riff24Khz16BitMonoPcm RIFF de alta fidelidade definindo SpeechSynthesisOutputFormat no SpeechConfig objeto. Semelhante ao exemplo na seção anterior, você usa AudioDataStream para obter um fluxo na memória do resultado e, em seguida, gravá-lo em um arquivo.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");

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

    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

Quando você executa o programa, ele grava um arquivo de .wav no caminho especificado.

Usar o SSML para personalizar as características de fala

Você pode usar o SSML para ajustar o tom, a pronúncia, a taxa de fala, o volume e outros aspetos na saída de texto para fala enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte o artigo de instruções do SSML.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterna a voz.

  1. Crie um novo arquivo XML para a configuração do SSML no diretório raiz do projeto.

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

    Neste exemplo, o arquivo é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

  2. Altere a solicitação de síntese de fala para fazer referência ao arquivo XML. O pedido é praticamente o mesmo. Em vez de usar a SpeakText() função, você usa SpeakSsml(). Esta função espera uma cadeia de caracteres XML, portanto, primeiro crie uma função para carregar um arquivo XML e retorná-lo como uma cadeia de caracteres:

    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.";
        }
    }
    

    Neste ponto, o objeto result é exatamente o mesmo que os exemplos anteriores:

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    
        String ssml = xmlToString("ssml.xml");
        SpeechSynthesisResult result = speechSynthesizer.SpeakSsml(ssml);
        AudioDataStream stream = AudioDataStream.fromResult(result);
        stream.saveToWavFile("path/to/write/file.wav");
    }
    

Nota

Para alterar a voz sem usar SSML, defina a propriedade ativada SpeechConfig usando SpeechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");.

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substituir o conteúdo desse arquivo SpeechSynthesis.java pelo seguinte código Java:

import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.audio.*;

import java.util.Scanner;
import java.util.concurrent.ExecutionException;

public class SpeechSynthesis {
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    private static String speechKey = System.getenv("SPEECH_KEY");
    private static String speechRegion = System.getenv("SPEECH_REGION");

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
        
        // Required for WordBoundary event sentences.
        speechConfig.setProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

        String speechSynthesisVoiceName = "en-US-AvaMultilingualNeural"; 
        
        String ssml = String.format("<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>"
            .concat(String.format("<voice name='%s'>", speechSynthesisVoiceName))
            .concat("<mstts:viseme type='redlips_front'/>")
            .concat("The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.")
            .concat("</voice>")
            .concat("</speak>"));

        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig);
        {
            // Subscribe to events

            speechSynthesizer.BookmarkReached.addEventListener((o, e) -> {
                System.out.println("BookmarkReached event:");
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tText: " + e.getText());
            });

            speechSynthesizer.SynthesisCanceled.addEventListener((o, e) -> {
                System.out.println("SynthesisCanceled event");
            });

            speechSynthesizer.SynthesisCompleted.addEventListener((o, e) -> {
                SpeechSynthesisResult result = e.getResult();                
                byte[] audioData = result.getAudioData();
                System.out.println("SynthesisCompleted event:");
                System.out.println("\tAudioData: " + audioData.length + " bytes");
                System.out.println("\tAudioDuration: " + result.getAudioDuration());
                result.close();
            });
            
            speechSynthesizer.SynthesisStarted.addEventListener((o, e) -> {
                System.out.println("SynthesisStarted event");
            });

            speechSynthesizer.Synthesizing.addEventListener((o, e) -> {
                SpeechSynthesisResult result = e.getResult();
                byte[] audioData = result.getAudioData();
                System.out.println("Synthesizing event:");
                System.out.println("\tAudioData: " + audioData.length + " bytes");
                result.close();
            });

            speechSynthesizer.VisemeReceived.addEventListener((o, e) -> {
                System.out.println("VisemeReceived event:");
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tVisemeId: " + e.getVisemeId());
            });

            speechSynthesizer.WordBoundary.addEventListener((o, e) -> {
                System.out.println("WordBoundary event:");
                System.out.println("\tBoundaryType: " + e.getBoundaryType());
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tDuration: " + e.getDuration());
                System.out.println("\tText: " + e.getText());
                System.out.println("\tTextOffset: " + e.getTextOffset());
                System.out.println("\tWordLength: " + e.getWordLength());
            });

            // Synthesize the SSML
            System.out.println("SSML to synthesize:");
            System.out.println(ssml);
            SpeechSynthesisResult speechSynthesisResult = speechSynthesizer.SpeakSsmlAsync(ssml).get();

            if (speechSynthesisResult.getReason() == ResultReason.SynthesizingAudioCompleted) {
                System.out.println("SynthesizingAudioCompleted result");
            }
            else if (speechSynthesisResult.getReason() == ResultReason.Canceled) {
                SpeechSynthesisCancellationDetails cancellation = SpeechSynthesisCancellationDetails.fromResult(speechSynthesisResult);
                System.out.println("CANCELED: Reason=" + cancellation.getReason());

                if (cancellation.getReason() == CancellationReason.Error) {
                    System.out.println("CANCELED: ErrorCode=" + cancellation.getErrorCode());
                    System.out.println("CANCELED: ErrorDetails=" + cancellation.getErrorDetails());
                    System.out.println("CANCELED: Did you set the speech resource key and region values?");
                }
            }
        }
        speechSynthesizer.close();

        System.exit(0);
    }
}

Você pode encontrar mais exemplos de texto para fala no GitHub.

Usar um ponto de extremidade personalizado

O ponto de extremidade personalizado é funcionalmente idêntico ao ponto de extremidade padrão usado para solicitações de texto para fala.

Uma diferença é que o EndpointId deve ser especificado para usar sua voz personalizada por meio do SDK de fala. Você pode começar com o início rápido de texto para fala e, em seguida, atualizar o código com o EndpointId e SpeechSynthesisVoiceName.

SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
speechConfig.setSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig.setEndpointId("YourEndpointId");

Para usar uma voz personalizada por meio do SSML (Speech Synthesis Markup Language), especifique o nome do modelo como o nome da voz. Este exemplo usa a YourCustomVoiceName voz.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (npm) | Exemplos adicionais no código-fonte da Biblioteca GitHub |

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Pode obter a lista completa ou experimentá-los na Galeria de Vozes.

Especifique o idioma ou a voz de para corresponder ao texto de SpeechConfig entrada e use a voz especificada:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.speechSynthesisLanguage = "en-US"; 
    speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}

synthesizeSpeech();

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto será falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especifica usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Sintetizar texto em fala

Para exportar a fala sintetizada para o dispositivo de saída ativo atual, como um alto-falante, instancie AudioConfig usando a fromDefaultSpeakerOutput() função estática. Eis um exemplo:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();

    const speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            if (result) {
                speechSynthesizer.close();
                return result.audioData;
            }
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

Quando você executa o programa, o áudio sintetizado é reproduzido a partir do alto-falante. Este resultado é um bom exemplo do uso mais básico. Em seguida, você pode personalizar a saída e manipular a resposta de saída como um fluxo na memória para trabalhar com cenários personalizados.

Obter um resultado como um fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos personalizados .wav e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Remova o bloco, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o AudioConfig controle. Em seguida, passe null para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar null para AudioConfig, em vez de omiti-lo como fez no exemplo de saída de alto-falante anterior, não reproduz o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma variável SpeechSynthesisResult . A SpeechSynthesisResult.audioData propriedade retorna um ArrayBuffer valor dos dados de saída, o tipo de fluxo de navegador padrão. Para código do lado do servidor, converta ArrayBuffer em um fluxo de buffer.

O código a seguir funciona para o lado do cliente:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);

    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            speechSynthesizer.close();
            return result.audioData;
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

Você pode implementar qualquer comportamento personalizado usando o objeto resultante ArrayBuffer . ArrayBuffer é um tipo comum para receber em um navegador e jogar a partir deste formato.

Para qualquer código baseado em servidor, se você precisar trabalhar com os dados como um fluxo, precisará converter o ArrayBuffer objeto em um fluxo:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);

    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            const { audioData } = result;

            speechSynthesizer.close();

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

Personalizar formato de áudio

Você pode personalizar atributos de saída de áudio, incluindo:

  • Tipo de ficheiro de áudio
  • Taxa de amostragem
  • Profundidade de bits

Para alterar o formato de áudio, use a speechSynthesisOutputFormat SpeechConfig propriedade no objeto. Esta propriedade espera uma enum instância do tipo SpeechSynthesisOutputFormat. Use o enum para selecionar o formato de saída. Para formatos disponíveis, consulte a lista de formatos de áudio.

Existem várias opções para diferentes tipos de ficheiros, dependendo dos seus requisitos. Por definição, formatos brutos como Raw24Khz16BitMonoPcm não incluem cabeçalhos de áudio. Use formatos brutos somente em uma destas situações:

  • Você sabe que sua implementação downstream pode decodificar um fluxo de bits bruto.
  • Você planeja criar cabeçalhos manualmente com base em fatores como profundidade de bits, taxa de amostragem e número de canais.

Este exemplo especifica o formato Riff24Khz16BitMonoPcm RIFF de alta fidelidade definindo speechSynthesisOutputFormat no SpeechConfig objeto. Semelhante ao exemplo na seção anterior, obtenha os dados de áudio ArrayBuffer e interaja com eles.

function synthesizeSpeech() {
    const speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");

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

    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null);
    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            // Interact with the audio ArrayBuffer data
            const audioData = result.audioData;
            console.log(`Audio data byte size: ${audioData.byteLength}.`)

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

Usar o SSML para personalizar as características de fala

Você pode usar o SSML para ajustar o tom, a pronúncia, a taxa de fala, o volume e outros aspetos na saída de texto para fala enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte Visão geral da linguagem de marcação de síntese de fala.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterna a voz.

  1. Crie um novo arquivo XML para a configuração do SSML no diretório raiz do projeto.

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

    Neste exemplo, é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

  2. Altere a solicitação de síntese de fala para fazer referência ao arquivo XML. A solicitação é basicamente a mesma, mas em vez de usar a speakTextAsync() função, você usa speakSsmlAsync(). Esta função espera uma cadeia de caracteres XML. Crie uma função para carregar um arquivo XML e retorná-lo como uma cadeia de caracteres:

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

    Para obter mais informações sobre readFileSynco , consulte Node.js sistema de arquivos.

    O objeto result é exatamente o mesmo que os exemplos anteriores:

    function synthesizeSpeech() {
        const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null);
    
        const ssml = xmlToString("ssml.xml");
        speechSynthesizer.speakSsmlAsync(
            ssml,
            result => {
                if (result.errorDetails) {
                    console.error(result.errorDetails);
                } else {
                    console.log(JSON.stringify(result));
                }
    
                speechSynthesizer.close();
            },
            error => {
                console.log(error);
                speechSynthesizer.close();
            });
    }
    

Nota

Para alterar a voz sem usar SSML, você pode definir a propriedade usando SpeechConfig SpeechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";.

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substituir o conteúdo desse arquivo SpeechSynthesis.js pelo seguinte código JavaScript.

(function() {

    "use strict";

    var sdk = require("microsoft-cognitiveservices-speech-sdk");

    var audioFile = "YourAudioFile.wav";
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    const speechConfig = sdk.SpeechConfig.fromSubscription(process.env.SPEECH_KEY, process.env.SPEECH_REGION);
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput(audioFile);

    var speechSynthesisVoiceName  = "en-US-AvaMultilingualNeural";  
    var ssml = `<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'> \r\n \
        <voice name='${speechSynthesisVoiceName}'> \r\n \
            <mstts:viseme type='redlips_front'/> \r\n \
            The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>. \r\n \
        </voice> \r\n \
    </speak>`;
    
    // Required for WordBoundary event sentences.
    speechConfig.setProperty(sdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

    // Create the speech speechSynthesizer.
    var speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);

    speechSynthesizer.bookmarkReached = function (s, e) {
        var str = `BookmarkReached event: \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tText: \"${e.text}\".`;
        console.log(str);
    };

    speechSynthesizer.synthesisCanceled = function (s, e) {
        console.log("SynthesisCanceled event");
    };
    
    speechSynthesizer.synthesisCompleted = function (s, e) {
        var str = `SynthesisCompleted event: \
                    \r\n\tAudioData: ${e.result.audioData.byteLength} bytes \
                    \r\n\tAudioDuration: ${e.result.audioDuration}`;
        console.log(str);
    };

    speechSynthesizer.synthesisStarted = function (s, e) {
        console.log("SynthesisStarted event");
    };

    speechSynthesizer.synthesizing = function (s, e) {
        var str = `Synthesizing event: \
            \r\n\tAudioData: ${e.result.audioData.byteLength} bytes`;
        console.log(str);
    };
    
    speechSynthesizer.visemeReceived = function(s, e) {
        var str = `VisemeReceived event: \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tVisemeId: ${e.visemeId}`;
        console.log(str);
    };

    speechSynthesizer.wordBoundary = function (s, e) {
        // Word, Punctuation, or Sentence
        var str = `WordBoundary event: \
            \r\n\tBoundaryType: ${e.boundaryType} \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tDuration: ${e.duration} \
            \r\n\tText: \"${e.text}\" \
            \r\n\tTextOffset: ${e.textOffset} \
            \r\n\tWordLength: ${e.wordLength}`;
        console.log(str);
    };

    // Synthesize the SSML
    console.log(`SSML to synthesize: \r\n ${ssml}`)
    console.log(`Synthesize to: ${audioFile}`);
    speechSynthesizer.speakSsmlAsync(ssml,
        function (result) {
      if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
        console.log("SynthesizingAudioCompleted result");
      } else {
        console.error("Speech synthesis canceled, " + result.errorDetails +
            "\nDid you set the speech resource key and region values?");
      }
      speechSynthesizer.close();
      speechSynthesizer = null;
    },
        function (err) {
      console.trace("err - " + err);
      speechSynthesizer.close();
      speechSynthesizer = null;
    });
}());

Você pode encontrar mais exemplos de texto para fala no GitHub.

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (download) | Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Pré-requisitos

  • Uma subscrição do Azure. Você pode criar um gratuitamente.
  • Crie um recurso de Fala no portal do Azure.
  • Obtenha a chave de recurso de Fala e a região. Depois que o recurso de Fala for implantado, selecione Ir para o recurso para exibir e gerenciar chaves.

Instalar o SDK de fala e exemplos

O repositório Azure-Samples/cognitive-services-speech-sdk contém exemplos escritos em Objective-C para iOS e Mac. Selecione um link para ver as instruções de instalação para cada exemplo:

Usar um ponto de extremidade personalizado

O ponto de extremidade personalizado é funcionalmente idêntico ao ponto de extremidade padrão usado para solicitações de texto para fala.

Uma diferença é que o EndpointId deve ser especificado para usar sua voz personalizada por meio do SDK de fala. Você pode começar com o início rápido de texto para fala e, em seguida, atualizar o código com o EndpointId e SpeechSynthesisVoiceName.

SPXSpeechConfiguration *speechConfig = [[SPXSpeechConfiguration alloc] initWithSubscription:speechKey region:speechRegion];
speechConfig.speechSynthesisVoiceName = @"YourCustomVoiceName";
speechConfig.EndpointId = @"YourEndpointId";

Para usar uma voz personalizada por meio do SSML (Speech Synthesis Markup Language), especifique o nome do modelo como o nome da voz. Este exemplo usa a YourCustomVoiceName voz.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (download) | Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Pré-requisitos

  • Uma subscrição do Azure. Você pode criar um gratuitamente.
  • Crie um recurso de Fala no portal do Azure.
  • Obtenha a chave de recurso de Fala e a região. Depois que o recurso de Fala for implantado, selecione Ir para o recurso para exibir e gerenciar chaves.

Instalar o SDK de fala e exemplos

O repositório Azure-Samples/cognitive-services-speech-sdk contém exemplos escritos em Swift para iOS e Mac. Selecione um link para ver as instruções de instalação para cada exemplo:

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Pacote de documentação | de referência (PyPi) | Amostras adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Selecionar linguagem de síntese e voz

A funcionalidade de conversão de texto em voz no serviço de Voz suporta mais de 400 vozes e mais de 140 idiomas e variantes. Pode obter a lista completa ou experimentá-los na Galeria de Vozes.

Especifique o idioma ou a voz de para corresponder ao texto de SpeechConfig entrada e use a voz especificada:

# Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speech_config.speech_synthesis_language = "en-US" 
speech_config.speech_synthesis_voice_name ="en-US-AvaMultilingualNeural"

Todas as vozes neurais são multilingues e fluentes em seu próprio idioma e inglês. Por exemplo, se o texto de entrada em inglês for "Estou animado para tentar conversão de texto em fala" e você selecionar es-ES-ElviraNeural, o texto será falado em inglês com sotaque espanhol.

Se a voz não falar o idioma do texto de entrada, o serviço de Fala não criará áudio sintetizado. Para obter uma lista completa das vozes neurais suportadas, consulte Suporte de idioma e voz para o serviço de fala.

Nota

A voz padrão é a primeira voz retornada por localidade da API de Lista de Vozes.

A voz que fala é determinada por ordem de prioridade da seguinte forma:

  • Se você não definir SpeechSynthesisVoiceName ou SpeechSynthesisLanguage, a voz padrão para en-US fala.
  • Se você definir SpeechSynthesisLanguageapenas , a voz padrão para a localidade especificada fala.
  • Se ambos SpeechSynthesisVoiceName estiverem SpeechSynthesisLanguage definidos, a SpeechSynthesisLanguage configuração será ignorada. A voz que você especifica usando SpeechSynthesisVoiceName fala.
  • Se o elemento voice for definido usando SSML (Speech Synthesis Markup Language), as SpeechSynthesisVoiceName configurações e SpeechSynthesisLanguage serão ignoradas.

Em resumo, a ordem de prioridade pode ser descrita como:

SpeechSynthesisVoiceName SpeechSynthesisLanguage SSML Resultado
Voz padrão para en-US fala
A voz padrão para a localidade especificada fala.
A voz que você especifica usando SpeechSynthesisVoiceName fala.
A voz que você especificar usando SSML fala.

Sintetizar fala em um arquivo

Crie um objeto SpeechSynthesizer . Este objeto executa conversões de texto para fala e saídas para alto-falantes, arquivos ou outros fluxos de saída. SpeechSynthesizer aceita como parâmetros:

  • O SpeechConfig objeto que você criou na etapa anterior.
  • Um AudioOutputConfig objeto que especifica como os resultados de saída devem ser tratados.
  1. Crie uma AudioOutputConfig instância para gravar automaticamente a saída em um arquivo .wav usando o filename parâmetro do construtor:

    audio_config = speechsdk.audio.AudioOutputConfig(filename="path/to/write/file.wav")
    
  2. Instancie SpeechSynthesizer passando seu speech_config objeto e o audio_config objeto como parâmetros. Para sintetizar fala e gravar em um arquivo, execute speak_text_async() com uma cadeia de caracteres de texto.

    speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
    speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
    
    

Quando você executa o programa, ele cria um arquivo .wav sintetizado, que é gravado no local que você especificar. Este resultado é um bom exemplo do uso mais básico. Em seguida, você pode personalizar a saída e manipular a resposta de saída como um fluxo na memória para trabalhar com cenários personalizados.

Sintetizar para saída de alto-falante

Para exportar a fala sintetizada para o dispositivo de saída ativo atual, como um alto-falante, defina o use_default_speaker parâmetro ao criar a AudioOutputConfig instância. Eis um exemplo:

audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)

Obter um resultado como um fluxo na memória

Você pode usar os dados de áudio resultantes como um fluxo na memória em vez de gravar diretamente em um arquivo. Com o fluxo na memória, você pode criar um comportamento personalizado:

  • Abstraia a matriz de bytes resultante como um fluxo pesquisável para serviços downstream personalizados.
  • Integre o resultado com outras APIs ou serviços.
  • Modifique os dados de áudio, escreva cabeçalhos de .wav personalizados e execute tarefas relacionadas.

Você pode fazer essa alteração no exemplo anterior. Primeiro, remova AudioConfig, porque você gerencia o comportamento de saída manualmente a partir deste ponto para aumentar o controle. Passe None para AudioConfig no SpeechSynthesizer construtor.

Nota

Passar None para AudioConfig, em vez de omiti-lo como fez no exemplo de saída de alto-falante anterior, não reproduz o áudio por padrão no dispositivo de saída ativo atual.

Salve o resultado em uma SpeechSynthesisResult variável. A audio_data propriedade contém um bytes objeto dos dados de saída. Você pode trabalhar com esse objeto manualmente ou pode usar a AudioDataStream classe para gerenciar o fluxo na memória.

Neste exemplo, use o AudioDataStream construtor para obter um fluxo do resultado:

speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = speechsdk.AudioDataStream(speech_synthesis_result)

Neste ponto, você pode implementar qualquer comportamento personalizado usando o objeto resultante stream .

Personalizar formato de áudio

Você pode personalizar atributos de saída de áudio, incluindo:

  • Tipo de ficheiro de áudio
  • Taxa de amostragem
  • Profundidade de bits

Para alterar o formato de áudio, use a set_speech_synthesis_output_format() SpeechConfig função no objeto. Esta função espera uma enum instância do tipo SpeechSynthesisOutputFormat. Use o enum para selecionar o formato de saída. Para formatos disponíveis, consulte a lista de formatos de áudio.

Existem várias opções para diferentes tipos de ficheiros, dependendo dos seus requisitos. Por definição, formatos brutos como Raw24Khz16BitMonoPcm não incluem cabeçalhos de áudio. Use formatos brutos somente em uma destas situações:

  • Você sabe que sua implementação downstream pode decodificar um fluxo de bits bruto.
  • Você planeja criar cabeçalhos manualmente com base em fatores como profundidade de bits, taxa de amostragem e número de canais.

Este exemplo especifica o formato Riff24Khz16BitMonoPcm RIFF de alta fidelidade definindo SpeechSynthesisOutputFormat no SpeechConfig objeto. Semelhante ao exemplo na seção anterior, você usa AudioDataStream para obter um fluxo na memória do resultado e, em seguida, gravá-lo em um arquivo.

speech_config.set_speech_synthesis_output_format(speechsdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)

speech_synthesis_result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = speechsdk.AudioDataStream(speech_synthesis_result)
stream.save_to_wav_file("path/to/write/file.wav")

Quando você executa o programa, ele grava um arquivo de .wav no caminho especificado.

Usar o SSML para personalizar as características de fala

Você pode usar o SSML para ajustar o tom, a pronúncia, a taxa de fala, o volume e outros aspetos na saída de texto para fala enviando suas solicitações de um esquema XML. Esta seção mostra um exemplo de alteração da voz. Para obter mais informações, consulte Visão geral da linguagem de marcação de síntese de fala.

Para começar a usar o SSML para personalização, faça uma pequena alteração que alterne a voz.

  1. Crie um novo arquivo XML para a configuração do SSML no diretório raiz do projeto.

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

    Neste exemplo, o arquivo é ssml.xml. O elemento raiz é sempre <speak>. Quebrar o texto em um <voice> elemento permite que você altere a voz usando o name parâmetro. Para obter a lista completa de vozes neurais suportadas, consulte Idiomas suportados.

  2. Altere a solicitação de síntese de fala para fazer referência ao arquivo XML. O pedido é praticamente o mesmo. Em vez de usar a speak_text_async() função, use speak_ssml_async(). Esta função espera uma cadeia de caracteres XML. Primeiro, leia a configuração do SSML como uma cadeia de caracteres. A partir deste ponto, o objeto result é exatamente o mesmo que os exemplos anteriores.

    Nota

    Se o seu ssml_string contiver  no início da cadeia de caracteres, você precisará remover o formato de lista técnica ou o serviço retornará um erro. Para fazer isso, defina o encoding parâmetro da seguinte maneira: open("ssml.xml", "r", encoding="utf-8-sig").

    speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
    
    ssml_string = open("ssml.xml", "r").read()
    speech_synthesis_result = speech_synthesizer.speak_ssml_async(ssml_string).get()
    
    stream = speechsdk.AudioDataStream(speech_synthesis_result)
    stream.save_to_wav_file("path/to/write/file.wav")
    

Nota

Para alterar a voz sem usar SSML, você pode definir a propriedade usando SpeechConfig speech_config.speech_synthesis_voice_name = "en-US-AvaMultilingualNeural".

Inscrever-se em eventos de sintetizadores

Você pode querer mais informações sobre o processamento de texto para fala e resultados. Por exemplo, você pode querer saber quando o sintetizador inicia e para, ou você pode querer saber sobre outros eventos encontrados durante a síntese.

Ao usar o SpeechSynthesizer para conversão de texto em fala, você pode se inscrever nos eventos desta tabela:

Evento Descrição Caso de utilização
BookmarkReached Sinais de que um marcador foi alcançado. Para acionar um evento atingido de indicador, é necessário um bookmark elemento no SSML. Este evento relata o tempo decorrido do áudio de saída entre o início da síntese e o bookmark elemento. A propriedade do Text evento é o valor da cadeia de caracteres que você define no atributo do mark indicador. Os bookmark elementos não são falados. Você pode usar o bookmark elemento para inserir marcadores personalizados no SSML para obter o deslocamento de cada marcador no fluxo de áudio. O bookmark elemento pode ser usado para fazer referência a um local específico na sequência de texto ou marca.
SynthesisCanceled Sinais de que a síntese da fala foi cancelada. Você pode confirmar quando a síntese é cancelada.
SynthesisCompleted Sinais de que a síntese da fala está completa. Você pode confirmar quando a síntese está completa.
SynthesisStarted Sinais de que a síntese de fala começou. Você pode confirmar quando a síntese começou.
Synthesizing Sinais de que a síntese de fala está em curso. Esse evento é acionado sempre que o SDK recebe um bloco de áudio do serviço de fala. Você pode confirmar quando a síntese está em andamento.
VisemeReceived Sinais de que um evento viseme foi recebido. Visemes são frequentemente usados para representar as posições-chave na fala observada. As principais poses incluem a posição dos lábios, mandíbula e língua na produção de um fonema específico. Você pode usar visemes para animar o rosto de um personagem enquanto o áudio de fala é reproduzido.
WordBoundary Sinais de que um limite de palavra foi recebido. Este evento é levantado no início de cada nova palavra falada, pontuação e frase. O evento relata o deslocamento de tempo da palavra atual, em ticks, a partir do início do áudio de saída. Esse evento também relata a posição do caractere no texto de entrada ou SSML imediatamente antes da palavra que está prestes a ser falada. Este evento é comumente usado para obter posições relativas do texto e áudio correspondente. Você pode querer saber sobre uma nova palavra e, em seguida, agir com base no tempo. Por exemplo, você pode obter informações que podem ajudá-lo a decidir quando e por quanto tempo destacar as palavras à medida que são faladas.

Nota

Os eventos são gerados à medida que os dados de áudio de saída ficam disponíveis, o que é mais rápido do que a reprodução para um dispositivo de saída. O chamador deve sincronizar adequadamente o streaming e o tempo real.

Eis um exemplo que mostra como subscrever eventos para síntese de voz.

Importante

Se você usar uma chave de API, armazene-a com segurança em outro lugar, como no Cofre de Chaves do Azure. Não inclua a chave da API diretamente no seu código e nunca a publique publicamente.

Para obter mais informações sobre segurança de serviços de IA, consulte Autenticar solicitações para serviços de IA do Azure.

Você pode seguir as instruções no início rápido, mas substituir o conteúdo desse arquivo speech-synthesis.py pelo seguinte código Python:

import os
import azure.cognitiveservices.speech as speechsdk

def speech_synthesizer_bookmark_reached_cb(evt: speechsdk.SessionEventArgs):
    print('BookmarkReached event:')
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tText: {}'.format(evt.text))

def speech_synthesizer_synthesis_canceled_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisCanceled event')

def speech_synthesizer_synthesis_completed_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisCompleted event:')
    print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))
    print('\tAudioDuration: {}'.format(evt.result.audio_duration))

def speech_synthesizer_synthesis_started_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisStarted event')

def speech_synthesizer_synthesizing_cb(evt: speechsdk.SessionEventArgs):
    print('Synthesizing event:')
    print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))

def speech_synthesizer_viseme_received_cb(evt: speechsdk.SessionEventArgs):
    print('VisemeReceived event:')
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tVisemeId: {}'.format(evt.viseme_id))

def speech_synthesizer_word_boundary_cb(evt: speechsdk.SessionEventArgs):
    print('WordBoundary event:')
    print('\tBoundaryType: {}'.format(evt.boundary_type))
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tDuration: {}'.format(evt.duration))
    print('\tText: {}'.format(evt.text))
    print('\tTextOffset: {}'.format(evt.text_offset))
    print('\tWordLength: {}'.format(evt.word_length))

# This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))

# Required for WordBoundary event sentences.
speech_config.set_property(property_id=speechsdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, value='true')

audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)

# Subscribe to events
speech_synthesizer.bookmark_reached.connect(speech_synthesizer_bookmark_reached_cb)
speech_synthesizer.synthesis_canceled.connect(speech_synthesizer_synthesis_canceled_cb)
speech_synthesizer.synthesis_completed.connect(speech_synthesizer_synthesis_completed_cb)
speech_synthesizer.synthesis_started.connect(speech_synthesizer_synthesis_started_cb)
speech_synthesizer.synthesizing.connect(speech_synthesizer_synthesizing_cb)
speech_synthesizer.viseme_received.connect(speech_synthesizer_viseme_received_cb)
speech_synthesizer.synthesis_word_boundary.connect(speech_synthesizer_word_boundary_cb)

# The language of the voice that speaks.
speech_synthesis_voice_name='en-US-AvaMultilingualNeural'

ssml = """<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
    <voice name='{}'>
        <mstts:viseme type='redlips_front'/>
        The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
    </voice>
</speak>""".format(speech_synthesis_voice_name)

# Synthesize the SSML
print("SSML to synthesize: \r\n{}".format(ssml))
speech_synthesis_result = speech_synthesizer.speak_ssml_async(ssml).get()

if speech_synthesis_result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
    print("SynthesizingAudioCompleted result")
elif speech_synthesis_result.reason == speechsdk.ResultReason.Canceled:
    cancellation_details = speech_synthesis_result.cancellation_details
    print("Speech synthesis canceled: {}".format(cancellation_details.reason))
    if cancellation_details.reason == speechsdk.CancellationReason.Error:
        if cancellation_details.error_details:
            print("Error details: {}".format(cancellation_details.error_details))
            print("Did you set the speech resource key and region values?")

Você pode encontrar mais exemplos de texto para fala no GitHub.

Usar um ponto de extremidade personalizado

O ponto de extremidade personalizado é funcionalmente idêntico ao ponto de extremidade padrão usado para solicitações de texto para fala.

Uma diferença é que o endpoint_id deve ser especificado para usar sua voz personalizada por meio do SDK de fala. Você pode começar com o início rápido de texto para fala e, em seguida, atualizar o código com o endpoint_id e speech_synthesis_voice_name.

speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))
speech_config.endpoint_id = "YourEndpointId"
speech_config.speech_synthesis_voice_name = "YourCustomVoiceName"

Para usar uma voz personalizada por meio do SSML (Speech Synthesis Markup Language), especifique o nome do modelo como o nome da voz. Este exemplo usa a YourCustomVoiceName voz.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Referência | da API REST de fala para texto API REST de fala para texto para referência | de áudio curta Exemplos adicionais no GitHub

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Pré-requisitos

  • Uma subscrição do Azure. Você pode criar um gratuitamente.
  • Crie um recurso de Fala no portal do Azure.
  • Obtenha a chave de recurso de Fala e a região. Depois que o recurso de Fala for implantado, selecione Ir para o recurso para exibir e gerenciar chaves.

Converter texto em fala

Em um prompt de comando, execute o seguinte comando. Insira estes valores no comando:

  • A sua chave de recurso de Fala
  • A sua região de recursos de Fala

Você também pode querer alterar os seguintes valores:

  • O X-Microsoft-OutputFormat valor do cabeçalho, que controla o formato de saída de áudio. Você pode encontrar uma lista de formatos de saída de áudio suportados na referência da API REST de texto para fala.
  • A voz de saída. Para obter uma lista de vozes disponíveis para o ponto de extremidade do serviço de Fala, consulte a API de Lista de Vozes.
  • O arquivo de saída. Neste exemplo, direcionamos a resposta do servidor para um arquivo chamado output.mp3.
curl --location --request POST 'https://YOUR_RESOURCE_REGION.tts.speech.microsoft.com/cognitiveservices/v1' \
--header 'Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY' \
--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 name='\''en-US-AvaMultilingualNeural'\''>
        I am excited to try text to speech
    </voice>
</speak>' > output.mp3

Neste guia de instruções, você aprende padrões de design comuns para fazer síntese de texto para fala.

Para obter mais informações sobre as seguintes áreas, consulte O que é conversão de texto em fala?

  • Obter respostas como fluxos na memória.
  • Personalização da taxa de amostragem de saída e da taxa de bits.
  • Envio de pedidos de síntese utilizando a Speech Synthesis Markup Language (SSML).
  • Usando vozes neurais.
  • Subscrever eventos e agir sobre resultados.

Pré-requisitos

  • Uma subscrição do Azure. Você pode criar um gratuitamente.
  • Crie um recurso de Fala no portal do Azure.
  • Obtenha a chave de recurso de Fala e a região. Depois que o recurso de Fala for implantado, selecione Ir para o recurso para exibir e gerenciar chaves.

Transferir e instalar

Siga estas etapas e consulte o início rápido da CLI de fala para obter outros requisitos para sua plataforma.

  1. Execute o seguinte comando da CLI do .NET para instalar a CLI de fala:

    dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
    
  2. Execute os comandos a seguir para configurar sua chave de recurso de fala e região. Substitua SUBSCRIPTION-KEY pela chave de recurso de Fala e substitua REGION pela região de recurso de Fala.

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

Sintetizar a voz num altifalante

Agora você está pronto para executar a CLI de fala para sintetizar fala a partir do texto.

  • Em uma janela do console, mude para o diretório que contém o arquivo binário da CLI de fala. Em seguida, execute o seguinte comando:

    spx synthesize --text "I'm excited to try text to speech"
    

A CLI de Fala produz linguagem natural em inglês através do alto-falante do computador.

Sintetizar fala em um arquivo

  • Execute o seguinte comando para alterar a saída do alto-falante para um arquivo .wav :

    spx synthesize --text "I'm excited to try text to speech" --audio output greetings.wav
    

A CLI de fala produz linguagem natural em inglês para o arquivo de áudio greetings.wav .

Executar e usar um contêiner

Os contêineres de fala fornecem APIs de ponto de extremidade de consulta baseadas em websocket que são acessadas por meio do SDK de Fala e da CLI de Fala. Por padrão, o SDK de Fala e a CLI de Fala usam o serviço de Fala público. Para usar o contêiner, você precisa alterar o método de inicialização. Use uma URL de host de contêiner em vez de chave e região.

Para obter mais informações sobre contêineres, consulte Instalar e executar contêineres de fala com o Docker.

Próximos passos