Files
skills/docs/media/audio/voice-elevenlabs/src/sound-effects/sound-effects.md
2026-05-29 08:20:56 +01:00

3.2 KiB
Raw Blame History

sound-generation

ElevenLabs implementation of @suaveplan/voice's SoundEffectEngine interface. Posts a JSON body to POST /v1/sound-generation and returns the generated audio as raw bytes.

(no submodules)

Purpose

Generative sound effects are an ElevenLabs strength but the /v1/sound-generation endpoint has its own request shape with snake_case fields and ElevenLabs-specific knobs (prompt_influence, loop). This adapter maps the SoundEffectRequest shape (camelCase, with optional duration / prompt-influence / loop / model id / output format) onto the wire body and remaps every error onto the @suaveplan/voice domain. Application code stays portable across providers; only this file knows the upstream conventions.

Features

  • One method, generate(request), returning the raw audio bytes plus the requested format (defaulting to mp3_44100_128).
  • Optional durationSeconds (0.5–30s typical), loop, promptInfluence (0..1), modelId, and outputFormat are forwarded when defined and omitted otherwise.
  • Surfaces the upstream x-request-id on the result.
  • Errors are remapped: 401 → ProviderNotConfiguredError, 429 → ProviderRateLimitedError (with retryAfterMs), 5xx → SoundEffectGenerationFailedError.
  • Built-in retry / backoff inherited from the shared ElevenLabsClient.

Usage: Basic Example

import { createElevenLabsAdapters } from "@suaveplan/third-party-elevenlabs";

const { soundEffects } = createElevenLabsAdapters({ apiKey: KEY });
const { audio } = await soundEffects.generate({ text: "ocean waves at dusk" });
await Bun.write("waves.mp3", audio);

Usage: Advanced Example

import {
    ElevenLabsClient,
    ElevenLabsSoundEffectEngine,
} from "@suaveplan/third-party-elevenlabs";

const eng = new ElevenLabsSoundEffectEngine(
    new ElevenLabsClient({ apiKey: KEY, timeoutMs: 60_000 })
);

const ctrl = new AbortController();
const result = await eng.generate({
    text: "thunderclap followed by rain",
    durationSeconds: 8,
    loop: false,
    promptInfluence: 0.7,
    modelId: "sound_v2",
    outputFormat: "wav_44100",
    signal: ctrl.signal,
});
console.log(`got ${result.audio.byteLength} bytes`, result.requestId);

API Reference

  • class ElevenLabsSoundEffectEngine implements SoundEffectEngine
    • providerName: "elevenlabs"
    • generate(request: SoundEffectRequest): Promise<SoundEffectResult>
      • returns { audio, format, requestId? }.

Throws: ProviderNotConfiguredError, ProviderRateLimitedError, SoundEffectGenerationFailedError.

Implementation Notes

  • The format on the result reflects the requested format, not necessarily the encoded output — ElevenLabs may return a different format if it rejects the request. Inspect the response bytes / use a metadata reader if you need ground truth.
  • prompt_influence defaults to ElevenLabs's server-side default when omitted (commonly 0.3); set explicitly to 0–1 for deterministic control.
  • text is sent verbatim — there is no client-side validation. Empty text will be rejected upstream as a 422.
  • The adapter inherits retry, timeout, and observability events from the shared ElevenLabsClient. Configure them on the client, not here.