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/stt/reset-stt-logic.ts","../../src/stt/vad-controller.ts","../../src/stt/stt-logic.ts"],"names":["ResetSTTLogic"],"mappings":"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","file":"index.mjs","sourcesContent":["export type ResetReason = \"silence\" | \"utterance-complete\" | \"manual\";\r\n\r\nexport interface ResetStats {\r\n utteranceStartedAt: number;\r\n lastActivityAt: number;\r\n partialTranscript: string;\r\n}\r\n\r\nexport interface ResetSTTOptions {\r\n /** Maximum silence (ms) allowed before forcing a reset. */\r\n maxSilenceMs?: number;\r\n /** Maximum utterance length (ms) before rotating to a fresh buffer. */\r\n maxUtteranceMs?: number;\r\n /** Optional reset hook for logging/analytics. */\r\n onReset?: (reason: ResetReason, stats: ResetStats) => void;\r\n /**\r\n * Supply a clock for deterministic tests; defaults to Date.now.\r\n * Using a function keeps the class platform-neutral.\r\n */\r\n now?: () => number;\r\n}\r\n\r\n/**\r\n * Tracks speech activity and decides when to reset an STT pipeline so tokens and streams do not grow unbounded.\r\n */\r\nexport class ResetSTTLogic {\r\n private readonly maxSilenceMs: number;\r\n private readonly maxUtteranceMs: number;\r\n private readonly onReset?: (reason: ResetReason, stats: ResetStats) => void;\r\n private readonly now: () => number;\r\n\r\n private utteranceStartedAt: number;\r\n private lastActivityAt: number;\r\n private partialTranscript = \"\";\r\n\r\n constructor(options: ResetSTTOptions = {}) {\r\n this.maxSilenceMs = options.maxSilenceMs ?? 2000;\r\n this.maxUtteranceMs = options.maxUtteranceMs ?? 15000;\r\n this.onReset = options.onReset;\r\n this.now = options.now ?? (() => Date.now());\r\n\r\n const start = this.now();\r\n this.utteranceStartedAt = start;\r\n this.lastActivityAt = start;\r\n }\r\n\r\n recordSpeechActivity(timestamp?: number): void {\r\n const now = timestamp ?? this.now();\r\n this.lastActivityAt = now;\r\n if (!this.utteranceStartedAt) {\r\n this.utteranceStartedAt = now;\r\n }\r\n }\r\n\r\n updatePartialTranscript(partial: string, timestamp?: number): void {\r\n this.partialTranscript = partial;\r\n this.recordSpeechActivity(timestamp);\r\n }\r\n\r\n shouldReset(timestamp?: number): ResetReason | null {\r\n const now = timestamp ?? this.now();\r\n const silenceElapsed = now - this.lastActivityAt;\r\n const utteranceElapsed = now - this.utteranceStartedAt;\r\n\r\n if (silenceElapsed >= this.maxSilenceMs) {\r\n return \"silence\";\r\n }\r\n\r\n if (utteranceElapsed >= this.maxUtteranceMs) {\r\n return \"utterance-complete\";\r\n }\r\n\r\n return null;\r\n }\r\n\r\n maybeReset(timestamp?: number): ResetReason | null {\r\n const reason = this.shouldReset(timestamp);\r\n if (reason) {\r\n this.reset(reason, timestamp);\r\n }\r\n return reason;\r\n }\r\n\r\n forceReset(reason: ResetReason = \"manual\", timestamp?: number): void {\r\n this.reset(reason, timestamp);\r\n }\r\n\r\n private reset(reason: ResetReason, timestamp?: number): void {\r\n const now = timestamp ?? this.now();\r\n const stats: ResetStats = {\r\n utteranceStartedAt: this.utteranceStartedAt,\r\n lastActivityAt: this.lastActivityAt,\r\n partialTranscript: this.partialTranscript,\r\n };\r\n\r\n this.utteranceStartedAt = now;\r\n this.lastActivityAt = now;\r\n this.partialTranscript = \"\";\r\n\r\n if (this.onReset) {\r\n this.onReset(reason, stats);\r\n }\r\n }\r\n}\r\n","import { MicVAD, getDefaultRealTimeVADOptions } from \"@ricky0123/vad-web\";\r\n\r\nexport type VADControllerOptions = {\r\n bufferSize?: number;\r\n minSpeechMs?: number;\r\n minSilenceMs?: number;\r\n energyThreshold?: number;\r\n dynamicThresholdFactor?: number;\r\n noiseFloorSmoothing?: number;\r\n noiseFloorDecay?: number;\r\n maxAmplitude?: number;\r\n};\r\n\r\nexport class VADController {\r\n private vad: MicVAD | null = null;\r\n private voiceStartListeners = new Set<() => void>();\r\n private voiceStopListeners = new Set<() => void>();\r\n private running = false;\r\n private options?: VADControllerOptions;\r\n\r\n constructor(options?: VADControllerOptions) {\r\n this.options = options;\r\n }\r\n\r\n public async start(): Promise<void> {\r\n if (this.running && this.vad) {\r\n if (!this.vad.listening) {\r\n await this.vad.start();\r\n }\r\n return;\r\n }\r\n\r\n if (\r\n typeof navigator === \"undefined\" ||\r\n !navigator.mediaDevices ||\r\n !navigator.mediaDevices.getUserMedia\r\n ) {\r\n throw new Error(\"Microphone access is not available.\");\r\n }\r\n\r\n try {\r\n const ortAny = (window as any).ort;\r\n if (ortAny && ortAny.env && ortAny.env.wasm) {\r\n ortAny.env.wasm.wasmPaths = \"/ort/\";\r\n }\r\n\r\n if (!this.vad) {\r\n const defaultOptions = getDefaultRealTimeVADOptions(\"v5\");\r\n \r\n // Configure custom options\r\n this.vad = await MicVAD.new({\r\n ...defaultOptions,\r\n startOnLoad: false,\r\n onSpeechStart: () => {\r\n this.emitVoiceStart();\r\n },\r\n onSpeechEnd: (audio: Float32Array) => {\r\n this.emitVoiceStop();\r\n },\r\n onVADMisfire: () => {\r\n },\r\n minSpeechMs: this.options?.minSpeechMs || 150,\r\n positiveSpeechThreshold: 0.5,\r\n negativeSpeechThreshold: 0.35,\r\n redemptionMs: this.options?.minSilenceMs || 450,\r\n preSpeechPadMs: 50,\r\n processorType: \"ScriptProcessor\",\r\n\r\n onnxWASMBasePath: \"/ort/\",\r\n baseAssetPath: \"/vad/\",\r\n workletOptions: {},\r\n });\r\n }\r\n\r\n if (!this.vad.listening) {\r\n await this.vad.start();\r\n }\r\n \r\n this.running = true;\r\n } catch (error: any) {\r\n this.running = false;\r\n throw new Error(\r\n error?.message || \"Failed to initialize voice activity detector\"\r\n );\r\n }\r\n }\r\n\r\n public stop(): void {\r\n if (!this.running || !this.vad) return;\r\n try {\r\n this.vad.pause();\r\n this.running = false;\r\n } catch (error) {\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n this.stop();\r\n if (this.vad) {\r\n try {\r\n this.vad.destroy();\r\n } catch (error) {\r\n }\r\n this.vad = null;\r\n }\r\n this.voiceStartListeners.clear();\r\n this.voiceStopListeners.clear();\r\n }\r\n\r\n public isActive(): boolean {\r\n return this.running && this.vad !== null && this.vad.listening;\r\n }\r\n\r\n public onVoiceStart(listener: () => void): () => void {\r\n this.voiceStartListeners.add(listener);\r\n return () => this.voiceStartListeners.delete(listener);\r\n }\r\n\r\n public onVoiceStop(listener: () => void): () => void {\r\n this.voiceStopListeners.add(listener);\r\n return () => this.voiceStopListeners.delete(listener);\r\n }\r\n\r\n private emitVoiceStart(): void {\r\n this.voiceStartListeners.forEach((listener) => {\r\n try {\r\n listener();\r\n } catch (error) {\r\n console.error(\"Error in voice start listener:\", error);\r\n }\r\n });\r\n }\r\n\r\n private emitVoiceStop(): void {\r\n this.voiceStopListeners.forEach((listener) => {\r\n try {\r\n listener();\r\n } catch (error) {\r\n console.error(\"Error in voice stop listener:\", error);\r\n }\r\n });\r\n }\r\n}\r\n","// Public callback/type aliases kept for backward compatibility with STTLogic API\r\nexport type WordUpdateCallback = (words: string[]) => void;\r\nexport type MicTimeUpdateCallback = (ms: number) => void;\r\nexport type RestartMetricsCallback = (count: number, lastDuration: number | null) => void;\r\nexport type VadCallbacks = { onSpeechStart?: () => void; onSpeechEnd?: () => void };\r\n\r\ntype LogCallback = (message: string, type?: \"info\" | \"error\" | \"warning\") => void;\r\ntype TranscriptCallback = (transcript: string) => void;\r\n\r\ninterface SpeechRecognitionEvent extends Event {\r\n results: SpeechRecognitionResultList;\r\n resultIndex: number;\r\n}\r\n\r\ninterface SpeechRecognitionErrorEvent extends Event {\r\n error: string;\r\n}\r\n\r\nexport interface ResetSTTOptions {\r\n sessionDurationMs?: number;\r\n interimSaveIntervalMs?: number;\r\n preserveTranscriptOnStart?: boolean;\r\n}\r\n\r\n// Alias to match previous public surface\r\nexport type STTLogicOptions = ResetSTTOptions;\r\n\r\nexport class ResetSTTLogic {\r\n private recognition: any;\r\n private isListening: boolean = false;\r\n private fullTranscript: string = \"\";\r\n private heardWords: string[] = [];\r\n private onLog: LogCallback;\r\n private onTranscript: TranscriptCallback;\r\n private onWordsUpdate: WordUpdateCallback | null = null;\r\n private onMicTimeUpdate: MicTimeUpdateCallback | null = null;\r\n private onRestartMetrics: RestartMetricsCallback | null = null;\r\n private options: Required<ResetSTTOptions>;\r\n\r\n private micOnTime: number = 0;\r\n private sessionDuration: number = 30000;\r\n private lastTickTime: number = 0;\r\n private micTimeInterval: number | null = null;\r\n private restartCount: number = 0;\r\n private isRestarting: boolean = false;\r\n private isRecognitionRunning: boolean = false;\r\n private lastInterimTranscript: string = \"\";\r\n private lastInterimSaveTime: number = 0;\r\n private interimSaveInterval: number = 1000;\r\n private lastInterimResultTime: number = 0;\r\n private lastSavedLength: number = 0;\r\n private transcriptBeforeRestart: string = \"\";\r\n private sessionStartTranscript: string = \"\";\r\n private resultHandler?: (e: Event) => void;\r\n private errorHandler?: (e: Event) => void;\r\n private endHandler?: (e?: Event) => void;\r\n private startHandler?: (e?: Event) => void;\r\n private sessionId: number = 0;\r\n private awaitingRestartFirstResultId: number | null = null;\r\n private lastWasFinal: boolean = false;\r\n private restartMetrics: Record<\r\n number,\r\n {\r\n requestedAt: number;\r\n stopAt?: number;\r\n startAttemptAt?: number;\r\n startedAt?: number;\r\n firstResultAt?: number;\r\n }\r\n > = {};\r\n private isAutoRestarting: boolean = false;\r\n private onUserSpeechStart?: () => void;\r\n private onUserSpeechEnd?: () => void;\r\n\r\n constructor(\r\n onLog: LogCallback,\r\n onTranscript: TranscriptCallback,\r\n options: ResetSTTOptions = {}\r\n ) {\r\n this.onLog = onLog;\r\n this.onTranscript = onTranscript;\r\n this.options = {\r\n sessionDurationMs: options.sessionDurationMs ?? 30000,\r\n interimSaveIntervalMs: options.interimSaveIntervalMs ?? 5000,\r\n preserveTranscriptOnStart: options.preserveTranscriptOnStart ?? false,\r\n };\r\n this.sessionDuration = this.options.sessionDurationMs;\r\n this.interimSaveInterval = this.options.interimSaveIntervalMs;\r\n\r\n const SpeechRecognitionAPI =\r\n (window as any).SpeechRecognition ||\r\n (window as any).webkitSpeechRecognition;\r\n\r\n if (!SpeechRecognitionAPI) {\r\n this.onLog(\"Speech Recognition API not supported\", \"error\");\r\n throw new Error(\"Speech Recognition API not available\");\r\n }\r\n\r\n this.recognition = new SpeechRecognitionAPI();\r\n this.setupRecognition();\r\n }\r\n\r\n public setWordsUpdateCallback(callback: WordUpdateCallback): void {\r\n this.onWordsUpdate = callback;\r\n }\r\n\r\n public setMicTimeUpdateCallback(callback: MicTimeUpdateCallback): void {\r\n this.onMicTimeUpdate = callback;\r\n }\r\n\r\n public setRestartMetricsCallback(\r\n callback: RestartMetricsCallback\r\n ): void {\r\n this.onRestartMetrics = callback;\r\n }\r\n\r\n public setVadCallbacks(\r\n onSpeechStart?: () => void,\r\n onSpeechEnd?: () => void\r\n ): void {\r\n this.onUserSpeechStart = onSpeechStart || undefined;\r\n this.onUserSpeechEnd = onSpeechEnd || undefined;\r\n }\r\n\r\n public getSessionDurationMs(): number {\r\n return this.sessionDuration;\r\n }\r\n\r\n public isInAutoRestart(): boolean {\r\n return this.isAutoRestarting;\r\n }\r\n\r\n public getFullTranscript(): string {\r\n if (this.transcriptBeforeRestart.length > 0) {\r\n if (this.fullTranscript.length > 0) {\r\n return (\r\n this.transcriptBeforeRestart +\r\n \" \" +\r\n this.fullTranscript\r\n ).trim();\r\n }\r\n return this.transcriptBeforeRestart;\r\n }\r\n return this.fullTranscript;\r\n }\r\n\r\n public clearTranscript(): void {\r\n this.fullTranscript = \"\";\r\n this.transcriptBeforeRestart = \"\";\r\n this.sessionStartTranscript = \"\";\r\n this.heardWords = [];\r\n }\r\n\r\n private setupRecognition(): void {\r\n this.recognition.lang = \"en-US\";\r\n this.recognition.interimResults = true;\r\n this.recognition.continuous = true;\r\n (this.recognition as any).maxAlternatives = 1;\r\n\r\n this.resultHandler = (event: Event) => {\r\n const speechEvent = event as SpeechRecognitionEvent;\r\n let completeTranscript = \"\";\r\n for (let i = 0; i < speechEvent.results.length; i++) {\r\n completeTranscript += speechEvent.results[i][0].transcript + \" \";\r\n }\r\n completeTranscript = completeTranscript.trim();\r\n\r\n const isFinal =\r\n speechEvent.results[speechEvent.results.length - 1].isFinal;\r\n\r\n completeTranscript = this.collapseRepeats(completeTranscript);\r\n this.lastInterimTranscript = completeTranscript;\r\n this.lastInterimResultTime = Date.now();\r\n\r\n if (this.awaitingRestartFirstResultId != null) {\r\n const rid = this.awaitingRestartFirstResultId;\r\n if (\r\n this.restartMetrics[rid] &&\r\n !this.restartMetrics[rid].firstResultAt\r\n ) {\r\n this.restartMetrics[rid].firstResultAt = Date.now();\r\n const delta =\r\n this.restartMetrics[rid].firstResultAt -\r\n this.restartMetrics[rid].requestedAt;\r\n this.onLog(\r\n `🔔 First result after restart #${rid} in ${delta}ms`,\r\n \"info\"\r\n );\r\n this.awaitingRestartFirstResultId = null;\r\n }\r\n }\r\n this.onLog(\r\n `[${isFinal ? \"FINAL\" : \"INTERIM\"}] \"${completeTranscript}\"`,\r\n isFinal ? \"info\" : \"warning\"\r\n );\r\n\r\n if (!isFinal && this.lastWasFinal) {\r\n try { this.onUserSpeechStart?.(); } catch {}\r\n }\r\n\r\n this.lastWasFinal = isFinal;\r\n\r\n if (isFinal) {\r\n this.fullTranscript = (this.sessionStartTranscript + \" \" + completeTranscript).trim();\r\n this.fullTranscript = this.collapseRepeats(this.fullTranscript);\r\n \r\n this.heardWords = this.fullTranscript\r\n .split(/\\s+/)\r\n .filter((word) => word.length > 0);\r\n \r\n this.onTranscript(this.getFullTranscript());\r\n this.lastSavedLength = this.fullTranscript.length;\r\n if (this.onWordsUpdate) this.onWordsUpdate(this.heardWords);\r\n \r\n this.lastInterimTranscript = \"\";\r\n \r\n if (this.awaitingRestartFirstResultId != null) {\r\n const rid = this.awaitingRestartFirstResultId;\r\n if (\r\n this.restartMetrics[rid] &&\r\n !this.restartMetrics[rid].firstResultAt\r\n ) {\r\n this.restartMetrics[rid].firstResultAt = Date.now();\r\n const startedAt =\r\n this.restartMetrics[rid].startedAt ||\r\n this.restartMetrics[rid].startAttemptAt ||\r\n Date.now();\r\n const firstResultDelta =\r\n this.restartMetrics[rid].firstResultAt -\r\n this.restartMetrics[rid].requestedAt;\r\n this.onLog(\r\n `🔔 First result after restart #${rid} in ${firstResultDelta}ms`,\r\n \"info\"\r\n );\r\n this.awaitingRestartFirstResultId = null;\r\n }\r\n }\r\n }\r\n };\r\n this.recognition.addEventListener(\"result\", this.resultHandler);\r\n\r\n this.errorHandler = (event: Event) => {\r\n const errorEvent = event as SpeechRecognitionErrorEvent;\r\n if (errorEvent.error === \"aborted\" && this.isRestarting) {\r\n this.onLog(\"Aborted during restart (ignored)\", \"info\");\r\n this.isRecognitionRunning = false;\r\n return;\r\n }\r\n this.onLog(`Error: ${errorEvent.error}`, \"error\");\r\n if (\r\n errorEvent.error === \"no-speech\" ||\r\n errorEvent.error === \"audio-capture\" ||\r\n errorEvent.error === \"network\"\r\n ) {\r\n setTimeout(() => {\r\n if (\r\n this.isListening &&\r\n !this.isRestarting &&\r\n !this.isRecognitionRunning\r\n ) {\r\n try {\r\n this.recognition.start();\r\n this.isRecognitionRunning = true;\r\n this.sessionId++;\r\n } catch (e) {\r\n this.onLog(`Failed restart after error: ${e}`, \"error\");\r\n }\r\n }\r\n }, 500);\r\n } else {\r\n this.onLog(\r\n `Unhandled SpeechRecognition error: ${errorEvent.error}`,\r\n \"warning\"\r\n );\r\n }\r\n };\r\n this.recognition.addEventListener(\"error\", this.errorHandler);\r\n\r\n this.endHandler = () => {\r\n this.isRecognitionRunning = false;\r\n if (this.isListening && !this.isRestarting) {\r\n setTimeout(() => {\r\n if (this.isListening && !this.isRestarting) {\r\n try {\r\n this.recognition.start();\r\n this.isRecognitionRunning = true;\r\n this.sessionId++;\r\n this.onLog(\r\n `🔁 Auto-resumed recognition after end (session ${this.sessionId})`,\r\n \"info\"\r\n );\r\n } catch (e) {\r\n this.onLog(`Failed to auto-start after end: ${e}`, \"error\");\r\n }\r\n }\r\n }, 100);\r\n }\r\n };\r\n this.recognition.addEventListener(\"end\", this.endHandler);\r\n\r\n this.startHandler = () => {\r\n this.isRecognitionRunning = true;\r\n const rid = this.awaitingRestartFirstResultId;\r\n if (rid != null && this.restartMetrics[rid]) {\r\n if (!this.restartMetrics[rid].startedAt) {\r\n this.restartMetrics[rid].startedAt = Date.now();\r\n this.onLog(\r\n `▶️ Restart #${rid} recognition started in ${\r\n this.restartMetrics[rid].startedAt -\r\n this.restartMetrics[rid].requestedAt\r\n }ms`,\r\n \"info\"\r\n );\r\n }\r\n }\r\n };\r\n this.recognition.addEventListener(\"start\", this.startHandler);\r\n }\r\n\r\n private waitForEventOnce(\r\n eventName: string,\r\n timeoutMs: number\r\n ): Promise<Event | null> {\r\n return new Promise((resolve) => {\r\n let timer: number | null = null;\r\n const handler = (ev: Event) => {\r\n if (timer !== null) clearTimeout(timer);\r\n this.recognition.removeEventListener(eventName, handler);\r\n resolve(ev);\r\n };\r\n this.recognition.addEventListener(eventName, handler);\r\n timer = window.setTimeout(() => {\r\n this.recognition.removeEventListener(eventName, handler);\r\n resolve(null);\r\n }, timeoutMs);\r\n });\r\n }\r\n\r\n private startMicTimer(): void {\r\n this.lastTickTime = Date.now();\r\n this.lastInterimSaveTime = Date.now();\r\n\r\n this.micTimeInterval = window.setInterval(() => {\r\n if (this.isListening) {\r\n const now = Date.now();\r\n const elapsed = now - this.lastTickTime;\r\n this.micOnTime += elapsed;\r\n this.lastTickTime = now;\r\n\r\n if (now - this.lastInterimSaveTime >= this.interimSaveInterval) {\r\n this.saveInterimToFinal();\r\n this.lastInterimSaveTime = now;\r\n }\r\n\r\n if (this.micOnTime >= this.sessionDuration) {\r\n if (!this.isRestarting) this.performRestart();\r\n }\r\n if (this.onMicTimeUpdate) this.onMicTimeUpdate(this.micOnTime);\r\n }\r\n }, 100);\r\n }\r\n\r\n private stopMicTimer(): void {\r\n if (this.micTimeInterval) {\r\n clearInterval(this.micTimeInterval);\r\n this.micTimeInterval = null;\r\n }\r\n }\r\n\r\n private saveInterimToFinal(): void {\r\n if (!this.lastInterimTranscript) return;\r\n const now = Date.now();\r\n if (now - this.lastInterimResultTime > this.interimSaveInterval && this.lastInterimTranscript.length > this.lastSavedLength) {\r\n this.fullTranscript = (this.fullTranscript + \" \" + this.lastInterimTranscript).trim();\r\n this.fullTranscript = this.collapseRepeats(this.fullTranscript);\r\n this.lastSavedLength = this.fullTranscript.length;\r\n if (this.onWordsUpdate) {\r\n const words = this.fullTranscript.split(/\\s+/).filter(w => w.length > 0);\r\n this.onWordsUpdate(words);\r\n }\r\n this.onTranscript(this.getFullTranscript());\r\n }\r\n }\r\n\r\n private getSuffixToAppend(base: string, current: string): string {\r\n if (!base || base.length === 0) return current;\r\n if (!current || current.length === 0) return \"\";\r\n base = base.trim();\r\n current = current.trim();\r\n if (current.startsWith(base)) {\r\n return current.slice(base.length).trim();\r\n }\r\n const maxOverlap = Math.min(base.length, current.length);\r\n for (let overlap = maxOverlap; overlap > 0; overlap--) {\r\n if (base.endsWith(current.slice(0, overlap))) {\r\n return current.slice(overlap).trim();\r\n }\r\n }\r\n return current;\r\n }\r\n\r\n private collapseRepeats(text: string): string {\r\n if (!text || text.trim().length === 0) return text.trim();\r\n let normalized = text.replace(/\\s+/g, \" \").trim();\r\n const n = normalized.length;\r\n const lps: number[] = new Array(n).fill(0);\r\n for (let i = 1; i < n; i++) {\r\n let j = lps[i - 1];\r\n while (j > 0 && normalized[i] !== normalized[j]) j = lps[j - 1];\r\n if (normalized[i] === normalized[j]) j++;\r\n lps[i] = j;\r\n }\r\n const period = n - lps[n - 1];\r\n if (period < n && n % period === 0) {\r\n return normalized.slice(0, period).trim();\r\n }\r\n const words = normalized.split(\" \");\r\n for (\r\n let block = Math.min(20, Math.floor(words.length / 2));\r\n block >= 1;\r\n block--\r\n ) {\r\n let i = 0;\r\n while (i + 2 * block <= words.length) {\r\n let blockA = words.slice(i, i + block).join(\" \");\r\n let blockB = words.slice(i + block, i + 2 * block).join(\" \");\r\n if (blockA === blockB) {\r\n words.splice(i + block, block);\r\n } else {\r\n i++;\r\n }\r\n }\r\n }\r\n const collapsedWords: string[] = [];\r\n for (const w of words) {\r\n if (\r\n collapsedWords.length === 0 ||\r\n collapsedWords[collapsedWords.length - 1] !== w\r\n )\r\n collapsedWords.push(w);\r\n }\r\n return collapsedWords.join(\" \").trim();\r\n }\r\n\r\n private performRestart(): void {\r\n if (!this.isListening || this.isRestarting) return;\r\n\r\n const restartStartTime = Date.now();\r\n this.restartCount++;\r\n this.isRestarting = true;\r\n this.isAutoRestarting = true;\r\n const rid = ++this.sessionId;\r\n this.awaitingRestartFirstResultId = rid;\r\n this.restartMetrics[rid] = { requestedAt: restartStartTime };\r\n\r\n this.onLog(\r\n `🔄 [AUTO-RESTART] Session ${rid} - buffering transcript, waiting for silence...`,\r\n \"warning\"\r\n );\r\n\r\n if (this.lastInterimTranscript.trim().length > 0) {\r\n this.saveInterimToFinal();\r\n }\r\n\r\n this.transcriptBeforeRestart = this.getFullTranscript();\r\n this.fullTranscript = \"\";\r\n this.sessionStartTranscript = \"\";\r\n this.lastInterimTranscript = \"\";\r\n this.heardWords = [];\r\n\r\n this.stopMicTimer();\r\n\r\n const stopTimeout = 600;\r\n const startTimeout = 1000;\r\n const firstResultTimeout = 2000;\r\n\r\n const stopNow = async () => {\r\n try {\r\n if (this.isRecognitionRunning) {\r\n this.recognition.stop();\r\n } else {\r\n this.onLog(\"Recognition not running at stop attempt\", \"warning\");\r\n }\r\n } catch (err) {\r\n this.onLog(`Stop threw: ${err}`, \"warning\");\r\n }\r\n const endEvent = await this.waitForEventOnce(\"end\", stopTimeout);\r\n if (!endEvent) {\r\n try {\r\n (this.recognition as any).abort();\r\n } catch (err) {\r\n this.onLog(`Abort also failed: ${err}`, \"error\");\r\n }\r\n await this.waitForEventOnce(\"end\", 300);\r\n }\r\n this.restartMetrics[rid].stopAt = Date.now();\r\n };\r\n\r\n (async () => {\r\n await stopNow();\r\n this.restartMetrics[rid].startAttemptAt = Date.now();\r\n try {\r\n if (!this.isRecognitionRunning) {\r\n this.sessionId = rid;\r\n this.recognition.start();\r\n } else {\r\n this.onLog(\r\n \"Recognition already running at restart time; skipping start.\",\r\n \"warning\"\r\n );\r\n }\r\n } catch (e) {\r\n this.onLog(`Failed to start recognition after restart: ${e}`, \"error\");\r\n }\r\n\r\n const startEv = await this.waitForEventOnce(\"start\", startTimeout);\r\n if (startEv) {\r\n this.restartMetrics[rid].startedAt = Date.now();\r\n } else {\r\n this.onLog(\r\n `Restart #${rid} did not produce start event within ${startTimeout}ms`,\r\n \"warning\"\r\n );\r\n }\r\n\r\n const resEv = await this.waitForEventOnce(\"result\", firstResultTimeout);\r\n if (resEv) {\r\n if (this.restartMetrics[rid])\r\n this.restartMetrics[rid].firstResultAt = Date.now();\r\n const firstResultDelta =\r\n (this.restartMetrics[rid].firstResultAt || Date.now()) -\r\n (this.restartMetrics[rid].requestedAt || Date.now());\r\n this.onLog(\r\n `🔔 First result after restart #${rid} in ${firstResultDelta}ms`,\r\n \"info\"\r\n );\r\n } else {\r\n this.onLog(\r\n `Restart #${rid} produced no result within ${firstResultTimeout}ms`,\r\n \"warning\"\r\n );\r\n }\r\n\r\n const startedAt =\r\n this.restartMetrics[rid].startedAt ||\r\n this.restartMetrics[rid].startAttemptAt ||\r\n Date.now();\r\n const restartDuration = startedAt - this.restartMetrics[rid].requestedAt;\r\n if (this.onRestartMetrics)\r\n this.onRestartMetrics(this.restartCount, restartDuration);\r\n this.onLog(\r\n `✅ Session ${rid} restarted in ${restartDuration}ms - resuming from silence gate`,\r\n \"info\"\r\n );\r\n this.startMicTimer();\r\n this.isRestarting = false;\r\n this.isAutoRestarting = false;\r\n })();\r\n }\r\n\r\n public start(): void {\r\n if (this.isListening) return;\r\n\r\n try {\r\n this.isListening = true;\r\n if (!this.options.preserveTranscriptOnStart) {\r\n this.fullTranscript = \"\";\r\n this.heardWords = [];\r\n this.transcriptBeforeRestart = \"\";\r\n this.sessionStartTranscript = \"\";\r\n } else {\r\n this.sessionStartTranscript = this.fullTranscript;\r\n }\r\n \r\n this.micOnTime = 0;\r\n this.restartCount = 0;\r\n this.lastSavedLength = 0;\r\n this.lastInterimTranscript = \"\";\r\n this.lastWasFinal = false;\r\n\r\n if (!this.isRecognitionRunning) {\r\n this.sessionId++;\r\n this.recognition.start();\r\n this.isRecognitionRunning = true;\r\n }\r\n this.startMicTimer();\r\n this.onLog(\r\n \"Listening started (auto-restart every 30s of mic time)\",\r\n \"info\"\r\n );\r\n } catch (error) {\r\n this.isListening = false;\r\n this.onLog(`Failed to start: ${error}`, \"error\");\r\n }\r\n }\r\n\r\n public stop(): void {\r\n if (!this.isListening) return;\r\n\r\n try {\r\n this.isListening = false;\r\n this.isAutoRestarting = false;\r\n this.stopMicTimer();\r\n this.recognition.stop();\r\n this.isRecognitionRunning = false;\r\n this.onLog(\r\n `Stopped listening (total mic time: ${(this.micOnTime / 1000).toFixed(\r\n 1\r\n )}s, restarts: ${this.restartCount})`,\r\n \"info\"\r\n );\r\n } catch (error) {\r\n this.onLog(`Failed to stop: ${error}`, \"error\");\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n this.isListening = false;\r\n this.stopMicTimer();\r\n try {\r\n (this.recognition as any).abort?.();\r\n } catch (e) {}\r\n try {\r\n if (this.resultHandler)\r\n this.recognition.removeEventListener(\"result\", this.resultHandler);\r\n if (this.errorHandler)\r\n this.recognition.removeEventListener(\"error\", this.errorHandler);\r\n if (this.endHandler)\r\n this.recognition.removeEventListener(\r\n \"end\",\r\n this.endHandler as EventListener\r\n );\r\n if (this.startHandler)\r\n this.recognition.removeEventListener(\r\n \"start\",\r\n this.startHandler as EventListener\r\n );\r\n } catch (e) {\r\n }\r\n }\r\n}\r\n\r\n// Backward-compatible alias so consumers can import STTLogic as before\r\nexport class STTLogic extends ResetSTTLogic {}\r\n"]}
@@ -0,0 +1,500 @@
1
+ 'use strict';
2
+
3
+ var piperTts = require('@realtimex/piper-tts-web');
4
+
5
+ function _interopNamespace(e) {
6
+ if (e && e.__esModule) return e;
7
+ var n = Object.create(null);
8
+ if (e) {
9
+ Object.keys(e).forEach(function (k) {
10
+ if (k !== 'default') {
11
+ var d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: function () { return e[k]; }
15
+ });
16
+ }
17
+ });
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+
23
+ var piperTts__namespace = /*#__PURE__*/_interopNamespace(piperTts);
24
+
25
+ // src/tts/prepare-piper-voice.ts
26
+ function preparePiperVoice(config) {
27
+ const modelPath = config.modelPath ?? `voices/${config.voiceId}.onnx`;
28
+ return {
29
+ voiceId: config.voiceId,
30
+ modelPath,
31
+ sampleRate: config.sampleRate ?? 22050,
32
+ inference: {
33
+ lengthScale: config.lengthScale ?? 1,
34
+ noiseScale: config.noiseScale ?? 0.667
35
+ },
36
+ metadata: {
37
+ speaker: config.speaker ?? "default"
38
+ }
39
+ };
40
+ }
41
+
42
+ // src/tts/stream-tokens-to-speech.ts
43
+ function isAsyncIterable(value) {
44
+ return typeof value[Symbol.asyncIterator] === "function";
45
+ }
46
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
47
+ async function streamTokensToSpeech(tokens, options = {}) {
48
+ const chunkSize = options.chunkSize ?? 40;
49
+ const delayMs = options.delayMs ?? 0;
50
+ let buffer = "";
51
+ let chunksEmitted = 0;
52
+ let characters = 0;
53
+ const emit = async () => {
54
+ if (!buffer) return;
55
+ characters += buffer.length;
56
+ chunksEmitted += 1;
57
+ if (options.onChunk) {
58
+ await options.onChunk(buffer);
59
+ }
60
+ buffer = "";
61
+ if (delayMs > 0) {
62
+ await sleep(delayMs);
63
+ }
64
+ };
65
+ if (isAsyncIterable(tokens)) {
66
+ for await (const token of tokens) {
67
+ buffer += token;
68
+ if (buffer.length >= chunkSize) {
69
+ await emit();
70
+ }
71
+ }
72
+ } else {
73
+ for (const token of tokens) {
74
+ buffer += token;
75
+ if (buffer.length >= chunkSize) {
76
+ await emit();
77
+ }
78
+ }
79
+ }
80
+ if (buffer) {
81
+ await emit();
82
+ }
83
+ return { chunksEmitted, characters };
84
+ }
85
+
86
+ // src/tts/ort-setup.ts
87
+ async function createOrtEnvironment(config = {}) {
88
+ const providers = config.providers ?? (config.device === "webgpu" ? ["webgpu", "wasm"] : ["wasm"]);
89
+ const environment = {
90
+ device: config.device ?? "cpu",
91
+ logLevel: config.logLevel ?? "warning",
92
+ providers,
93
+ initialized: false,
94
+ async init() {
95
+ this.initialized = true;
96
+ }
97
+ };
98
+ await environment.init();
99
+ return environment;
100
+ }
101
+
102
+ // src/tts/piper.ts
103
+ var voiceCache = /* @__PURE__ */ new Map();
104
+ var ortEnv = null;
105
+ async function ensureOrtReady(config = {}) {
106
+ if (ortEnv) return ortEnv;
107
+ ortEnv = await createOrtEnvironment(config);
108
+ return ortEnv;
109
+ }
110
+ async function ensureVoiceLoaded(config) {
111
+ const cached = voiceCache.get(config.voiceId);
112
+ if (cached) return cached;
113
+ const voice = preparePiperVoice(config);
114
+ voiceCache.set(config.voiceId, voice);
115
+ return voice;
116
+ }
117
+ async function warmupPiper(voiceConfig, synth, text = "warmup") {
118
+ const voice = await ensureVoiceLoaded(voiceConfig);
119
+ await synth(text, voice);
120
+ }
121
+ function resetVoiceCache() {
122
+ voiceCache.clear();
123
+ }
124
+ function getBackendLabel(device) {
125
+ if (!device) return "auto";
126
+ return device === "webgpu" ? "WebGPU" : "CPU";
127
+ }
128
+ function isCorruptModelError(error) {
129
+ if (!error) return false;
130
+ const msg = typeof error === "string" ? error : error.message;
131
+ if (!msg) return false;
132
+ return /corrupt|checksum|integrity/i.test(msg);
133
+ }
134
+ async function* synthesizerWorker(textQueue, voiceConfig, synth) {
135
+ const voice = await ensureVoiceLoaded(voiceConfig);
136
+ for await (const text of textQueue) {
137
+ yield synth(text, voice);
138
+ }
139
+ }
140
+ async function playerWorker(audioQueue, play) {
141
+ for await (const audio of audioQueue) {
142
+ await play(audio);
143
+ }
144
+ }
145
+ function nextBoundaryIndex(text) {
146
+ const idx = text.search(/[.!?,]/);
147
+ return idx >= 0 ? idx : -1;
148
+ }
149
+ function emitSentence(queue, sentence) {
150
+ const trimmed = sentence.trim();
151
+ if (trimmed) {
152
+ queue.put(trimmed);
153
+ }
154
+ }
155
+ function handleChunk(state, chunk, queue) {
156
+ state.buffer += chunk;
157
+ let boundary = nextBoundaryIndex(state.buffer);
158
+ while (boundary >= 0) {
159
+ const sentence = state.buffer.slice(0, boundary + 1);
160
+ state.buffer = state.buffer.slice(boundary + 1);
161
+ emitSentence(queue, sentence);
162
+ boundary = nextBoundaryIndex(state.buffer);
163
+ }
164
+ }
165
+ function getAsyncIterator(source) {
166
+ if (source[Symbol.asyncIterator]) {
167
+ return source;
168
+ }
169
+ return {
170
+ async *[Symbol.asyncIterator]() {
171
+ for (const item of source) {
172
+ yield item;
173
+ }
174
+ }
175
+ };
176
+ }
177
+ var SimpleQueue = class {
178
+ constructor() {
179
+ this.buffer = [];
180
+ this.resolvers = [];
181
+ }
182
+ put(item) {
183
+ if (this.resolvers.length > 0) {
184
+ const resolve = this.resolvers.shift();
185
+ resolve?.({ value: item, done: false });
186
+ } else {
187
+ this.buffer.push(item);
188
+ }
189
+ }
190
+ size() {
191
+ return this.buffer.length;
192
+ }
193
+ async get() {
194
+ if (this.buffer.length > 0) {
195
+ return this.buffer.shift();
196
+ }
197
+ return new Promise((resolve) => {
198
+ this.resolvers.push(({ value }) => resolve(value));
199
+ });
200
+ }
201
+ async *[Symbol.asyncIterator]() {
202
+ while (true) {
203
+ const value = await this.get();
204
+ yield value;
205
+ }
206
+ }
207
+ };
208
+
209
+ // src/tts/use-streaming-tts.ts
210
+ var defaultSynth = async (text) => text;
211
+ var defaultPlayer = async () => void 0;
212
+ function useStreamingTTS(options) {
213
+ const textQueue = new SimpleQueue();
214
+ const bufferState = { buffer: "" };
215
+ let ready = false;
216
+ let stopped = false;
217
+ let voice = null;
218
+ const synth = options.synth ?? defaultSynth;
219
+ const play = options.play ?? defaultPlayer;
220
+ const chunkSize = options.chunkSize ?? 48;
221
+ const delayMs = options.delayMs ?? 0;
222
+ async function ensureReady() {
223
+ if (ready) return;
224
+ await ensureOrtReady(options.ort ?? {});
225
+ voice = await ensureVoiceLoaded(options.voice);
226
+ ready = true;
227
+ }
228
+ async function addChunk(text) {
229
+ handleChunk(bufferState, text, textQueue);
230
+ if (bufferState.buffer.length >= chunkSize) {
231
+ emitSentence(textQueue, bufferState.buffer);
232
+ bufferState.buffer = "";
233
+ }
234
+ }
235
+ async function finishStreaming() {
236
+ if (bufferState.buffer) {
237
+ emitSentence(textQueue, bufferState.buffer);
238
+ bufferState.buffer = "";
239
+ }
240
+ }
241
+ function stop() {
242
+ stopped = true;
243
+ }
244
+ async function synthAndPlayChunk(text) {
245
+ await ensureReady();
246
+ const audio = await synth(text, voice);
247
+ await play(audio);
248
+ }
249
+ async function processQueue() {
250
+ await ensureReady();
251
+ const tokenIterator = getAsyncIterator(textQueue);
252
+ const audioIterator = synthesizerWorker(tokenIterator, options.voice, synth);
253
+ await playerWorker(audioIterator, play);
254
+ }
255
+ function createTokenIterable(text) {
256
+ return text.split(/\s+/g).filter(Boolean);
257
+ }
258
+ async function streamTokens(tokens) {
259
+ await ensureReady();
260
+ await streamTokensToSpeech(tokens, {
261
+ chunkSize,
262
+ delayMs,
263
+ onChunk: async (chunk) => {
264
+ if (stopped) return;
265
+ await synthAndPlayChunk(chunk);
266
+ }
267
+ });
268
+ }
269
+ processQueue().catch(() => void 0);
270
+ streamTokens(textQueue).catch(() => void 0);
271
+ return {
272
+ ensureReady,
273
+ addChunk,
274
+ finishStreaming,
275
+ stop,
276
+ synthAndPlayChunk,
277
+ processQueue,
278
+ createTokenIterable
279
+ };
280
+ }
281
+ var DEFAULT_VOICE_ID = "en_US-hfc_female-medium";
282
+ var TTSLogic = class {
283
+ constructor(config = {}) {
284
+ this.ready = false;
285
+ this.voiceLoaded = false;
286
+ this.config = {
287
+ voiceId: DEFAULT_VOICE_ID,
288
+ sampleRate: 22050,
289
+ ...config
290
+ };
291
+ }
292
+ /**
293
+ * Initialize the synthesizer by loading the voice model
294
+ */
295
+ async initialize() {
296
+ if (this.ready) return;
297
+ try {
298
+ const voiceId = this.config.voiceId;
299
+ console.log("\u{1F4CD} Loading Piper voice:", voiceId);
300
+ const storedVoices = await piperTts__namespace.stored();
301
+ const alreadyCached = Array.isArray(storedVoices) ? storedVoices.includes(voiceId) : false;
302
+ if (!alreadyCached) {
303
+ console.log("\u2B07\uFE0F Downloading voice model...");
304
+ await piperTts__namespace.download(voiceId, (progress) => {
305
+ if (progress?.total) {
306
+ const pct = Math.round(progress.loaded * 100 / progress.total);
307
+ console.log(`\u2B07\uFE0F Downloading: ${pct}%`);
308
+ }
309
+ });
310
+ } else {
311
+ console.log("\u2713 Voice found in cache");
312
+ }
313
+ this.voiceLoaded = true;
314
+ this.ready = true;
315
+ console.log("\u2713 Piper synthesizer initialized");
316
+ } catch (error) {
317
+ throw new Error(`Failed to initialize Piper synthesizer: ${error}`);
318
+ }
319
+ }
320
+ /**
321
+ * Check if the synthesizer is ready
322
+ */
323
+ isReady() {
324
+ return this.ready;
325
+ }
326
+ /**
327
+ * Synthesize speech from text
328
+ * @param text - Text to convert to speech
329
+ * @returns Audio data as WAV Blob and Float32Array
330
+ */
331
+ async synthesize(text) {
332
+ if (!this.ready) {
333
+ throw new Error("Synthesizer not initialized. Call initialize() first.");
334
+ }
335
+ const trimmed = text?.trim();
336
+ if (!trimmed) {
337
+ throw new Error("No text provided for synthesis");
338
+ }
339
+ try {
340
+ const wavBlob = await piperTts__namespace.predict({
341
+ text: trimmed,
342
+ voiceId: this.config.voiceId
343
+ });
344
+ const arrayBuffer = await wavBlob.arrayBuffer();
345
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
346
+ const decodedBuffer = await audioContext.decodeAudioData(arrayBuffer);
347
+ const audioData = decodedBuffer.getChannelData(0);
348
+ audioContext.close();
349
+ return {
350
+ audioBlob: wavBlob,
351
+ audio: audioData,
352
+ sampleRate: decodedBuffer.sampleRate,
353
+ duration: decodedBuffer.duration
354
+ };
355
+ } catch (error) {
356
+ throw new Error(`Synthesis failed: ${error}`);
357
+ }
358
+ }
359
+ /**
360
+ * Synthesize and return WAV Blob only (faster, no decoding)
361
+ */
362
+ async synthesizeToBlob(text) {
363
+ if (!this.ready) {
364
+ throw new Error("Synthesizer not initialized. Call initialize() first.");
365
+ }
366
+ const trimmed = text?.trim();
367
+ if (!trimmed) {
368
+ throw new Error("No text provided for synthesis");
369
+ }
370
+ return piperTts__namespace.predict({
371
+ text: trimmed,
372
+ voiceId: this.config.voiceId
373
+ });
374
+ }
375
+ /**
376
+ * Stop current synthesis (not directly supported, but we can track state)
377
+ */
378
+ stop() {
379
+ console.log("Stop requested");
380
+ }
381
+ /**
382
+ * Dispose of the synthesizer and free resources
383
+ */
384
+ async dispose() {
385
+ this.ready = false;
386
+ this.voiceLoaded = false;
387
+ }
388
+ };
389
+ function textToPhonemes(_text) {
390
+ console.warn(
391
+ "textToPhonemes is deprecated. Use PiperSynthesizer.synthesize(text) instead."
392
+ );
393
+ return [];
394
+ }
395
+
396
+ // src/tts/audio-player.ts
397
+ var AudioPlayer = class {
398
+ constructor(config = {}) {
399
+ this.audioContext = null;
400
+ this.currentSource = null;
401
+ this.config = {
402
+ sampleRate: 22050,
403
+ volume: 1,
404
+ ...config
405
+ };
406
+ }
407
+ /**
408
+ * Initialize the audio context
409
+ */
410
+ getAudioContext() {
411
+ if (!this.audioContext) {
412
+ this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
413
+ sampleRate: this.config.sampleRate
414
+ });
415
+ }
416
+ return this.audioContext;
417
+ }
418
+ /**
419
+ * Play audio data
420
+ * @param audioData - Float32Array of audio samples
421
+ * @param sampleRate - Sample rate of the audio
422
+ */
423
+ async play(audioData, sampleRate) {
424
+ const ctx = this.getAudioContext();
425
+ if (ctx.state === "suspended") {
426
+ await ctx.resume();
427
+ }
428
+ const audioBuffer = ctx.createBuffer(1, audioData.length, sampleRate);
429
+ audioBuffer.getChannelData(0).set(audioData);
430
+ const source = ctx.createBufferSource();
431
+ source.buffer = audioBuffer;
432
+ const gainNode = ctx.createGain();
433
+ gainNode.gain.value = this.config.volume;
434
+ source.connect(gainNode);
435
+ gainNode.connect(ctx.destination);
436
+ this.currentSource = source;
437
+ source.start(0);
438
+ return new Promise((resolve) => {
439
+ source.onended = () => {
440
+ this.currentSource = null;
441
+ resolve();
442
+ };
443
+ });
444
+ }
445
+ /**
446
+ * Stop current playback
447
+ */
448
+ stop() {
449
+ if (this.currentSource) {
450
+ try {
451
+ this.currentSource.stop();
452
+ this.currentSource = null;
453
+ } catch (error) {
454
+ }
455
+ }
456
+ }
457
+ /**
458
+ * Set volume (0.0 to 1.0)
459
+ */
460
+ setVolume(volume) {
461
+ this.config.volume = Math.max(0, Math.min(1, volume));
462
+ }
463
+ /**
464
+ * Close the audio context and free resources
465
+ */
466
+ async close() {
467
+ this.stop();
468
+ if (this.audioContext) {
469
+ await this.audioContext.close();
470
+ this.audioContext = null;
471
+ }
472
+ }
473
+ };
474
+ function createAudioPlayer(config) {
475
+ return new AudioPlayer(config);
476
+ }
477
+
478
+ exports.AudioPlayer = AudioPlayer;
479
+ exports.SimpleQueue = SimpleQueue;
480
+ exports.TTSLogic = TTSLogic;
481
+ exports.createAudioPlayer = createAudioPlayer;
482
+ exports.createOrtEnvironment = createOrtEnvironment;
483
+ exports.emitSentence = emitSentence;
484
+ exports.ensureOrtReady = ensureOrtReady;
485
+ exports.ensureVoiceLoaded = ensureVoiceLoaded;
486
+ exports.getAsyncIterator = getAsyncIterator;
487
+ exports.getBackendLabel = getBackendLabel;
488
+ exports.handleChunk = handleChunk;
489
+ exports.isCorruptModelError = isCorruptModelError;
490
+ exports.nextBoundaryIndex = nextBoundaryIndex;
491
+ exports.playerWorker = playerWorker;
492
+ exports.preparePiperVoice = preparePiperVoice;
493
+ exports.resetVoiceCache = resetVoiceCache;
494
+ exports.streamTokensToSpeech = streamTokensToSpeech;
495
+ exports.synthesizerWorker = synthesizerWorker;
496
+ exports.textToPhonemes = textToPhonemes;
497
+ exports.useStreamingTTS = useStreamingTTS;
498
+ exports.warmupPiper = warmupPiper;
499
+ //# sourceMappingURL=index.cjs.map
500
+ //# sourceMappingURL=index.cjs.map