{"record":{"id":"5c05eec75a3868a3","repo":"RVC-Boss/GPT-SoVITS","slug":"3-10","errorCode":null,"errorMessage":"参考音频在3~10秒范围外，请更换！","messagePattern":"参考音频在3~10秒范围外，请更换！","errorType":"validation","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"GPT_SoVITS/TTS_infer_pack/TTS.py","lineNumber":816,"sourceCode":"        if self.configs.is_half:\n            spec = spec.half()\n        if self.is_v2pro == True:\n            audio = resample(audio, self.configs.sampling_rate, 16000, self.configs.device)\n            if self.configs.is_half:\n                audio = audio.half()\n        else:\n            audio = None\n        return spec, audio\n\n    def _set_prompt_semantic(self, ref_wav_path: str):\n        zero_wav = np.zeros(\n            int(self.configs.sampling_rate * 0.3),\n            dtype=np.float16 if self.configs.is_half else np.float32,\n        )\n        with torch.no_grad():\n            wav16k, sr = librosa.load(ref_wav_path, sr=16000)\n            if wav16k.shape[0] > 160000 or wav16k.shape[0] < 48000:\n                raise OSError(i18n(\"参考音频在3~10秒范围外，请更换！\"))\n            wav16k = torch.from_numpy(wav16k)\n            zero_wav_torch = torch.from_numpy(zero_wav)\n            wav16k = wav16k.to(self.configs.device)\n            zero_wav_torch = zero_wav_torch.to(self.configs.device)\n            if self.configs.is_half:\n                wav16k = wav16k.half()\n                zero_wav_torch = zero_wav_torch.half()\n\n            wav16k = torch.cat([wav16k, zero_wav_torch])\n            hubert_feature = self.cnhuhbert_model.model(wav16k.unsqueeze(0))[\"last_hidden_state\"].transpose(\n                1, 2\n            )  # .float()\n            codes = self.vits_model.extract_latent(hubert_feature)\n\n            prompt_semantic = codes[0, 0].to(self.configs.device)\n            self.prompt_cache[\"prompt_semantic\"] = prompt_semantic\n\n    def batch_sequences(self, sequences: List[torch.Tensor], axis: int = 0, pad_value: int = 0, max_length: int = None):","sourceCodeStart":798,"sourceCodeEnd":834,"githubUrl":"https://github.com/RVC-Boss/GPT-SoVITS/blob/d523079fc05d9a8028d6085bffe4a2757c32abb6/GPT_SoVITS/TTS_infer_pack/TTS.py#L798-L834","documentation":"Raised in _set_prompt_semantic() after loading the reference audio at 16 kHz: the HuBERT/CnHuBERT SSL frontend requires the prompt audio to be between 48000 samples (3 s) and 160000 samples (10 s). Outside this window the extracted semantic tokens degrade badly (too short = not enough voice identity; too long = memory/quality issues), so the loader rejects it with an OSError instead of producing bad audio.","triggerScenarios":"Calling set_ref_audio(ref_wav_path) (directly or via infer_batch with a new ref_audio_path) where librosa.load(ref_wav_path, sr=16000) returns wav16k.shape[0] > 160000 or < 48000 — audio shorter than 3 seconds or longer than 10 seconds at 16 kHz.","commonSituations":"User records a 2-second voice sample; user points at a full 30-second song/utterance as reference; trailing silence trimmed too aggressively; wrong file selected (e.g. an hour-long podcast).","solutions":["Trim or re-select the reference audio to be between 3 and 10 seconds of speech (aim for 5-8 s of clean speech).","Use tools/slicer2.py (or the webui audio slicing) to cut a long recording into valid 3-10 s segments and pick the cleanest one.","If your pipeline controls the input, pre-check duration with librosa.get_duration(path=..., ) or soundfile before calling set_ref_audio and reject/trim early.","Strip leading/trailing silence (e.g. with ffmpeg silenceremove or sox) so a '10 second' file actually contains ~10 s of speech within the limit."],"exampleFix":"# before\nhandler.set_ref_audio(\"ref.wav\")  # OSError: 参考音频在3~10秒范围外\n\n# after\nimport librosa\ndur = librosa.get_duration(path=\"ref.wav\")\nassert 3 <= dur <= 10, f\"ref audio is {dur:.1f}s, must be 3-10s\"\nhandler.set_ref_audio(\"ref.wav\")","handlingStrategy":"validation","validationCode":"import librosa\n\ndef valid_ref_duration(path: str, lo: float = 3.0, hi: float = 10.0) -> bool:\n    dur = librosa.get_duration(path=path)\n    return lo <= dur <= hi\n\nif not valid_ref_duration(ref_wav):\n    ref_wav = auto_trim_to(ref_wav, target=6.0)  # or prompt the user","typeGuard":null,"tryCatchPattern":"try:\n    handler.set_ref_audio(ref_wav)\nexcept OSError as e:\n    if \"3~10\" in str(e):\n        ref_wav = trim_or_pick_another(ref_wav)\n        handler.set_ref_audio(ref_wav)\n    else:\n        raise","preventionTips":["Standardize reference clips at 5-8 seconds of clean speech.","Strip silence before measuring duration so padding doesn't push past 10 s.","Pre-check with librosa.get_duration in ingestion pipelines and reject early with a friendly message."],"tags":["reference-audio","audio-duration","validation","tts"],"backgroundTag":null,"analyzedSha":"d523079fc05d9a8028d6085bffe4a2757c32abb6","analyzedAt":"2026-08-15T01:06:46.402Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}