CoolFace
Apppublic

NhanNguyen1309/audio-separation-api

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
harmonic_source.py79 linesDownload Raw Back to app
1from __future__ import annotations2 3from dataclasses import dataclass, field4from pathlib import Path5 6from app.config import settings7 8 9@dataclass(slots=True)10class ChordAudioSource:11    path: Path12    source: str13    warnings: list[str] = field(default_factory=list)14 15 16def _find_first(root: Path, names: tuple[str, ...]) -> Path | None:17    for name in names:18        candidates = sorted(path for path in root.rglob(name) if path.is_file())19        if candidates:20            return candidates[0]21    return None22 23 24def _combine_stems(bass_path: Path, other_path: Path, output_path: Path) -> None:25    import librosa  # type: ignore[import-untyped]26    import numpy as np27    import soundfile as sf28 29    bass, sr = librosa.load(str(bass_path), sr=44100, mono=True)30    other, _ = librosa.load(str(other_path), sr=sr, mono=True)31    length = max(len(bass), len(other))32    bass = np.pad(bass, (0, length - len(bass)))33    other = np.pad(other, (0, length - len(other)))34    output_path.parent.mkdir(parents=True, exist_ok=True)35    sf.write(str(output_path), (bass + other) / 2.0, sr)36 37 38def _build_harmonic_audio(original_path: Path, output_path: Path) -> None:39    import librosa  # type: ignore[import-untyped]40    import soundfile as sf41 42    audio, sr = librosa.load(str(original_path), sr=11025, mono=True)43    harmonic = librosa.effects.harmonic(audio, kernel_size=17)44    output_path.parent.mkdir(parents=True, exist_ok=True)45    sf.write(str(output_path), harmonic, sr)46 47 48def prepare_chord_detection_audio(49    original_audio_path: str | Path,50    output_path: str | Path | None = None,51    existing_stems_dir: str | Path | None = None,52) -> ChordAudioSource:53    original = Path(original_audio_path)54    harmonic_output = Path(output_path) if output_path else original.with_name("harmonic.wav")55 56    if not settings.chord_use_harmonic_source:57        return ChordAudioSource(path=original, source="original")58 59    if existing_stems_dir:60        stems_root = Path(existing_stems_dir)61        instrumental = _find_first(stems_root, ("instrumental.wav", "no_vocals.wav"))62        if instrumental:63            return ChordAudioSource(path=instrumental, source="instrumental")64 65        bass = _find_first(stems_root, ("bass.wav",))66        other = _find_first(stems_root, ("other.wav",))67        if bass and other:68            try:69                _combine_stems(bass, other, harmonic_output)70                return ChordAudioSource(path=harmonic_output, source="bass_other")71            except Exception:  # noqa: BLE00172                pass73 74    try:75        _build_harmonic_audio(original, harmonic_output)76        return ChordAudioSource(path=harmonic_output, source="harmonic")77    except Exception:  # noqa: BLE00178        return ChordAudioSource(path=original, source="original", warnings=["harmonic_audio_fallback_used"])79