# `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 ```ts 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 ```ts 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` - 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.