Crea una voz personalizada con diseño de voz

Puedes crear una voz personalizada a partir de una descripción en lenguaje natural con la función de diseño de voz. En lugar de elegir una voz prediseñada o grabar audio de referencia, creas una voz describiendo la edad, el timbre, el acento y la interpretación básica de un personaje. La API de Voices almacena la voz en tu proyecto y devuelve un ID de voice_... reutilizable que pasas en las solicitudes de generación de voz.

Las voces diseñadas funcionan con Gemini 3.8 Flash TTS (gemini-3.8-flash-tts) y Gemini 3.8 Flash-Lite TTS (gemini-3.8-flash-lite-tts).

Cómo funciona el diseño de voz

  1. Crea una voz guiada: Llama al método create de la API de Voices con voice.type establecido en VOICE_TYPE_PROMPTED y store establecido en true.
  2. Recibe un ID de voz y una muestra: La API de Voices genera la voz, la almacena en tu proyecto y muestra su ID (por ejemplo, voice_abc123...) en el campo id y una muestra de la voz en el campo sample_audio.
  3. Generar voz: Pasa el ID de voz en speechConfig.voiceConfig.voice cuando llames a generateContent o streamGenerateContent.

Antes de comenzar

Completa los pasos que se indican en Antes de comenzar en la página de TTS de Gemini. La API de Voices está disponible en la ubicación global a través de la versión de la API de v1beta1.

Crea una voz diseñada

Configura los siguientes campos en la solicitud:

  • store: Debe ser true. Las voces diseñadas siempre se almacenan en tu proyecto.
  • voice.type: VOICE_TYPE_PROMPTED.
  • voice.prompted.input: Es una descripción en lenguaje natural de la voz.
  • voice.display_name, voice.gender, voice.language_code: Metadatos opcionales de la voz.

No establezcas voice.model. Las solicitudes que establecen un modelo junto con store: true fallan con un error INVALID_ARGUMENT.

El diseño de una voz puede tardar varios segundos. La muestra de Python establece el tiempo de espera de la solicitud en 60 segundos.

La respuesta contiene los siguientes campos:

  • id: Es el ID de la voz nueva.
  • sample_audio: Muestra de la voz. El campo data contiene el audio codificado en Base64, y el campo mime_type nombra su codificación. Por ejemplo, audio/l16; rate=24000; channels=1 es PCM de 16 bits sin encabezado a 24 kHz, mono.
  • usage: Es la cantidad de tokens que usó la solicitud. Para obtener más información, consulta Precios.

Python

import base64
import wave

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

voice = client.voices.create(
    store=True,
    voice={
        "type": "VOICE_TYPE_PROMPTED",
        "display_name": "Warm British Astronomer",
        "gender": "male",
        "language_code": "en-GB",
        "prompted": {
            "input": (
                "A warm, thoughtful astronomer in his late 60s with a gentle"
                " British accent, speaking with quiet wonder."
            )
        },
    },
    timeout=60,
)

print(f"Created voice ID: {voice.id}")

# Save the voice sample. The SDK returns sample_audio.data as a base64
# string. Raw 16-bit PCM (audio/l16) needs a WAV header.
sample = base64.b64decode(voice.sample_audio.data)
if voice.sample_audio.mime_type.lower().startswith("audio/l16"):
    with wave.open("voice_sample.wav", "wb") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)
        wf.writeframes(sample)
else:
    with open("voice_sample.wav", "wb") as f:
        f.write(sample)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  -d '{
    "store": true,
    "voice": {
      "type": "VOICE_TYPE_PROMPTED",
      "displayName": "Warm British Astronomer",
      "gender": "male",
      "languageCode": "en-GB",
      "prompted": {
        "input": "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder."
      }
    }
  }' > created_voice.json

# Print the voice ID and the encoding of the voice sample.
jq -r '.id, .sample_audio.mime_type' created_voice.json

# Decode the voice sample.
jq -r '.sample_audio.data' created_voice.json | base64 --decode > voice_sample.pcm

Si sample_audio.mime_type es audio/l16, el archivo voice_sample.pcm contiene audio PCM de 16 bits sin encabezado a 24 kHz, mono.

Para escuchar la voz con tu propio texto, genera voz con ella como se muestra en la siguiente sección.

Genera voz con una voz diseñada

Pasa el ID de voz en speechConfig.voiceConfig.voice:

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

