Provider-agnostic Text-to-Audio middleware for music and sound effect generation.
Table of Contents
- Multi-Provider Architecture — ElevenLabs (SFX + Music) and Google Lyria (Instrumental Music)
- Discriminated Union Requests — Full type safety with separate request types for sound effects and music
- Retry Logic — Exponential backoff with jitter for transient errors (429, 5xx, timeouts)
- Dry Mode — Validate requests without making API calls (no cost)
- Debug Logging — Markdown-based request/response logging
- TypeScript-First — Full type definitions with discriminated unions
- Typed Error Classes —
InvalidConfigError,QuotaExceededError,CapabilityNotSupportedError, etc. - Lazy SDK Loading — Provider SDKs loaded only when needed
npm install @loonylabs/tta-middleware
# Install provider SDK(s) you need:
npm install @elevenlabs/elevenlabs-js # For ElevenLabs
npm install @google-cloud/aiplatform # For Google Lyriaimport { TTAService, ElevenLabsTTAProvider } from '@loonylabs/tta-middleware';
const service = new TTAService();
service.registerProvider(new ElevenLabsTTAProvider({ apiKey: 'your-key' }));
// Generate a sound effect
const sfxResult = await service.generate({
type: 'sound_effect',
prompt: 'Thunder crash with echoes',
durationSeconds: 5,
});
// Generate music
const musicResult = await service.generate({
type: 'music',
prompt: 'Smooth jazz piano trio',
musicLengthMs: 30000,
});
// Access the audio
const audioBase64 = sfxResult.audio[0].data;
const contentType = sfxResult.audio[0].contentType; // 'audio/mpeg'| Provider | Model | Type | Looping | Instrumental Only | Max Duration |
|---|---|---|---|---|---|
| ElevenLabs | eleven_text_to_sound_v2 |
Sound Effects | Yes | No | 30s |
| ElevenLabs | music_v1 |
Music | No | No | 600s |
| Google Lyria | lyria-002 |
Music | No | Yes | 600s |
const service = new TTAService();
// Provider management
service.registerProvider(provider);
service.getProvider(TTAProvider.ELEVENLABS);
service.getAvailableProviders();
service.setDefaultProvider(TTAProvider.GOOGLE_LYRIA);
// Generation
const result = await service.generate(request, provider?);
// Discovery
service.listAllModels();
service.findProvidersWithCapability('soundEffects');Sound Effect Request:
interface TTASoundEffectRequest {
type: 'sound_effect';
prompt: string;
durationSeconds?: number; // 0.5-30
promptInfluence?: number; // 0-1
loop?: boolean;
model?: string;
outputFormat?: string;
retry?: boolean | RetryOptions;
dry?: boolean;
}Music Request:
interface TTAMusicRequest {
type: 'music';
prompt: string;
musicLengthMs?: number; // 3000-600000
forceInstrumental?: boolean;
seed?: number;
negativePrompt?: string;
model?: string;
outputFormat?: string;
retry?: boolean | RetryOptions;
dry?: boolean;
}interface TTAResponse {
audio: TTAAudio[]; // Array of generated audio clips
metadata: {
provider: string;
model: string;
region?: string;
duration: number; // Request duration in ms
};
usage: TTAUsage;
billing?: TTABilling;
}Test without API calls:
const result = await service.generate({
type: 'sound_effect',
prompt: 'test',
dry: true, // Returns placeholder audio, no API call
});const result = await service.generate({
type: 'music',
prompt: 'jazz piano',
retry: {
maxRetries: 5,
delayMs: 1000,
backoffMultiplier: 2.0,
maxDelayMs: 30000,
jitter: true,
timeoutMs: 60000,
},
});# Enable via environment variable
DEBUG_TTA_REQUESTS=trueimport { TTADebugger } from '@loonylabs/tta-middleware';
TTADebugger.setEnabled(true);
TTADebugger.setLogsDir('./logs/tta/requests');import {
TTAError,
InvalidConfigError,
QuotaExceededError,
CapabilityNotSupportedError,
} from '@loonylabs/tta-middleware';
try {
await service.generate(request);
} catch (error) {
if (error instanceof QuotaExceededError) {
console.log('Rate limited, try again later');
} else if (error instanceof CapabilityNotSupportedError) {
console.log('This provider/model does not support the requested type');
}
}# Run all unit tests
npm test
# Watch mode
npm run test:unit:watch
# Coverage report
npm run test:unit:coverage
# Manual tests (requires API keys)
npm run test:manual:elevenlabs-sfx
npm run test:manual:elevenlabs-music
npm run test:manual:google-lyria- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Write tests for your changes
- Ensure
npm run build && npm testpasses - Submit a pull request
MIT - see LICENSE for details.