/** * @fileoverview Unified text-to-speech API supporting Kokoro (default) and Deepgram * * Kokoro: Faster, more natural, runs on Node CPU * Deepgram: Requires Cloudflare AI binding, MP3 output */ import type { TTSOptions, TTSResult } from "./types/types"; import { generateKokoroSpeech } from "./core/kokoro"; import { generateDeepgramSpeech } from "./core/deepgram"; export * from "./types/types"; // Markdown handling is exported from the root entry so a server route can turn a // document into speakable text with the same rules the CLI and the browser use. export { looksLikeMarkdown, markdownToSpeech, markdownToSpeechSegments, stripInlineMarkdown, type MarkdownToSpeechOptions, type SpeechSegment, type SpeechSegmentType, } from "./utils/markdown-to-speech"; export { encodeWav, concatSamples, wavDurationSeconds } from "./utils/wav"; /** * Generate speech from text using the specified provider * * @param options - TTS configuration * @returns Audio buffer and content type * * @example * ```ts * // Use Kokoro (default) * const audio = await generateSpeech({ * text: "Hello world", * voice: "af_heart" * }); * * // Use Deepgram * const audio = await generateSpeech({ * text: "Hello world", * provider: "deepgram", * voice: "angus" * }); * ``` */ export async function generateSpeech( options: TTSOptions ): Promise { const { text, provider = "kokoro", voice = "af_heart" } = options; if (!text || typeof text !== "string" || text.trim().length === 0) { throw new Error("Text is required"); } switch (provider) { case "kokoro": return generateKokoroSpeech(text, voice); case "deepgram": return generateDeepgramSpeech(text, voice); default: throw new Error(`Unknown TTS provider: ${provider}`); } }