Spaces:
Running on Zero
Running on Zero
File size: 2,940 Bytes
b260242 fc8c46f b260242 fc8c46f b260242 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | """L2 tests for post-processing — Demucs and ffmpeg are mocked."""
from __future__ import annotations
from pathlib import Path
from unittest.mock import MagicMock
import post_process as pp
def test_separate_stems_returns_four_paths(tmp_path, monkeypatch):
"""Mocks the lower-level demucs path used by post_process.separate_stems:
torchaudio.load → apply_model → sf.write. The wrapper convenience API
(Separator.separate_audio_file) is intentionally not in this code path
because it only ships with demucs >= 4.1."""
import sys
import types
import numpy as np
import torch
src = tmp_path / "song.wav"
src.write_bytes(b"RIFF" + b"\0" * 100)
fake_model = MagicMock()
fake_model.samplerate = 44100
fake_model.sources = ["drums", "bass", "other", "vocals"]
fake_model.audio_channels = 2
monkeypatch.setattr(pp, "_get_demucs", lambda: fake_model)
fake_torchaudio = types.ModuleType("torchaudio")
fake_torchaudio.load = lambda _path: (torch.zeros((2, 44100)), 44100)
fake_torchaudio.functional = types.SimpleNamespace(resample=lambda wav, _sr_in, _sr_out: wav)
monkeypatch.setitem(sys.modules, "torchaudio", fake_torchaudio)
fake_demucs_apply = types.ModuleType("demucs.apply")
fake_demucs_apply.apply_model = lambda _m, batch, **_kw: torch.zeros((batch.shape[0], 4, 2, 44100))
monkeypatch.setitem(sys.modules, "demucs.apply", fake_demucs_apply)
written: list[str] = []
def fake_sf_write(path, _data, _sr):
written.append(path)
Path(path).write_bytes(b"RIFF" + b"\0" * 100)
fake_sf = types.ModuleType("soundfile")
fake_sf.write = fake_sf_write
fake_sf.read = lambda _path: (np.zeros((44100, 2)), 44100)
monkeypatch.setitem(sys.modules, "soundfile", fake_sf)
stems = pp.separate_stems(src)
assert set(stems.keys()) == {"vocals", "drums", "bass", "other"}
for p in stems.values():
assert Path(p).exists()
def test_normalise_lufs_invokes_pyloudnorm(monkeypatch, tmp_path):
src = tmp_path / "in.wav"
src.write_bytes(b"RIFF" + b"\0" * 100)
captured = {}
def fake_norm(in_path, out_path, target_lufs):
captured.update({"in": in_path, "out": out_path, "target": target_lufs})
Path(out_path).write_bytes(b"RIFF")
monkeypatch.setattr(pp, "_pyloudnorm_normalise", fake_norm)
out = pp.normalise_lufs(src, target_lufs=-14.0)
assert captured["target"] == -14.0
assert Path(out).exists()
def test_to_mp3_invokes_ffmpeg(monkeypatch, tmp_path):
src = tmp_path / "in.wav"
src.write_bytes(b"RIFF")
captured = {}
def fake_run(cmd, **kw):
captured["cmd"] = cmd
Path(cmd[-1]).write_bytes(b"ID3")
return MagicMock(returncode=0)
monkeypatch.setattr(pp.subprocess, "run", fake_run)
out = pp.to_mp3(src, bitrate_kbps=320)
assert Path(out).exists()
assert "320k" in " ".join(captured["cmd"])
|