response = client.models.generate_content(
    model="gemini-3.8-flash-tts",
    contents=[{
        "role": "user",
        "parts": [{
            "text": (
                "Look out past the rings of Saturn. Those faint photons left"
                " their source millions of years ago."
            ),
            "speech_metadata": {"style": "reflective and awe-inspired"},
        }],
    }],
    config={
        "response_modalities": ["AUDIO"],
        "speech_config": {"voice_config": {"voice": "VOICE_ID"}},
    },
)

# The SDK has already decoded the base64 audio, so inline_data.data is a
# complete WAV file by default.
with open("designed_voice.wav", "wb") as f:
    f.write(response.candidates[0].content.parts[0].inline_data.data)

REST

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.8-flash-tts:generateContent \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [{
        "text": "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.",
        "speechMetadata": {"style": "reflective and awe-inspired"}
      }]
    }],
    "generationConfig": {
      "responseModalities": ["AUDIO"],
      "speechConfig": {
        "voiceConfig": {"voice": "VOICE_ID"}
      }
    }
  }' | jq -r '.candidates[0].content.parts[0].inlineData.data' | base64 --decode > designed_voice.wav

Reemplaza VOICE_ID por el ID de voz que devolvió el método create.

Administra las voces almacenadas

Puedes enumerar, obtener y borrar las voces almacenadas en tu proyecto, incluidas las voces diseñadas y las voces replicadas almacenadas. El método list devuelve las voces almacenadas en tu proyecto, seguidas de las voces prediseñadas y de la Biblioteca de voces extendida. Para enumerar solo las voces almacenadas en tu proyecto, establece el filtro type en prompted y replicated, como se muestra en los siguientes ejemplos. El método get también devuelve la muestra de una voz diseñada en el campo sample_audio.

Python

from google import genai

client = genai.Client(enterprise=True, project="PROJECT_ID", location="global")

# List the voices stored in your project.
for voice in client.voices.list(type_=["prompted", "replicated"]).voices or []:
    print(voice.id, voice.display_name, voice.type)

# Get a voice by ID.
voice = client.voices.get(id="VOICE_ID")

# Delete a voice.
client.voices.delete(id="VOICE_ID")

REST

# List the voices stored in your project.
curl -G \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices \
  --data-urlencode "type=prompted" \
  --data-urlencode "type=replicated"

# Get a voice by ID.
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

# Delete a voice.
curl -X DELETE \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  https://aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/global/voices/VOICE_ID

Límites

  • Las voces almacenadas vencen un año después de su último uso. Si generas voz con una voz, se reinicia este período, por lo que una voz que usas con regularidad no vence. Borra las voces que ya no necesites.
  • Las solicitudes de creación de voz están sujetas a una cuota por proyecto y por minuto. Si lo superas, el método create devuelve un error RESOURCE_EXHAUSTED. Espera un momento y vuelve a intentarlo. Para obtener más información, consulta Cuotas y límites del sistema.

Precios

La creación de una voz diseñada se factura como tokens de entrada de texto y tokens de salida de audio según las tarifas de Gemini 3.8 Flash TTS. Los tokens de salida de audio abarcan la muestra de voz que genera la API de Voices. El campo usage en la respuesta create informa ambos recuentos. Por ejemplo, la descripción de una oración en el ejemplo de creación usa alrededor de 220 tokens de entrada y 1,100 tokens de salida.

Los métodos get, list y delete no se facturan. El discurso que generas con una voz diseñada se factura según las tarifas del modelo al que llamas.

Para conocer las tarifas de tokens, consulta los precios de Gemini Enterprise.

Prácticas recomendadas para escribir instrucciones

  • Coloca rasgos permanentes en la descripción de la voz: Define la edad, el género, el timbre, la textura vocal y el acento regional cuando crees la voz, no en speech_metadata.style.
  • Usa speech_metadata.style para expresar emociones situacionales: Después de crear la voz, usa valores de style cortos, como "whispered urgently" o "cheerful and energetic", para dirigir cada turno sin cambiar la identidad del orador.
  • Sé específico y conciso: Una descripción clara de una o dos oraciones, como "Una locutora deportiva enérgica y nítida de unos 30 años con un ligero acento del Medio Oeste", produce resultados más coherentes que un párrafo largo o contradictorio.

¿Qué sigue?