Initial Commit
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# `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.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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<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.
|
||||
Reference in New Issue
Block a user