Pular para o conteúdo principal

Desafio 35: Text-to-Speech e SSML

Tempo Estimado

45 min | Custo: $2-5 (estimado) | Domínio: Implementar Soluções de NLP (15-20%)

Habilidades do exame abordadas

  • Implementar síntese de text-to-speech
  • Melhorar a saída de fala com SSML (Speech Synthesis Markup Language)
  • Configurar seleção de voz e formatos de saída de áudio

Visão Geral

O Azure Text-to-Speech (TTS) converte texto em áudio com som natural:

RecursoDescrição
Vozes neuraisVozes geradas por IA (400+ em 140 idiomas)
SSMLMarcação XML para controlar prosódia, ênfase, pausas
Formatos de áudioWAV, MP3, OGG, PCM raw
VisemeDados de posição da boca para animação de avatar
Custom Neural VoiceTreine uma voz única (requer aprovação)

Elementos SSML: <speak>, <voice>, <prosody>, <emphasis>, <break>, <say-as>, <phoneme>

Pré-requisitos

  • Assinatura do Azure
  • Recurso Azure Speech
  • Python 3.9+ ou .NET 8
  • Pacote: azure-cognitiveservices-speech (v1.38+)
  • Dispositivo de saída de áudio (alto-falante) ou saída em arquivo

Implementação

Tarefa 1: Text-to-Speech Básico

import os
import azure.cognitiveservices.speech as speechsdk

speech_config = speechsdk.SpeechConfig(
subscription=os.environ["AZURE_SPEECH_KEY"],
region=os.environ["AZURE_SPEECH_REGION"]
)

# Set voice
speech_config.speech_synthesis_voice_name = "en-US-JennyNeural"

# Set output format
speech_config.set_speech_synthesis_output_format(
speechsdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3
)

# Synthesize to audio file
audio_config = speechsdk.audio.AudioOutputConfig(filename="output.mp3")
synthesizer = speechsdk.SpeechSynthesizer(
speech_config=speech_config,
audio_config=audio_config
)

text = "Welcome to Azure AI Services. Today we'll explore text-to-speech capabilities."
result = synthesizer.speak_text_async(text).get()

if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
print(f"Speech synthesized successfully!")
print(f"Audio duration: {result.audio_duration / 10_000_000:.2f} seconds")
print(f"Audio length: {len(result.audio_data)} bytes")
elif result.reason == speechsdk.ResultReason.Canceled:
cancellation = result.cancellation_details
print(f"Synthesis canceled: {cancellation.reason}")
print(f"Error: {cancellation.error_details}")

Tarefa 2: SSML para Controle Avançado de Fala

# Synthesize using SSML for fine control
ssml = """
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis"
xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="en-US">
<voice name="en-US-JennyNeural">
<prosody rate="-10%" pitch="+5%">
Welcome to the Azure AI certification prep.
</prosody>

<break time="500ms"/>

<emphasis level="strong">
This is an important concept.
</emphasis>

<break time="300ms"/>

<prosody volume="soft" rate="slow">
Let me explain it step by step.
</prosody>

<break time="500ms"/>

<!-- Pronunciation control -->
The API version is <say-as interpret-as="characters">3.0</say-as>.

<break time="200ms"/>

<!-- Date and number formatting -->
The release date is <say-as interpret-as="date" format="mdy">01/15/2024</say-as>.
The cost is <say-as interpret-as="currency" language="en-US">$2.50</say-as>.
</voice>
</speak>
"""

# Use SSML synthesis
audio_config = speechsdk.audio.AudioOutputConfig(filename="ssml-output.mp3")
synthesizer = speechsdk.SpeechSynthesizer(
speech_config=speech_config,
audio_config=audio_config
)

result = synthesizer.speak_ssml_async(ssml).get()

if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
print(f"SSML synthesis complete: {len(result.audio_data)} bytes")
print(f"Duration: {result.audio_duration / 10_000_000:.2f}s")

Tarefa 3: Listar Vozes Disponíveis

# List all available voices
synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
voices_result = synthesizer.get_voices_async("en-US").get()

if voices_result.reason == speechsdk.ResultReason.VoicesListRetrieved:
print(f"Available en-US voices ({len(voices_result.voices)}):")
for voice in voices_result.voices[:10]:
print(f" {voice.short_name}: {voice.local_name} "
f"({voice.gender.name}, {voice.voice_type.name})")
if voice.style_list:
print(f" Styles: {', '.join(voice.style_list)}")

Saída Esperada

Speech synthesized successfully!
Audio duration: 4.82 seconds
Audio length: 77120 bytes

SSML synthesis complete: 98304 bytes
Duration: 8.15s

Available en-US voices (148):
en-US-JennyNeural: Jenny (Female, Neural)
Styles: assistant, chat, customerservice, newscast, angry, cheerful, sad
en-US-GuyNeural: Guy (Male, Neural)
Styles: newscast, angry, cheerful, sad
en-US-AriaNeural: Aria (Female, Neural)
Styles: chat, customerservice, narration-professional

Quebra & conserta

CenárioSintomaCausa RaizCorreção
Sem saída de áudio0 bytes geradosNome de voz inválidoUse o short_name exato da lista de vozes
Erro de parse SSMLSíntese canceladaXML malformadoValide a estrutura SSML; verifique URIs de namespace
Voz não encontradaErro de cancelamentoVoz não disponível na regiãoVerifique disponibilidade da voz por região
Qualidade de áudio ruimSom robóticoUsando vozes standard antigasMude para vozes Neural (sufixo *Neural)
Arquivo muito grandeBytes de áudio excessivosFormato de saída erradoUse formato comprimido (MP3/OGG) em vez de PCM raw

Verificação de Conhecimento

1. Qual é o propósito do elemento SSML <prosody>?

2. Qual método você usa para sintetizar fala a partir de SSML?

3. O que o elemento SSML <say-as> faz?

4. Quais formatos de saída de áudio estão disponíveis para text-to-speech?

5. Como você insere uma pausa na fala sintetizada?

Limpeza

az group delete --name rg-ai102-speech --yes --no-wait

Saiba Mais