import { HFModelConfig_v1, InterfaceHF } from "outetts"; // Check if WebGPU is supported let fp16_supported = false; try { const adapter = await navigator.gpu.requestAdapter(); if (!adapter) { throw new Error("WebGPU is not supported (no adapter found)"); } fp16_supported = adapter.features.has("shader-f16"); self.postMessage({ status: "feature-success" }); } catch (e) { self.postMessage({ status: "feature-error", data: e.toString(), }); throw e; } // Configure the model const model_config = new HFModelConfig_v1({ model_path: "onnx-community/OuteTTS-0.2-500M", language: "en", // Supported languages in v0.2: en, zh, ja, ko dtype: fp16_supported ? "q4f16" : "q4", // Supported dtypes: fp32, fp16, q8, q4, q4f16 device: "webgpu", // Supported devices: webgpu, wasm }); // Initialize the interface const tts_interface = await InterfaceHF({ model_version: "0.2", cfg: model_config, }); self.postMessage({ status: "ready" }); // Listen for messages from the main thread self.addEventListener("message", async (e) => { const { text, speaker_id } = e.data; // Load a default speaker const speaker = speaker_id === "random" ? null : tts_interface.load_default_speaker(speaker_id); // Generate speech const output = await tts_interface.generate({ text, temperature: 0.1, // Lower temperature values may result in a more stable tone repetition_penalty: 1.1, max_length: 4096, // Optional: Use a speaker profile for consistent voice characteristics // Without a speaker profile, the model will generate a voice with random characteristics speaker, }); // Send the audio file back to the main thread const buffer = output.to_wav("output.wav"); const blob = new Blob([buffer], { type: "audio/wav" }); self.postMessage({ status: "complete", audio: URL.createObjectURL(blob), text, }); });