speech-to-speech 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tts/prepare-piper-voice.ts","../../src/tts/stream-tokens-to-speech.ts","../../src/tts/ort-setup.ts","../../src/tts/piper.ts","../../src/tts/use-streaming-tts.ts","../../src/tts/piper-synthesizer.ts","../../src/tts/audio-player.ts"],"names":["piperTts"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface PiperVoiceConfig {\r\n voiceId: string;\r\n modelPath?: string;\r\n sampleRate?: number;\r\n lengthScale?: number;\r\n noiseScale?: number;\r\n speaker?: string;\r\n}\r\n\r\nexport interface PreparedPiperVoice {\r\n voiceId: string;\r\n modelPath: string;\r\n sampleRate: number;\r\n inference: {\r\n lengthScale: number;\r\n noiseScale: number;\r\n };\r\n metadata: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Normalize Piper voice configuration so downstream synthesis gets predictable defaults.\r\n */\r\nexport function preparePiperVoice(config: PiperVoiceConfig): PreparedPiperVoice {\r\n const modelPath = config.modelPath ?? `voices/${config.voiceId}.onnx`;\r\n\r\n return {\r\n voiceId: config.voiceId,\r\n modelPath,\r\n sampleRate: config.sampleRate ?? 22050,\r\n inference: {\r\n lengthScale: config.lengthScale ?? 1.0,\r\n noiseScale: config.noiseScale ?? 0.667,\r\n },\r\n metadata: {\r\n speaker: config.speaker ?? \"default\",\r\n },\r\n };\r\n}\r\n","export interface StreamTokensOptions {\r\n chunkSize?: number;\r\n delayMs?: number;\r\n onChunk?: (text: string) => Promise<void> | void;\r\n}\r\n\r\nexport interface StreamTokensResult {\r\n chunksEmitted: number;\r\n characters: number;\r\n}\r\n\r\nfunction isAsyncIterable<T>(value: AsyncIterable<T> | Iterable<T>): value is AsyncIterable<T> {\r\n return typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\";\r\n}\r\n\r\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\r\n\r\n/**\r\n * Convert incremental tokens to speech-sized chunks. Consumers can bridge this into an audio renderer.\r\n */\r\nexport async function streamTokensToSpeech(\r\n tokens: AsyncIterable<string> | Iterable<string>,\r\n options: StreamTokensOptions = {},\r\n): Promise<StreamTokensResult> {\r\n const chunkSize = options.chunkSize ?? 40;\r\n const delayMs = options.delayMs ?? 0;\r\n\r\n let buffer = \"\";\r\n let chunksEmitted = 0;\r\n let characters = 0;\r\n\r\n const emit = async () => {\r\n if (!buffer) return;\r\n characters += buffer.length;\r\n chunksEmitted += 1;\r\n if (options.onChunk) {\r\n await options.onChunk(buffer);\r\n }\r\n buffer = \"\";\r\n if (delayMs > 0) {\r\n await sleep(delayMs);\r\n }\r\n };\r\n\r\n if (isAsyncIterable(tokens)) {\r\n for await (const token of tokens) {\r\n buffer += token;\r\n if (buffer.length >= chunkSize) {\r\n await emit();\r\n }\r\n }\r\n } else {\r\n for (const token of tokens) {\r\n buffer += token;\r\n if (buffer.length >= chunkSize) {\r\n await emit();\r\n }\r\n }\r\n }\r\n\r\n if (buffer) {\r\n await emit();\r\n }\r\n\r\n return { chunksEmitted, characters };\r\n}\r\n","export type OrtDevice = \"cpu\" | \"webgpu\";\r\nexport type OrtLogLevel = \"verbose\" | \"warning\" | \"error\";\r\n\r\nexport interface OrtEnvironmentConfig {\r\n device?: OrtDevice;\r\n logLevel?: OrtLogLevel;\r\n providers?: string[];\r\n}\r\n\r\nexport interface OrtEnvironment {\r\n device: OrtDevice;\r\n logLevel: OrtLogLevel;\r\n providers: string[];\r\n initialized: boolean;\r\n init: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Minimal Onnx Runtime bootstrapper. This is intentionally dependency-light: callers can pass\r\n * a custom provider list when integrating with onnxruntime-web or node-ort.\r\n */\r\nexport async function createOrtEnvironment(\r\n config: OrtEnvironmentConfig = {},\r\n): Promise<OrtEnvironment> {\r\n const providers = config.providers ?? (config.device === \"webgpu\" ? [\"webgpu\", \"wasm\"] : [\"wasm\"]);\r\n\r\n const environment: OrtEnvironment = {\r\n device: config.device ?? \"cpu\",\r\n logLevel: config.logLevel ?? \"warning\",\r\n providers,\r\n initialized: false,\r\n async init() {\r\n // Real implementation would call into the ORT API. Here we just flip a flag for consumers.\r\n this.initialized = true;\r\n },\r\n };\r\n\r\n await environment.init();\r\n return environment;\r\n}\r\n","import { createOrtEnvironment, OrtEnvironment, OrtEnvironmentConfig } from \"./ort-setup.js\";\r\nimport { preparePiperVoice, PiperVoiceConfig, PreparedPiperVoice } from \"./prepare-piper-voice.js\";\r\n\r\nexport type SynthResult = string | ArrayBuffer | Uint8Array;\r\nexport type Synthesizer = (text: string, voice: PreparedPiperVoice) => Promise<SynthResult>;\r\nexport type Player = (audio: SynthResult) => Promise<void>;\r\n\r\nconst voiceCache = new Map<string, PreparedPiperVoice>();\r\nlet ortEnv: OrtEnvironment | null = null;\r\n\r\nexport async function ensureOrtReady(config: OrtEnvironmentConfig = {}): Promise<OrtEnvironment> {\r\n if (ortEnv) return ortEnv;\r\n ortEnv = await createOrtEnvironment(config);\r\n return ortEnv;\r\n}\r\n\r\nexport async function ensureVoiceLoaded(config: PiperVoiceConfig): Promise<PreparedPiperVoice> {\r\n const cached = voiceCache.get(config.voiceId);\r\n if (cached) return cached;\r\n const voice = preparePiperVoice(config);\r\n voiceCache.set(config.voiceId, voice);\r\n return voice;\r\n}\r\n\r\nexport async function warmupPiper(\r\n voiceConfig: PiperVoiceConfig,\r\n synth: Synthesizer,\r\n text = \"warmup\",\r\n): Promise<void> {\r\n const voice = await ensureVoiceLoaded(voiceConfig);\r\n await synth(text, voice);\r\n}\r\n\r\nexport function resetVoiceCache(): void {\r\n voiceCache.clear();\r\n}\r\n\r\nexport function getBackendLabel(device: string | undefined): string {\r\n if (!device) return \"auto\";\r\n return device === \"webgpu\" ? \"WebGPU\" : \"CPU\";\r\n}\r\n\r\nexport function isCorruptModelError(error: unknown): boolean {\r\n if (!error) return false;\r\n const msg = typeof error === \"string\" ? error : (error as { message?: string }).message;\r\n if (!msg) return false;\r\n return /corrupt|checksum|integrity/i.test(msg);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Workers and helpers\r\n// ---------------------------------------------------------------------------\r\n\r\nexport async function* synthesizerWorker(\r\n textQueue: AsyncIterable<string>,\r\n voiceConfig: PiperVoiceConfig,\r\n synth: Synthesizer,\r\n): AsyncGenerator<SynthResult, void, unknown> {\r\n const voice = await ensureVoiceLoaded(voiceConfig);\r\n for await (const text of textQueue) {\r\n yield synth(text, voice);\r\n }\r\n}\r\n\r\nexport async function playerWorker(\r\n audioQueue: AsyncIterable<SynthResult>,\r\n play: Player,\r\n): Promise<void> {\r\n for await (const audio of audioQueue) {\r\n await play(audio);\r\n }\r\n}\r\n\r\nexport function nextBoundaryIndex(text: string): number {\r\n const idx = text.search(/[.!?,]/);\r\n return idx >= 0 ? idx : -1;\r\n}\r\n\r\nexport function emitSentence(queue: SimpleQueue<string>, sentence: string): void {\r\n const trimmed = sentence.trim();\r\n if (trimmed) {\r\n queue.put(trimmed);\r\n }\r\n}\r\n\r\nexport function handleChunk(state: { buffer: string }, chunk: string, queue: SimpleQueue<string>): void {\r\n state.buffer += chunk;\r\n let boundary = nextBoundaryIndex(state.buffer);\r\n while (boundary >= 0) {\r\n const sentence = state.buffer.slice(0, boundary + 1);\r\n state.buffer = state.buffer.slice(boundary + 1);\r\n emitSentence(queue, sentence);\r\n boundary = nextBoundaryIndex(state.buffer);\r\n }\r\n}\r\n\r\nexport function getAsyncIterator<T>(\r\n source: AsyncIterable<T> | Iterable<T>,\r\n): AsyncIterable<T> {\r\n if ((source as AsyncIterable<T>)[Symbol.asyncIterator]) {\r\n return source as AsyncIterable<T>;\r\n }\r\n return {\r\n async *[Symbol.asyncIterator]() {\r\n for (const item of source as Iterable<T>) {\r\n yield item;\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport class SimpleQueue<T> implements AsyncIterable<T> {\r\n private buffer: T[] = [];\r\n private resolvers: Array<(value: IteratorResult<T>) => void> = [];\r\n\r\n put(item: T): void {\r\n if (this.resolvers.length > 0) {\r\n const resolve = this.resolvers.shift();\r\n resolve?.({ value: item, done: false });\r\n } else {\r\n this.buffer.push(item);\r\n }\r\n }\r\n\r\n size(): number {\r\n return this.buffer.length;\r\n }\r\n\r\n async get(): Promise<T> {\r\n if (this.buffer.length > 0) {\r\n return this.buffer.shift() as T;\r\n }\r\n return new Promise<T>((resolve) => {\r\n this.resolvers.push(({ value }) => resolve(value as T));\r\n });\r\n }\r\n\r\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\r\n while (true) {\r\n const value = await this.get();\r\n yield value;\r\n }\r\n }\r\n}\r\n","import { streamTokensToSpeech } from \"./stream-tokens-to-speech.js\";\r\nimport {\r\n ensureOrtReady,\r\n ensureVoiceLoaded,\r\n handleChunk,\r\n SimpleQueue,\r\n synthesizerWorker,\r\n playerWorker,\r\n getAsyncIterator,\r\n emitSentence,\r\n} from \"./piper.js\";\r\nimport type { PiperVoiceConfig, PreparedPiperVoice } from \"./prepare-piper-voice.js\";\r\nimport type { OrtEnvironmentConfig } from \"./ort-setup.js\";\r\nimport type { SynthResult, Synthesizer, Player } from \"./piper.js\";\r\n\r\nexport interface StreamingTTSOptions {\r\n voice: PiperVoiceConfig;\r\n ort?: OrtEnvironmentConfig;\r\n synth?: Synthesizer;\r\n play?: Player;\r\n chunkSize?: number;\r\n delayMs?: number;\r\n}\r\n\r\nexport interface StreamingTTSController {\r\n ensureReady(): Promise<void>;\r\n addChunk(text: string): Promise<void>;\r\n finishStreaming(): Promise<void>;\r\n stop(): void;\r\n synthAndPlayChunk(text: string): Promise<void>;\r\n processQueue(): Promise<void>;\r\n createTokenIterable(text: string): Iterable<string>;\r\n}\r\n\r\nconst defaultSynth: Synthesizer = async (text) => text;\r\nconst defaultPlayer: Player = async () => undefined;\r\n\r\nexport function useStreamingTTS(options: StreamingTTSOptions): StreamingTTSController {\r\n const textQueue = new SimpleQueue<string>();\r\n const audioQueue = new SimpleQueue<SynthResult>();\r\n const bufferState = { buffer: \"\" };\r\n\r\n let ready = false;\r\n let stopped = false;\r\n let voice: PreparedPiperVoice | null = null;\r\n\r\n const synth = options.synth ?? defaultSynth;\r\n const play = options.play ?? defaultPlayer;\r\n const chunkSize = options.chunkSize ?? 48;\r\n const delayMs = options.delayMs ?? 0;\r\n\r\n async function ensureReady(): Promise<void> {\r\n if (ready) return;\r\n await ensureOrtReady(options.ort ?? {});\r\n voice = await ensureVoiceLoaded(options.voice);\r\n ready = true;\r\n }\r\n\r\n async function addChunk(text: string): Promise<void> {\r\n handleChunk(bufferState, text, textQueue);\r\n if (bufferState.buffer.length >= chunkSize) {\r\n emitSentence(textQueue, bufferState.buffer);\r\n bufferState.buffer = \"\";\r\n }\r\n }\r\n\r\n async function finishStreaming(): Promise<void> {\r\n if (bufferState.buffer) {\r\n emitSentence(textQueue, bufferState.buffer);\r\n bufferState.buffer = \"\";\r\n }\r\n }\r\n\r\n function stop(): void {\r\n stopped = true;\r\n }\r\n\r\n async function synthAndPlayChunk(text: string): Promise<void> {\r\n await ensureReady();\r\n const audio = await synth(text, voice as PreparedPiperVoice);\r\n await play(audio);\r\n }\r\n\r\n async function processQueue(): Promise<void> {\r\n await ensureReady();\r\n const tokenIterator = getAsyncIterator(textQueue as AsyncIterable<string>);\r\n const audioIterator = synthesizerWorker(tokenIterator, options.voice, synth);\r\n await playerWorker(audioIterator, play);\r\n }\r\n\r\n function createTokenIterable(text: string): Iterable<string> {\r\n return text.split(/\\s+/g).filter(Boolean);\r\n }\r\n\r\n async function streamTokens(tokens: AsyncIterable<string> | Iterable<string>): Promise<void> {\r\n await ensureReady();\r\n await streamTokensToSpeech(tokens, {\r\n chunkSize,\r\n delayMs,\r\n onChunk: async (chunk) => {\r\n if (stopped) return;\r\n await synthAndPlayChunk(chunk);\r\n },\r\n });\r\n }\r\n\r\n // Kick off background processors\r\n processQueue().catch(() => undefined);\r\n streamTokens(textQueue as AsyncIterable<string>).catch(() => undefined);\r\n\r\n return {\r\n ensureReady,\r\n addChunk,\r\n finishStreaming,\r\n stop,\r\n synthAndPlayChunk,\r\n processQueue,\r\n createTokenIterable,\r\n };\r\n}\r\n","/**\r\n * Piper TTS Synthesizer using @realtimex/piper-tts-web\r\n * This library handles text-to-phoneme conversion properly using espeak-ng\r\n *\r\n * Note: @realtimex/piper-tts-web handles ONNX Runtime configuration internally,\r\n * so NO separate ort-setup.js is needed!\r\n */\r\n\r\nimport * as piperTts from \"@realtimex/piper-tts-web\";\r\n\r\nexport interface PiperSynthesizerConfig {\r\n /** Voice ID (e.g., \"en_US-hfc_female-medium\") */\r\n voiceId?: string;\r\n /** Sample rate (default: 22050) */\r\n sampleRate?: number;\r\n}\r\n\r\nexport interface SynthesisResult {\r\n /** Audio data as WAV Blob */\r\n audioBlob: Blob;\r\n /** Audio data as Float32Array (for direct playback) */\r\n audio: Float32Array;\r\n /** Sample rate */\r\n sampleRate: number;\r\n /** Duration in seconds */\r\n duration: number;\r\n}\r\n\r\nconst DEFAULT_VOICE_ID = \"en_US-hfc_female-medium\";\r\n\r\n/**\r\n * Piper TTS Synthesizer\r\n * Uses @mintplex-labs/piper-tts-web for proper text-to-speech conversion\r\n */\r\nexport class TTSLogic {\r\n private config: PiperSynthesizerConfig;\r\n private ready = false;\r\n private voiceLoaded = false;\r\n\r\n constructor(config: PiperSynthesizerConfig = {}) {\r\n this.config = {\r\n voiceId: DEFAULT_VOICE_ID,\r\n sampleRate: 22050,\r\n ...config,\r\n };\r\n }\r\n\r\n /**\r\n * Initialize the synthesizer by loading the voice model\r\n */\r\n async initialize(): Promise<void> {\r\n if (this.ready) return;\r\n\r\n try {\r\n const voiceId = this.config.voiceId!;\r\n console.log(\"📍 Loading Piper voice:\", voiceId);\r\n\r\n // Check if voice is already cached\r\n const storedVoices = await piperTts.stored();\r\n const alreadyCached = Array.isArray(storedVoices)\r\n ? storedVoices.includes(voiceId)\r\n : false;\r\n\r\n if (!alreadyCached) {\r\n console.log(\"⬇️ Downloading voice model...\");\r\n await piperTts.download(voiceId, (progress) => {\r\n if (progress?.total) {\r\n const pct = Math.round((progress.loaded * 100) / progress.total);\r\n console.log(`⬇️ Downloading: ${pct}%`);\r\n }\r\n });\r\n } else {\r\n console.log(\"✓ Voice found in cache\");\r\n }\r\n\r\n this.voiceLoaded = true;\r\n this.ready = true;\r\n console.log(\"✓ Piper synthesizer initialized\");\r\n } catch (error) {\r\n throw new Error(`Failed to initialize Piper synthesizer: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Check if the synthesizer is ready\r\n */\r\n isReady(): boolean {\r\n return this.ready;\r\n }\r\n\r\n /**\r\n * Synthesize speech from text\r\n * @param text - Text to convert to speech\r\n * @returns Audio data as WAV Blob and Float32Array\r\n */\r\n async synthesize(text: string): Promise<SynthesisResult> {\r\n if (!this.ready) {\r\n throw new Error(\"Synthesizer not initialized. Call initialize() first.\");\r\n }\r\n\r\n const trimmed = text?.trim();\r\n if (!trimmed) {\r\n throw new Error(\"No text provided for synthesis\");\r\n }\r\n\r\n try {\r\n // Use piper-tts-web to convert text to speech\r\n // This handles text-to-phoneme conversion internally using espeak-ng\r\n const wavBlob: Blob = await piperTts.predict({\r\n text: trimmed,\r\n voiceId: this.config.voiceId!,\r\n });\r\n\r\n // Convert Blob to Float32Array for direct playback\r\n const arrayBuffer = await wavBlob.arrayBuffer();\r\n const audioContext = new (window.AudioContext ||\r\n (window as any).webkitAudioContext)();\r\n const decodedBuffer = await audioContext.decodeAudioData(arrayBuffer);\r\n const audioData = decodedBuffer.getChannelData(0);\r\n audioContext.close();\r\n\r\n return {\r\n audioBlob: wavBlob,\r\n audio: audioData,\r\n sampleRate: decodedBuffer.sampleRate,\r\n duration: decodedBuffer.duration,\r\n };\r\n } catch (error) {\r\n throw new Error(`Synthesis failed: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Synthesize and return WAV Blob only (faster, no decoding)\r\n */\r\n async synthesizeToBlob(text: string): Promise<Blob> {\r\n if (!this.ready) {\r\n throw new Error(\"Synthesizer not initialized. Call initialize() first.\");\r\n }\r\n\r\n const trimmed = text?.trim();\r\n if (!trimmed) {\r\n throw new Error(\"No text provided for synthesis\");\r\n }\r\n\r\n return piperTts.predict({\r\n text: trimmed,\r\n voiceId: this.config.voiceId!,\r\n });\r\n }\r\n\r\n /**\r\n * Stop current synthesis (not directly supported, but we can track state)\r\n */\r\n stop(): void {\r\n // Piper doesn't have a stop method, but we track state\r\n console.log(\"Stop requested\");\r\n }\r\n\r\n /**\r\n * Dispose of the synthesizer and free resources\r\n */\r\n async dispose(): Promise<void> {\r\n this.ready = false;\r\n this.voiceLoaded = false;\r\n }\r\n}\r\n\r\n/**\r\n * Create and initialize a Piper synthesizer\r\n */\r\n// export async function createPiperSynthesizer(\r\n// config: PiperSynthesizerConfig = {}\r\n// ): Promise<PiperSynthesizer> {\r\n// const synthesizer = new PiperSynthesizer(config);\r\n// await synthesizer.initialize();\r\n// return synthesizer;\r\n// }\r\n\r\n/**\r\n * @deprecated Use PiperSynthesizer.synthesize() which handles text-to-phoneme internally\r\n * This is kept for backwards compatibility but should not be used directly\r\n */\r\nexport function textToPhonemes(_text: string): number[] {\r\n console.warn(\r\n \"textToPhonemes is deprecated. Use PiperSynthesizer.synthesize(text) instead.\"\r\n );\r\n return [];\r\n}\r\n","/**\r\n * Web Audio API Player\r\n * Plays synthesized audio using the Web Audio API\r\n */\r\n\r\nexport interface AudioPlayerConfig {\r\n sampleRate?: number;\r\n volume?: number;\r\n}\r\n\r\n/**\r\n * Audio Player for Web Audio API\r\n */\r\nexport class AudioPlayer {\r\n private audioContext: AudioContext | null = null;\r\n private config: AudioPlayerConfig;\r\n private currentSource: AudioBufferSourceNode | null = null;\r\n\r\n constructor(config: AudioPlayerConfig = {}) {\r\n this.config = {\r\n sampleRate: 22050,\r\n volume: 1.0,\r\n ...config,\r\n };\r\n }\r\n\r\n /**\r\n * Initialize the audio context\r\n */\r\n private getAudioContext(): AudioContext {\r\n if (!this.audioContext) {\r\n this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)({\r\n sampleRate: this.config.sampleRate,\r\n });\r\n }\r\n return this.audioContext;\r\n }\r\n\r\n /**\r\n * Play audio data\r\n * @param audioData - Float32Array of audio samples\r\n * @param sampleRate - Sample rate of the audio\r\n */\r\n async play(audioData: Float32Array, sampleRate: number): Promise<void> {\r\n const ctx = this.getAudioContext();\r\n\r\n // Resume audio context if suspended (browser security requirement)\r\n if (ctx.state === 'suspended') {\r\n await ctx.resume();\r\n }\r\n\r\n // Create audio buffer\r\n const audioBuffer = ctx.createBuffer(1, audioData.length, sampleRate);\r\n audioBuffer.getChannelData(0).set(audioData);\r\n\r\n // Create source\r\n const source = ctx.createBufferSource();\r\n source.buffer = audioBuffer;\r\n\r\n // Create gain node for volume control\r\n const gainNode = ctx.createGain();\r\n gainNode.gain.value = this.config.volume!;\r\n\r\n // Connect nodes\r\n source.connect(gainNode);\r\n gainNode.connect(ctx.destination);\r\n\r\n // Store current source\r\n this.currentSource = source;\r\n\r\n // Play\r\n source.start(0);\r\n\r\n // Wait for playback to finish\r\n return new Promise<void>((resolve) => {\r\n source.onended = () => {\r\n this.currentSource = null;\r\n resolve();\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Stop current playback\r\n */\r\n stop(): void {\r\n if (this.currentSource) {\r\n try {\r\n this.currentSource.stop();\r\n this.currentSource = null;\r\n } catch (error) {\r\n // Ignore errors if already stopped\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Set volume (0.0 to 1.0)\r\n */\r\n setVolume(volume: number): void {\r\n this.config.volume = Math.max(0, Math.min(1, volume));\r\n }\r\n\r\n /**\r\n * Close the audio context and free resources\r\n */\r\n async close(): Promise<void> {\r\n this.stop();\r\n if (this.audioContext) {\r\n await this.audioContext.close();\r\n this.audioContext = null;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Create and return an audio player instance\r\n */\r\nexport function createAudioPlayer(config?: AudioPlayerConfig): AudioPlayer {\r\n return new AudioPlayer(config);\r\n}\r\n"]}
@@ -0,0 +1,215 @@
1
+ interface PiperVoiceConfig {
2
+ voiceId: string;
3
+ modelPath?: string;
4
+ sampleRate?: number;
5
+ lengthScale?: number;
6
+ noiseScale?: number;
7
+ speaker?: string;
8
+ }
9
+ interface PreparedPiperVoice {
10
+ voiceId: string;
11
+ modelPath: string;
12
+ sampleRate: number;
13
+ inference: {
14
+ lengthScale: number;
15
+ noiseScale: number;
16
+ };
17
+ metadata: Record<string, unknown>;
18
+ }
19
+ /**
20
+ * Normalize Piper voice configuration so downstream synthesis gets predictable defaults.
21
+ */
22
+ declare function preparePiperVoice(config: PiperVoiceConfig): PreparedPiperVoice;
23
+
24
+ interface StreamTokensOptions {
25
+ chunkSize?: number;
26
+ delayMs?: number;
27
+ onChunk?: (text: string) => Promise<void> | void;
28
+ }
29
+ interface StreamTokensResult {
30
+ chunksEmitted: number;
31
+ characters: number;
32
+ }
33
+ /**
34
+ * Convert incremental tokens to speech-sized chunks. Consumers can bridge this into an audio renderer.
35
+ */
36
+ declare function streamTokensToSpeech(tokens: AsyncIterable<string> | Iterable<string>, options?: StreamTokensOptions): Promise<StreamTokensResult>;
37
+
38
+ type OrtDevice = "cpu" | "webgpu";
39
+ type OrtLogLevel = "verbose" | "warning" | "error";
40
+ interface OrtEnvironmentConfig {
41
+ device?: OrtDevice;
42
+ logLevel?: OrtLogLevel;
43
+ providers?: string[];
44
+ }
45
+ interface OrtEnvironment {
46
+ device: OrtDevice;
47
+ logLevel: OrtLogLevel;
48
+ providers: string[];
49
+ initialized: boolean;
50
+ init: () => Promise<void>;
51
+ }
52
+ /**
53
+ * Minimal Onnx Runtime bootstrapper. This is intentionally dependency-light: callers can pass
54
+ * a custom provider list when integrating with onnxruntime-web or node-ort.
55
+ */
56
+ declare function createOrtEnvironment(config?: OrtEnvironmentConfig): Promise<OrtEnvironment>;
57
+
58
+ type SynthResult = string | ArrayBuffer | Uint8Array;
59
+ type Synthesizer = (text: string, voice: PreparedPiperVoice) => Promise<SynthResult>;
60
+ type Player = (audio: SynthResult) => Promise<void>;
61
+ declare function ensureOrtReady(config?: OrtEnvironmentConfig): Promise<OrtEnvironment>;
62
+ declare function ensureVoiceLoaded(config: PiperVoiceConfig): Promise<PreparedPiperVoice>;
63
+ declare function warmupPiper(voiceConfig: PiperVoiceConfig, synth: Synthesizer, text?: string): Promise<void>;
64
+ declare function resetVoiceCache(): void;
65
+ declare function getBackendLabel(device: string | undefined): string;
66
+ declare function isCorruptModelError(error: unknown): boolean;
67
+ declare function synthesizerWorker(textQueue: AsyncIterable<string>, voiceConfig: PiperVoiceConfig, synth: Synthesizer): AsyncGenerator<SynthResult, void, unknown>;
68
+ declare function playerWorker(audioQueue: AsyncIterable<SynthResult>, play: Player): Promise<void>;
69
+ declare function nextBoundaryIndex(text: string): number;
70
+ declare function emitSentence(queue: SimpleQueue<string>, sentence: string): void;
71
+ declare function handleChunk(state: {
72
+ buffer: string;
73
+ }, chunk: string, queue: SimpleQueue<string>): void;
74
+ declare function getAsyncIterator<T>(source: AsyncIterable<T> | Iterable<T>): AsyncIterable<T>;
75
+ declare class SimpleQueue<T> implements AsyncIterable<T> {
76
+ private buffer;
77
+ private resolvers;
78
+ put(item: T): void;
79
+ size(): number;
80
+ get(): Promise<T>;
81
+ [Symbol.asyncIterator](): AsyncIterator<T>;
82
+ }
83
+
84
+ interface StreamingTTSOptions {
85
+ voice: PiperVoiceConfig;
86
+ ort?: OrtEnvironmentConfig;
87
+ synth?: Synthesizer;
88
+ play?: Player;
89
+ chunkSize?: number;
90
+ delayMs?: number;
91
+ }
92
+ interface StreamingTTSController {
93
+ ensureReady(): Promise<void>;
94
+ addChunk(text: string): Promise<void>;
95
+ finishStreaming(): Promise<void>;
96
+ stop(): void;
97
+ synthAndPlayChunk(text: string): Promise<void>;
98
+ processQueue(): Promise<void>;
99
+ createTokenIterable(text: string): Iterable<string>;
100
+ }
101
+ declare function useStreamingTTS(options: StreamingTTSOptions): StreamingTTSController;
102
+
103
+ /**
104
+ * Piper TTS Synthesizer using @realtimex/piper-tts-web
105
+ * This library handles text-to-phoneme conversion properly using espeak-ng
106
+ *
107
+ * Note: @realtimex/piper-tts-web handles ONNX Runtime configuration internally,
108
+ * so NO separate ort-setup.js is needed!
109
+ */
110
+ interface PiperSynthesizerConfig {
111
+ /** Voice ID (e.g., "en_US-hfc_female-medium") */
112
+ voiceId?: string;
113
+ /** Sample rate (default: 22050) */
114
+ sampleRate?: number;
115
+ }
116
+ interface SynthesisResult {
117
+ /** Audio data as WAV Blob */
118
+ audioBlob: Blob;
119
+ /** Audio data as Float32Array (for direct playback) */
120
+ audio: Float32Array;
121
+ /** Sample rate */
122
+ sampleRate: number;
123
+ /** Duration in seconds */
124
+ duration: number;
125
+ }
126
+ /**
127
+ * Piper TTS Synthesizer
128
+ * Uses @mintplex-labs/piper-tts-web for proper text-to-speech conversion
129
+ */
130
+ declare class TTSLogic {
131
+ private config;
132
+ private ready;
133
+ private voiceLoaded;
134
+ constructor(config?: PiperSynthesizerConfig);
135
+ /**
136
+ * Initialize the synthesizer by loading the voice model
137
+ */
138
+ initialize(): Promise<void>;
139
+ /**
140
+ * Check if the synthesizer is ready
141
+ */
142
+ isReady(): boolean;
143
+ /**
144
+ * Synthesize speech from text
145
+ * @param text - Text to convert to speech
146
+ * @returns Audio data as WAV Blob and Float32Array
147
+ */
148
+ synthesize(text: string): Promise<SynthesisResult>;
149
+ /**
150
+ * Synthesize and return WAV Blob only (faster, no decoding)
151
+ */
152
+ synthesizeToBlob(text: string): Promise<Blob>;
153
+ /**
154
+ * Stop current synthesis (not directly supported, but we can track state)
155
+ */
156
+ stop(): void;
157
+ /**
158
+ * Dispose of the synthesizer and free resources
159
+ */
160
+ dispose(): Promise<void>;
161
+ }
162
+ /**
163
+ * Create and initialize a Piper synthesizer
164
+ */
165
+ /**
166
+ * @deprecated Use PiperSynthesizer.synthesize() which handles text-to-phoneme internally
167
+ * This is kept for backwards compatibility but should not be used directly
168
+ */
169
+ declare function textToPhonemes(_text: string): number[];
170
+
171
+ /**
172
+ * Web Audio API Player
173
+ * Plays synthesized audio using the Web Audio API
174
+ */
175
+ interface AudioPlayerConfig {
176
+ sampleRate?: number;
177
+ volume?: number;
178
+ }
179
+ /**
180
+ * Audio Player for Web Audio API
181
+ */
182
+ declare class AudioPlayer {
183
+ private audioContext;
184
+ private config;
185
+ private currentSource;
186
+ constructor(config?: AudioPlayerConfig);
187
+ /**
188
+ * Initialize the audio context
189
+ */
190
+ private getAudioContext;
191
+ /**
192
+ * Play audio data
193
+ * @param audioData - Float32Array of audio samples
194
+ * @param sampleRate - Sample rate of the audio
195
+ */
196
+ play(audioData: Float32Array, sampleRate: number): Promise<void>;
197
+ /**
198
+ * Stop current playback
199
+ */
200
+ stop(): void;
201
+ /**
202
+ * Set volume (0.0 to 1.0)
203
+ */
204
+ setVolume(volume: number): void;
205
+ /**
206
+ * Close the audio context and free resources
207
+ */
208
+ close(): Promise<void>;
209
+ }
210
+ /**
211
+ * Create and return an audio player instance
212
+ */
213
+ declare function createAudioPlayer(config?: AudioPlayerConfig): AudioPlayer;
214
+
215
+ export { AudioPlayer, type AudioPlayerConfig, type OrtDevice, type OrtEnvironment, type OrtEnvironmentConfig, type OrtLogLevel, type PiperSynthesizerConfig, type PiperVoiceConfig, type Player, type PreparedPiperVoice, SimpleQueue, type StreamTokensOptions, type StreamTokensResult, type StreamingTTSController, type StreamingTTSOptions, type SynthResult, type SynthesisResult, type Synthesizer, TTSLogic, createAudioPlayer, createOrtEnvironment, emitSentence, ensureOrtReady, ensureVoiceLoaded, getAsyncIterator, getBackendLabel, handleChunk, isCorruptModelError, nextBoundaryIndex, playerWorker, preparePiperVoice, resetVoiceCache, streamTokensToSpeech, synthesizerWorker, textToPhonemes, useStreamingTTS, warmupPiper };
@@ -0,0 +1,215 @@
1
+ interface PiperVoiceConfig {
2
+ voiceId: string;
3
+ modelPath?: string;
4
+ sampleRate?: number;
5
+ lengthScale?: number;
6
+ noiseScale?: number;
7
+ speaker?: string;
8
+ }
9
+ interface PreparedPiperVoice {
10
+ voiceId: string;
11
+ modelPath: string;
12
+ sampleRate: number;
13
+ inference: {
14
+ lengthScale: number;
15
+ noiseScale: number;
16
+ };
17
+ metadata: Record<string, unknown>;
18
+ }
19
+ /**
20
+ * Normalize Piper voice configuration so downstream synthesis gets predictable defaults.
21
+ */
22
+ declare function preparePiperVoice(config: PiperVoiceConfig): PreparedPiperVoice;
23
+
24
+ interface StreamTokensOptions {
25
+ chunkSize?: number;
26
+ delayMs?: number;
27
+ onChunk?: (text: string) => Promise<void> | void;
28
+ }
29
+ interface StreamTokensResult {
30
+ chunksEmitted: number;
31
+ characters: number;
32
+ }
33
+ /**
34
+ * Convert incremental tokens to speech-sized chunks. Consumers can bridge this into an audio renderer.
35
+ */
36
+ declare function streamTokensToSpeech(tokens: AsyncIterable<string> | Iterable<string>, options?: StreamTokensOptions): Promise<StreamTokensResult>;
37
+
38
+ type OrtDevice = "cpu" | "webgpu";
39
+ type OrtLogLevel = "verbose" | "warning" | "error";
40
+ interface OrtEnvironmentConfig {
41
+ device?: OrtDevice;
42
+ logLevel?: OrtLogLevel;
43
+ providers?: string[];
44
+ }
45
+ interface OrtEnvironment {
46
+ device: OrtDevice;
47
+ logLevel: OrtLogLevel;
48
+ providers: string[];
49
+ initialized: boolean;
50
+ init: () => Promise<void>;
51
+ }
52
+ /**
53
+ * Minimal Onnx Runtime bootstrapper. This is intentionally dependency-light: callers can pass
54
+ * a custom provider list when integrating with onnxruntime-web or node-ort.
55
+ */
56
+ declare function createOrtEnvironment(config?: OrtEnvironmentConfig): Promise<OrtEnvironment>;
57
+
58
+ type SynthResult = string | ArrayBuffer | Uint8Array;
59
+ type Synthesizer = (text: string, voice: PreparedPiperVoice) => Promise<SynthResult>;
60
+ type Player = (audio: SynthResult) => Promise<void>;
61
+ declare function ensureOrtReady(config?: OrtEnvironmentConfig): Promise<OrtEnvironment>;
62
+ declare function ensureVoiceLoaded(config: PiperVoiceConfig): Promise<PreparedPiperVoice>;
63
+ declare function warmupPiper(voiceConfig: PiperVoiceConfig, synth: Synthesizer, text?: string): Promise<void>;
64
+ declare function resetVoiceCache(): void;
65
+ declare function getBackendLabel(device: string | undefined): string;
66
+ declare function isCorruptModelError(error: unknown): boolean;
67
+ declare function synthesizerWorker(textQueue: AsyncIterable<string>, voiceConfig: PiperVoiceConfig, synth: Synthesizer): AsyncGenerator<SynthResult, void, unknown>;
68
+ declare function playerWorker(audioQueue: AsyncIterable<SynthResult>, play: Player): Promise<void>;
69
+ declare function nextBoundaryIndex(text: string): number;
70
+ declare function emitSentence(queue: SimpleQueue<string>, sentence: string): void;
71
+ declare function handleChunk(state: {
72
+ buffer: string;
73
+ }, chunk: string, queue: SimpleQueue<string>): void;
74
+ declare function getAsyncIterator<T>(source: AsyncIterable<T> | Iterable<T>): AsyncIterable<T>;
75
+ declare class SimpleQueue<T> implements AsyncIterable<T> {
76
+ private buffer;
77
+ private resolvers;
78
+ put(item: T): void;
79
+ size(): number;
80
+ get(): Promise<T>;
81
+ [Symbol.asyncIterator](): AsyncIterator<T>;
82
+ }
83
+
84
+ interface StreamingTTSOptions {
85
+ voice: PiperVoiceConfig;
86
+ ort?: OrtEnvironmentConfig;
87
+ synth?: Synthesizer;
88
+ play?: Player;
89
+ chunkSize?: number;
90
+ delayMs?: number;
91
+ }
92
+ interface StreamingTTSController {
93
+ ensureReady(): Promise<void>;
94
+ addChunk(text: string): Promise<void>;
95
+ finishStreaming(): Promise<void>;
96
+ stop(): void;
97
+ synthAndPlayChunk(text: string): Promise<void>;
98
+ processQueue(): Promise<void>;
99
+ createTokenIterable(text: string): Iterable<string>;
100
+ }
101
+ declare function useStreamingTTS(options: StreamingTTSOptions): StreamingTTSController;
102
+
103
+ /**
104
+ * Piper TTS Synthesizer using @realtimex/piper-tts-web
105
+ * This library handles text-to-phoneme conversion properly using espeak-ng
106
+ *
107
+ * Note: @realtimex/piper-tts-web handles ONNX Runtime configuration internally,
108
+ * so NO separate ort-setup.js is needed!
109
+ */
110
+ interface PiperSynthesizerConfig {
111
+ /** Voice ID (e.g., "en_US-hfc_female-medium") */
112
+ voiceId?: string;
113
+ /** Sample rate (default: 22050) */
114
+ sampleRate?: number;
115
+ }
116
+ interface SynthesisResult {
117
+ /** Audio data as WAV Blob */
118
+ audioBlob: Blob;
119
+ /** Audio data as Float32Array (for direct playback) */
120
+ audio: Float32Array;
121
+ /** Sample rate */
122
+ sampleRate: number;
123
+ /** Duration in seconds */
124
+ duration: number;
125
+ }
126
+ /**
127
+ * Piper TTS Synthesizer
128
+ * Uses @mintplex-labs/piper-tts-web for proper text-to-speech conversion
129
+ */
130
+ declare class TTSLogic {
131
+ private config;
132
+ private ready;
133
+ private voiceLoaded;
134
+ constructor(config?: PiperSynthesizerConfig);
135
+ /**
136
+ * Initialize the synthesizer by loading the voice model
137
+ */
138
+ initialize(): Promise<void>;
139
+ /**
140
+ * Check if the synthesizer is ready
141
+ */
142
+ isReady(): boolean;
143
+ /**
144
+ * Synthesize speech from text
145
+ * @param text - Text to convert to speech
146
+ * @returns Audio data as WAV Blob and Float32Array
147
+ */
148
+ synthesize(text: string): Promise<SynthesisResult>;
149
+ /**
150
+ * Synthesize and return WAV Blob only (faster, no decoding)
151
+ */
152
+ synthesizeToBlob(text: string): Promise<Blob>;
153
+ /**
154
+ * Stop current synthesis (not directly supported, but we can track state)
155
+ */
156
+ stop(): void;
157
+ /**
158
+ * Dispose of the synthesizer and free resources
159
+ */
160
+ dispose(): Promise<void>;
161
+ }
162
+ /**
163
+ * Create and initialize a Piper synthesizer
164
+ */
165
+ /**
166
+ * @deprecated Use PiperSynthesizer.synthesize() which handles text-to-phoneme internally
167
+ * This is kept for backwards compatibility but should not be used directly
168
+ */
169
+ declare function textToPhonemes(_text: string): number[];
170
+
171
+ /**
172
+ * Web Audio API Player
173
+ * Plays synthesized audio using the Web Audio API
174
+ */
175
+ interface AudioPlayerConfig {
176
+ sampleRate?: number;
177
+ volume?: number;
178
+ }
179
+ /**
180
+ * Audio Player for Web Audio API
181
+ */
182
+ declare class AudioPlayer {
183
+ private audioContext;
184
+ private config;
185
+ private currentSource;
186
+ constructor(config?: AudioPlayerConfig);
187
+ /**
188
+ * Initialize the audio context
189
+ */
190
+ private getAudioContext;
191
+ /**
192
+ * Play audio data
193
+ * @param audioData - Float32Array of audio samples
194
+ * @param sampleRate - Sample rate of the audio
195
+ */
196
+ play(audioData: Float32Array, sampleRate: number): Promise<void>;
197
+ /**
198
+ * Stop current playback
199
+ */
200
+ stop(): void;
201
+ /**
202
+ * Set volume (0.0 to 1.0)
203
+ */
204
+ setVolume(volume: number): void;
205
+ /**
206
+ * Close the audio context and free resources
207
+ */
208
+ close(): Promise<void>;
209
+ }
210
+ /**
211
+ * Create and return an audio player instance
212
+ */
213
+ declare function createAudioPlayer(config?: AudioPlayerConfig): AudioPlayer;
214
+
215
+ export { AudioPlayer, type AudioPlayerConfig, type OrtDevice, type OrtEnvironment, type OrtEnvironmentConfig, type OrtLogLevel, type PiperSynthesizerConfig, type PiperVoiceConfig, type Player, type PreparedPiperVoice, SimpleQueue, type StreamTokensOptions, type StreamTokensResult, type StreamingTTSController, type StreamingTTSOptions, type SynthResult, type SynthesisResult, type Synthesizer, TTSLogic, createAudioPlayer, createOrtEnvironment, emitSentence, ensureOrtReady, ensureVoiceLoaded, getAsyncIterator, getBackendLabel, handleChunk, isCorruptModelError, nextBoundaryIndex, playerWorker, preparePiperVoice, resetVoiceCache, streamTokensToSpeech, synthesizerWorker, textToPhonemes, useStreamingTTS, warmupPiper };