{"record":{"id":"d9b1ba05bbce6474","repo":"microsoft/VibeVoice","slug":"soundfile-is-required-to-save-audio-files-install","errorCode":null,"errorMessage":"soundfile is required to save audio files. Install it with: pip install soundfile","messagePattern":"soundfile is required to save audio files\\. Install it with: pip install soundfile","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"vibevoice/processor/vibevoice_tokenizer_processor.py","lineNumber":313,"sourceCode":"                - torch.Tensor: PyTorch tensor with shape (B, C, T) or (B, T) or (T)\n                - np.ndarray: NumPy array with shape (B, C, T) or (B, T) or (T)\n                - List of tensors or arrays\n            output_path: Path where to save the audio. If saving multiple files,\n                this is treated as a directory and individual files will be saved inside.\n            sampling_rate: Sampling rate for the saved audio. Defaults to the processor's rate.\n            normalize: Whether to normalize audio before saving.\n            batch_prefix: Prefix for batch files when saving multiple audios.\n                \n        Returns:\n            List[str]: Paths to the saved audio files.\n        \"\"\"\n        if sampling_rate is None:\n            sampling_rate = self.sampling_rate\n        \n        try:\n            import soundfile as sf\n        except ImportError:\n            raise ImportError(\n                \"soundfile is required to save audio files. \"\n                \"Install it with: pip install soundfile\"\n            )\n        \n        # Ensure audio is in the right format\n        if isinstance(audio, torch.Tensor):\n            # Convert PyTorch tensor to numpy\n            audio_np = audio.float().detach().cpu().numpy()\n        elif isinstance(audio, np.ndarray):\n            audio_np = audio\n        elif isinstance(audio, list):\n            # Handle list of tensors or arrays\n            if all(isinstance(a, torch.Tensor) for a in audio):\n                audio_np = [a.float().detach().cpu().numpy() for a in audio]\n            else:\n                audio_np = audio\n        else:\n            raise ValueError(f\"Unsupported audio type: {type(audio)}\")","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/microsoft/VibeVoice/blob/94da20d98b2fa7688e9cbfaf7692ddb4954f7600/vibevoice/processor/vibevoice_tokenizer_processor.py#L295-L331","documentation":"VibeVoice's tokenizer processor lazily imports `soundfile` inside `save_audio()`; if the import fails, it re-raises an ImportError telling you soundfile is required. The dependency is optional, so a base install of the package does not include it, and the failure only surfaces at save time, not at package import time. The error is purely environmental — the audio data itself is fine.","triggerScenarios":"Calling `processor.save_audio(audio, \"out.wav\")` (or any batch/list variant) in an environment where `pip install soundfile` was never run or where libsndfile (the C library soundfile wraps) is missing, making `import soundfile` raise ImportError.","commonSituations":"Running inference in a slim Docker/CI image, a fresh venv where vibevoice was installed without the `[audio]`/soundfile extra, or on a system without libsndfile installed (Alpine/minimal images) so the soundfile wheel cannot load.","solutions":["Install the dependency: `pip install soundfile` (add it to requirements.txt or the project's audio extra).","If libsndfile is missing at the OS level, install it: `apt-get install libsndfile1` (Debian/Ubuntu) or `apk add libsndfile` (Alpine), then retry.","If you cannot install soundfile, convert the tensor yourself and write the WAV with `torchaudio.save`/`scipy.io.wavfile.write` instead of calling `save_audio`."],"exampleFix":"# before (ImportError in slim environments)\nprocessor.save_audio(wav, \"out.wav\")\n\n# after: ensure the optional dep is present\n# pip install soundfile\nprocessor.save_audio(wav, \"out.wav\")","handlingStrategy":"validation","validationCode":"import importlib.util\n\nif importlib.util.find_spec(\"soundfile\") is None:\n    raise RuntimeError(\n        \"soundfile is not installed; run `pip install soundfile` before saving audio\"\n    )\nprocessor.save_audio(wav, \"out.wav\")","typeGuard":null,"tryCatchPattern":"try:\n    processor.save_audio(wav, \"out.wav\")\nexcept ImportError as e:\n    if \"soundfile\" in str(e):\n        logger.error(\"Optional dependency missing: %s\", e)\n        raise SystemExit(\"Install with: pip install soundfile\") from e\n    raise","preventionTips":["Add soundfile to your project's requirements or install the package with its audio extras.","In Dockerfiles, install libsndfile1 (or use an image that has it) so the soundfile wheel can load.","Check importlib.util.find_spec('soundfile') at pipeline startup, not at save time, to fail fast."],"tags":["python","audio","dependency","optional-import","environment"],"backgroundTag":null,"analyzedSha":"94da20d98b2fa7688e9cbfaf7692ddb4954f7600","analyzedAt":"2026-08-15T04:12:07.418Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}