// Text-to-Speech - Unified interface for multiple TTS models // Endpoint: /tts import { type AIMLAPIClient } from '../client'; import { buildPath } from './_paths'; // ===== VERSION ===== const VERSION = 'v1' as const; /** * Base text-to-speech parameters */ export interface TextToSpeechParams { model: string; text?: string; // Make text optional for models that use script instead script?: string; // For Microsoft VibeVoice models } /** * Unified Text-to-Speech create parameters interface * Following the same approach as images and speech-to-text resources */ export interface TextToSpeechCreateParams extends TextToSpeechParams { // Voice parameter - supports all provider voice types voice?: string; // Alibaba Qwen3 TTS Flash specific parameters // (uses voice parameter above) // Deepgram Aura specific parameters container?: string; encoding?: 'linear16' | 'mulaw' | 'alaw' | 'mp3' | 'opus' | 'flac' | 'aac'; sample_rate?: string; // ElevenLabs specific parameters apply_text_normalization?: 'auto' | 'on' | 'off'; next_text?: string; previous_text?: string; output_format?: | 'mp3_22050_32' | 'mp3_44100_32' | 'mp3_44100_64' | 'mp3_44100_96' | 'mp3_44100_128' | 'mp3_44100_192' | 'pcm_8000' | 'pcm_16000' | 'pcm_22000' | 'pcm_24000' | 'pcm_44100' | 'pcm_48000' | 'ulaw_8000' | 'alaw_8000' | 'opus_48000_32' | 'opus_48000_64' | 'opus_48000_96' | 'opus_48000_128' | 'opus_48000_192'; voice_settings?: { stability?: number; use_speaker_boost?: boolean; similarity_boost?: number; style?: number; speed?: number; }; seed?: number; // Inworld TTS specific parameters format?: 'wav' | 'mp3'; // Microsoft VibeVoice specific parameters script?: string; speakers?: Array<{ preset?: string; audio_url?: string; }>; cfg_scale?: number; // OpenAI TTS specific parameters style?: string; response_format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'; speed?: number; } /** * Text-to-speech creation response */ export interface TextToSpeechCreateResponse { audio: { url: string; }; meta?: { usage?: { credits_used: number; }; }; } /** * Text-to-speech streaming response (for models that return raw audio) */ export interface TextToSpeechStreamResponse { audio: Buffer; // Raw audio data meta?: { usage?: { credits_used: number; }; }; } /** * Text-to-speech response metadata */ export interface TextToSpeechMetadata { transaction_key: string; request_id: string; sha256: string; created: string; duration: number; channels: number; models: string[]; model_info: Record< string, { name: string; version: string; arch: string; } >; } /** * Text-to-speech response with metadata */ export interface TextToSpeechResponse { metadata: TextToSpeechMetadata; } /** * Text-to-Speech resource class * Handles text-to-speech API calls with unified parameter interface */ export class TextToSpeech { constructor(private readonly _client: AIMLAPIClient) {} /** * Create text-to-speech audio (JSON response) * @example * ```typescript * const result = await client.textToSpeech.create({ * model: 'openai/tts-1', * text: 'Hello, world!', * voice: 'alloy' * }); * ``` */ async create( params: TextToSpeechCreateParams, options?: any ): Promise { // Transform parameters for API compatibility const apiParams = this._transformToApiParams(params); return this._client.post(buildPath('/tts', VERSION), { body: apiParams, ...options, headers: { ...options?.headers, // Always request JSON for the main create method Accept: 'application/json', }, }); } /** * Create text-to-speech audio (streaming response for models that support it) * @example * ```typescript * const result = await client.textToSpeech.createStream({ * model: '#g1_aura-athena-en', * text: 'Hello, world!', * encoding: 'mp3' * }); * ``` */ async createStream( params: TextToSpeechCreateParams, options?: any ): Promise { // Transform parameters for API compatibility const apiParams = this._transformToApiParams(params); return this._client.post(buildPath('/tts', VERSION), { body: apiParams, ...options, headers: { ...options?.headers, // Request audio for streaming Accept: 'audio/*', }, // We'll handle the raw response in the test }); } /** * Transform unified parameters to API-specific format * Filters out undefined parameters and handles model-specific transformations */ private _transformToApiParams(params: TextToSpeechCreateParams): Record { const transformed: Record = {}; // Base parameters transformed.model = params.model; // Handle text or script parameter if (params.text) { transformed.text = params.text; } if (params.script) { transformed.script = params.script; } // All possible parameters const allParams = [ // Alibaba Qwen3 TTS Flash 'voice', // Deepgram Aura 'container', 'encoding', 'sample_rate', // ElevenLabs 'apply_text_normalization', 'next_text', 'previous_text', 'output_format', 'voice_settings', 'seed', // Inworld TTS 'format', // Microsoft VibeVoice 'speakers', 'cfg_scale', // OpenAI TTS 'style', 'response_format', 'speed', ]; // Add all defined parameters to transformed object allParams.forEach((param) => { const value = params[param as keyof TextToSpeechCreateParams]; if (value !== undefined) { transformed[param] = value; } }); return transformed; } /** * Check if model returns streaming audio response */ private _isStreamingModel(model: string): boolean { // Models that return streaming audio responses const streamingModels: string[] = [ // Deepgram Aura models '#g1_aura-angus-en', '#g1_aura-arcas-en', '#g1_aura-asteria-en', '#g1_aura-athena-en', '#g1_aura-helios-en', '#g1_aura-hera-en', '#g1_aura-luna-en', '#g1_aura-orion-en', '#g1_aura-orpheus-en', '#g1_aura-perseus-en', '#g1_aura-stella-en', '#g1_aura-zeus-en', '#g1_aura-2-amalthea-en', '#g1_aura-2-andromeda-en', '#g1_aura-2-apollo-en', '#g1_aura-2-arcas-en', '#g1_aura-2-aries-en', '#g1_aura-2-asteria-en', '#g1_aura-2-athena-en', '#g1_aura-2-atlas-en', '#g1_aura-2-aurora-en', '#g1_aura-2-cora-en', '#g1_aura-2-cordelia-en', '#g1_aura-2-delia-en', '#g1_aura-2-draco-en', '#g1_aura-2-electra-en', '#g1_aura-2-harmonia-en', '#g1_aura-2-helena-en', '#g1_aura-2-hera-en', '#g1_aura-2-hermes-en', '#g1_aura-2-hyperion-en', '#g1_aura-2-iris-en', '#g1_aura-2-janus-en', '#g1_aura-2-juno-en', '#g1_aura-2-jupiter-en', '#g1_aura-2-luna-en', '#g1_aura-2-mars-en', '#g1_aura-2-minerva-en', '#g1_aura-2-neptune-en', '#g1_aura-2-odysseus-en', '#g1_aura-2-ophelia-en', '#g1_aura-2-orion-en', '#g1_aura-2-orpheus-en', '#g1_aura-2-pandora-en', '#g1_aura-2-phoebe-en', '#g1_aura-2-pluto-en', '#g1_aura-2-saturn-en', '#g1_aura-2-selene-en', '#g1_aura-2-thalia-en', '#g1_aura-2-theia-en', '#g1_aura-2-vesta-en', '#g1_aura-2-zeus-en', '#g1_aura-2-celeste-es', '#g1_aura-2-estrella-es', '#g1_aura-2-nestor-es', // ElevenLabs models 'elevenlabs/eleven_multilingual_v2', 'elevenlabs/eleven_turbo_v2_5', // Minimax models 'minimax/speech-2.6-hd', 'minimax/speech-2.5-turbo-preview', ]; return streamingModels.includes(model); } }