diff --git a/src/islands/media/TextToSpeech.tsx b/src/islands/media/TextToSpeech.tsx index 8acac64..8188c68 100644 --- a/src/islands/media/TextToSpeech.tsx +++ b/src/islands/media/TextToSpeech.tsx @@ -3,7 +3,7 @@ import { Button } from '@/components/ui/Button'; import { Alert } from '@/components/ui/Alert'; import { splitIntoChunks } from '@/tools/media/tts.lib'; import { floatToWav } from '@/tools/media/tts-audio.lib'; -import { NEURAL_VOICES } from '@/tools/media/neural-tts.engine'; +import { NEURAL_VOICES } from '@/tools/media/neural-tts.voices'; import { downloadService } from '@/services/download'; import type { Lang } from '@/i18n/config'; diff --git a/src/tools/media/neural-tts.engine.ts b/src/tools/media/neural-tts.engine.ts index d52b1f7..271e59a 100644 --- a/src/tools/media/neural-tts.engine.ts +++ b/src/tools/media/neural-tts.engine.ts @@ -6,22 +6,13 @@ * through the same-origin /hf proxy, matching the Whisper setup. */ import { concatWithSilence, floatToPcm16, splitForPause } from './tts-audio.lib'; +import type { NeuralVoice } from './neural-tts.voices'; -export interface NeuralVoice { id: string; label: string; model: string; } - -// MMS-TTS is multilingual with one small model per language and needs no speaker -// embedding. A curated set that has ONNX ports on the Hugging Face hub. -export const NEURAL_VOICES: NeuralVoice[] = [ - { id: 'eng', label: 'English', model: 'Xenova/mms-tts-eng' }, - { id: 'ind', label: 'Bahasa Indonesia', model: 'Xenova/mms-tts-ind' }, - { id: 'spa', label: 'Español', model: 'Xenova/mms-tts-spa' }, - { id: 'fra', label: 'Français', model: 'Xenova/mms-tts-fra' }, - { id: 'deu', label: 'Deutsch', model: 'Xenova/mms-tts-deu' }, - { id: 'por', label: 'Português', model: 'Xenova/mms-tts-por' }, - { id: 'rus', label: 'Русский', model: 'Xenova/mms-tts-rus' }, - { id: 'ara', label: 'العربية', model: 'Xenova/mms-tts-ara' }, - { id: 'hin', label: 'हिन्दी', model: 'Xenova/mms-tts-hin' }, -]; +// Re-exported for compatibility; the catalogue lives in a lightweight module so +// the TextToSpeech island can import the voice list without pulling this heavy +// engine into its chunk (see neural-tts.voices.ts). +export { NEURAL_VOICES } from './neural-tts.voices'; +export type { NeuralVoice } from './neural-tts.voices'; /* eslint-disable @typescript-eslint/no-explicit-any */ let cached: { model: string; synth: any } | null = null; diff --git a/src/tools/media/neural-tts.voices.ts b/src/tools/media/neural-tts.voices.ts new file mode 100644 index 0000000..fdeaf3b --- /dev/null +++ b/src/tools/media/neural-tts.voices.ts @@ -0,0 +1,25 @@ +/** + * Voice catalogue for neural TTS, split out from `neural-tts.engine.ts` so the + * TextToSpeech island can list voices without statically importing the engine + * (which is heavy and must stay dynamically imported / code-split — a static + + * dynamic import of the engine made Rollup keep it in the island chunk). + */ +export interface NeuralVoice { + id: string; + label: string; + model: string; +} + +// MMS-TTS is multilingual with one small model per language and needs no speaker +// embedding. A curated set that has ONNX ports on the Hugging Face hub. +export const NEURAL_VOICES: NeuralVoice[] = [ + { id: 'eng', label: 'English', model: 'Xenova/mms-tts-eng' }, + { id: 'ind', label: 'Bahasa Indonesia', model: 'Xenova/mms-tts-ind' }, + { id: 'spa', label: 'Español', model: 'Xenova/mms-tts-spa' }, + { id: 'fra', label: 'Français', model: 'Xenova/mms-tts-fra' }, + { id: 'deu', label: 'Deutsch', model: 'Xenova/mms-tts-deu' }, + { id: 'por', label: 'Português', model: 'Xenova/mms-tts-por' }, + { id: 'rus', label: 'Русский', model: 'Xenova/mms-tts-rus' }, + { id: 'ara', label: 'العربية', model: 'Xenova/mms-tts-ara' }, + { id: 'hin', label: 'हिन्दी', model: 'Xenova/mms-tts-hin' }, +];