{"record":{"id":"8150e19c9d78a45a","repo":"SubtitleEdit/subtitleedit","slug":"indextts-crispasr-requires-a-reference-voice-wav","errorCode":null,"errorMessage":"IndexTTS (CrispASR) requires a reference voice WAV. Import one via the voice settings, then pick it in the voice combo. Reference WAV should be 24 kHz mono (3-10 s of clean speech).","messagePattern":"IndexTTS \\(CrispASR\\) requires a reference voice WAV\\. Import one via the voice settings, then pick it in the voice combo\\. Reference WAV should be 24 kHz mono \\(3-10 s of clean speech\\)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/TextToSpeech/Engines/IndexTtsCrispAsr.cs","lineNumber":357,"sourceCode":"        GetVoices(language);\n\n    public async Task<TtsResult> Speak(\n        string text,\n        string outputFolder,\n        Voice voice,\n        TtsLanguage? language,\n        string? region,\n        string? model,\n        CancellationToken cancellationToken)\n    {\n        if (voice.EngineVoice is not IndexTtsVoice indexVoice)\n        {\n            throw new ArgumentException(\"Voice is not an IndexTtsVoice\");\n        }\n\n        if (string.IsNullOrEmpty(indexVoice.FilePath))\n        {\n            throw new InvalidOperationException(\n                \"IndexTTS (CrispASR) requires a reference voice WAV. \"\n                + \"Import one via the voice settings, then pick it in the voice combo. \"\n                + \"Reference WAV should be 24 kHz mono (3-10 s of clean speech).\");\n        }\n\n        var modelKey = ResolveModelKey(model);\n        await EnsureServerRunningAsync(modelKey, indexVoice.FilePath, cancellationToken);\n\n        var outputFileName = Path.Combine(TtsOutputFolder.Resolve(outputFolder, GetSetFolder), Guid.NewGuid() + \".wav\");\n        var inputText = text;\n\n        // OpenAI-compatible /v1/audio/speech payload. CrispASR's indextts backend uses:\n        //   - `input`             — the text to synthesise\n        //   - `response_format`   — \"wav\"\n        //   - `voice`             — absolute WAV path or filename in --voice-dir\n        //   - `speed`             — server-side linear resample of the synth output (0.25-4.0).\n        //                           Default is 1.0; the user can override in the engine settings.\n        // The server-mode indextts backend ignores the request `voice` field, so we still","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/TextToSpeech/Engines/IndexTtsCrispAsr.cs#L339-L375","documentation":"InvalidOperationException from IndexTtsCrispAsr.Speak when the IndexTtsVoice is the correct type but its `FilePath` is null or empty. IndexTTS is a voice-cloning engine: it needs a reference WAV baked into the server at startup via `--voice`, so an empty path is unrecoverable. The message tells the user to import a reference WAV and gives the format spec (24 kHz mono, 3–10 s).","triggerScenarios":"Selecting an IndexTTS voice entry that was created before a reference WAV was attached; deleting/moving the referenced WAV after import; an import flow that registered the voice name but left FilePath blank.","commonSituations":"User picked the engine before importing a reference clip; the imported file was on a removable drive now detached; voice list loaded from an older settings format that didn't persist FilePath.","solutions":["Open the voice settings and import a clean 3–10 s 24 kHz mono WAV as the reference.","Re-select that voice in the IndexTTS combo so the entry is bound to the file.","If the WAV was moved, re-import from its new location.","Validate the WAV format (24 kHz mono PCM) — wrong format can also cause downstream synth failures."],"exampleFix":"// before\nvar voice = new Voice { EngineVoice = new IndexTtsVoice { FilePath = \"\" } };\n\n// after\nvar voice = new Voice { EngineVoice = new IndexTtsVoice { FilePath = @\"C:\\Voices\\ref.wav\" } };","handlingStrategy":"validation","validationCode":"if (voice.EngineVoice is IndexTtsVoice iv && string.IsNullOrEmpty(iv.FilePath))\n{\n    WarnUser(\"Import a reference WAV (24 kHz mono, 3-10 s) first.\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try { await indexEngine.Speak(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"requires a reference voice WAV\"))\n{\n    PromptImportReferenceWav();\n}","preventionTips":["Disable the Speak button until the selected IndexTTS voice has a non-empty FilePath.","Validate the WAV exists at FilePath before each batch (files can be moved/deleted).","On import, verify 24 kHz mono PCM format and reject otherwise.","Re-bind the voice entry when the underlying file moves."],"tags":["indextts","crispasr","voice-cloning","reference-audio","tts","validation"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}