import { useState, useRef, useEffect, useCallback, useMemo } from 'react' import { Play, Square, Download, Eraser, Loader2, Volume2 } from 'lucide-react' import { TextToSpeechWorkerInput, WorkerMessage } from '../../types' import { useModel } from '../../contexts/ModelContext' import { useTextToSpeech, AudioResult } from '../../contexts/TextToSpeechContext' import AudioPlayer from '../AudioPlayer' import { preview } from 'vite' const SAMPLE_TEXTS = [ 'Hello, this is a sample text for text-to-speech synthesis.', 'Transformers.js makes it easy to run machine learning models in the browser.', 'The quick brown fox jumps over the lazy dog.', 'Text-to-speech technology converts written text into spoken words using artificial intelligence.' ] function TextToSpeech() { const { config, setConfig, audioResults, currentText, setCurrentText, addAudioResult, clearAudioResults } = useTextToSpeech() const [isSynthesizing, setIsSynthesizing] = useState(false) const { activeWorker, status, modelInfo, hasBeenLoaded, selectedQuantization } = useModel() const handleSynthesize = useCallback(() => { if (!currentText.trim() || !modelInfo || !activeWorker || isSynthesizing) return setIsSynthesizing(true) const message: TextToSpeechWorkerInput = { type: 'synthesize', text: currentText.trim(), model: modelInfo.id, dtype: selectedQuantization ?? 'fp32', isStyleTTS2: modelInfo.isStyleTTS2 ?? false, config: { speakerEmbeddings: config.speakerEmbeddings, voice: config.voice } } activeWorker.postMessage(message) }, [ currentText, modelInfo, activeWorker, config, isSynthesizing, selectedQuantization ]) useEffect(() => { if (!activeWorker) return const onMessageReceived = (e: MessageEvent) => { const { status, output } = e.data if (status === 'output' && output) { setIsSynthesizing(false) const audioResult = { audio: new Float32Array(output.audio), sampling_rate: output.sampling_rate } addAudioResult(currentText, audioResult, config.voice) } else if (status === 'ready' || status === 'error') { setIsSynthesizing(false) } } activeWorker.addEventListener('message', onMessageReceived) return () => activeWorker.removeEventListener('message', onMessageReceived) }, [activeWorker, currentText, addAudioResult]) useEffect(() => { if (!modelInfo) return if (modelInfo && modelInfo?.voices.length > 0) setConfig((prev) => ({ ...prev, voice: modelInfo.voices[0] })) }, [modelInfo]) const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() handleSynthesize() } } const busy = status !== 'ready' || isSynthesizing return (

Text to Speech