gelpi01 commited on
Commit
1ded0f9
·
1 Parent(s): c48e3b9

Usar Spleeter para separación y corregir flujo

Browse files
Files changed (2) hide show
  1. app.py +12 -12
  2. audio_pipeline.py +16 -32
app.py CHANGED
@@ -3,36 +3,36 @@
3
  import os
4
  import gradio as gr
5
  from audio_pipeline import (
6
- separar_audio_demucs,
7
  limpiar_stems,
8
  combinar_stems_sin_vocales,
9
  reducir_ruido
10
  )
11
 
12
  def procesar_wav(input_wav_path):
13
- # 1) Separar con Demucs y obtener carpeta de stems
14
- stems_dir = separar_audio_demucs(input_wav_path)
15
 
16
  # 2) Limpiar stems (_cleaned.wav)
17
  limpiar_stems(stems_dir)
18
 
19
- # 3) Combinar stems sin vocales en base_instrumental.wav
20
  combinar_stems_sin_vocales(stems_dir)
21
 
22
- # 4) Reducir ruido sobre la base resultante
23
- base_instru = os.path.join(stems_dir, "base_instrumental.wav")
24
- clean_instru = os.path.join(stems_dir, "base_instrumental_clean.wav")
25
- reducir_ruido(base_instru, clean_instru)
26
 
27
- # 5) Devolver la ruta del WAV limpio
28
- return clean_instru
29
 
30
  demo = gr.Interface(
31
  fn=procesar_wav,
32
  inputs=gr.Audio(label="Sube un archivo .wav", type="filepath"),
33
  outputs=gr.Audio(label="Base instrumental limpia", type="filepath"),
34
- title="Procesador de WAV a Base Instrumental",
35
- description="Sube tu WAV y obtén su base limpia sin vocales."
36
  )
37
 
38
  if __name__ == "__main__":
 
3
  import os
4
  import gradio as gr
5
  from audio_pipeline import (
6
+ separar_audio_spleeter,
7
  limpiar_stems,
8
  combinar_stems_sin_vocales,
9
  reducir_ruido
10
  )
11
 
12
  def procesar_wav(input_wav_path):
13
+ # 1) Separar con Spleeter
14
+ stems_dir = separar_audio_spleeter(input_wav_path)
15
 
16
  # 2) Limpiar stems (_cleaned.wav)
17
  limpiar_stems(stems_dir)
18
 
19
+ # 3) Combinar stems sin vocales => base_instrumental.wav
20
  combinar_stems_sin_vocales(stems_dir)
21
 
22
+ # 4) Reducir ruido en la base
23
+ base = os.path.join(stems_dir, "base_instrumental.wav")
24
+ clean = os.path.join(stems_dir, "base_instrumental_clean.wav")
25
+ reducir_ruido(base, clean)
26
 
27
+ # 5) Devolver ruta al WAV final
28
+ return clean
29
 
30
  demo = gr.Interface(
31
  fn=procesar_wav,
32
  inputs=gr.Audio(label="Sube un archivo .wav", type="filepath"),
33
  outputs=gr.Audio(label="Base instrumental limpia", type="filepath"),
34
+ title="Procesador de WAV a Base Instrumental con Spleeter",
35
+ description="Sube tu WAV y obtén la base sin vocales usando Spleeter."
36
  )
37
 
38
  if __name__ == "__main__":
audio_pipeline.py CHANGED
@@ -1,47 +1,33 @@
1
  # audio_pipeline.py
2
 
3
  import os
4
- import subprocess
5
- import sys
6
- import torch
7
  import librosa
8
  import numpy as np
9
  import soundfile as sf
10
  import noisereduce as nr
 
11
 
12
  # Directorio base donde guardaremos todos los stems
13
  BASE_STEMS_DIR = "data/stems"
14
 
15
- def highpass_filter(audio, sr, cutoff=80, order=4):
16
- """Aplica un filtro Butterworth de paso alto al audio."""
17
- sos = signal.butter(order, cutoff, btype='highpass', fs=sr, output='sos')
18
- return signal.sosfilt(sos, audio)
19
-
20
- def separar_audio_demucs(input_file, model="htdemucs"):
21
  """
22
- Separa stems usando Demucs, los deja en:
23
- data/stems/<modelo>/<base_name>/
24
- y devuelve la ruta al folder con los stems.
25
  """
26
- # 1) Crear directorio raíz para ese modelo
27
- out_root = os.path.join(BASE_STEMS_DIR, model)
 
28
  os.makedirs(out_root, exist_ok=True)
29
 
30
- # 2) Ejecutar Demucs (en GPU si está disponible)
31
- device = "cuda" if torch.cuda.is_available() else "cpu"
32
- cmd = [
33
- sys.executable, "-m", "demucs",
34
- input_file,
35
- "--out", out_root,
36
- "--device", device
37
- ]
38
- subprocess.run(cmd, check=True)
39
 
40
- # 3) Detectar carpeta generada con los stems
41
- base = os.path.splitext(os.path.basename(input_file))[0]
42
  stems_dir = os.path.join(out_root, base)
43
  if not os.path.isdir(stems_dir):
44
- raise FileNotFoundError(f"No existe el folder de stems en {stems_dir}")
45
  return stems_dir
46
 
47
  def limpiar_stems(stems_dir):
@@ -55,18 +41,16 @@ def limpiar_stems(stems_dir):
55
 
56
  def combinar_stems_sin_vocales(stems_dir):
57
  """Mezcla todos los stems (limpios) excepto los de vocales."""
58
- # Primero, buscar stems *_cleaned.wav que no contengan 'vocal'
59
  wavs = [
60
  f for f in os.listdir(stems_dir)
61
- if f.endswith(".wav") and
62
- "cleaned" in f.lower() and
63
- "vocal" not in f.lower()
64
  ]
65
- # Si no hay cleaned, fallback a stems originales sin 'vocal'
66
  if not wavs:
67
  wavs = [
68
  f for f in os.listdir(stems_dir)
69
- if f.endswith(".wav") and "vocal" not in f.lower()
70
  ]
71
 
72
  signals = []
 
1
  # audio_pipeline.py
2
 
3
  import os
 
 
 
4
  import librosa
5
  import numpy as np
6
  import soundfile as sf
7
  import noisereduce as nr
8
+ from spleeter.separator import Separator
9
 
10
  # Directorio base donde guardaremos todos los stems
11
  BASE_STEMS_DIR = "data/stems"
12
 
13
+ def separar_audio_spleeter(input_file, model="spleeter:4stems"):
 
 
 
 
 
14
  """
15
+ Separa stems usando Spleeter (4 stems: vocals, drums, bass, other),
16
+ los deja en data/stems/4stems/<nombre_base>/ y devuelve esa ruta.
 
17
  """
18
+ base = os.path.splitext(os.path.basename(input_file))[0]
19
+ model_name = model.split(":")[1] # "4stems"
20
+ out_root = os.path.join(BASE_STEMS_DIR, model_name)
21
  os.makedirs(out_root, exist_ok=True)
22
 
23
+ # Ejecuta la separación
24
+ sep = Separator(model)
25
+ sep.separate_to_file(input_file, out_root)
 
 
 
 
 
 
26
 
27
+ # La salida es out_root/<base>/*.wav
 
28
  stems_dir = os.path.join(out_root, base)
29
  if not os.path.isdir(stems_dir):
30
+ raise FileNotFoundError(f"No se encontró el folder de stems en {stems_dir}")
31
  return stems_dir
32
 
33
  def limpiar_stems(stems_dir):
 
41
 
42
  def combinar_stems_sin_vocales(stems_dir):
43
  """Mezcla todos los stems (limpios) excepto los de vocales."""
44
+ # Busca "*_cleaned.wav" que no contengan "vocals"
45
  wavs = [
46
  f for f in os.listdir(stems_dir)
47
+ if f.endswith("_cleaned.wav") and "vocals" not in f.lower()
 
 
48
  ]
49
+ # Si no hay cleaned, fallback a originales sin "vocals"
50
  if not wavs:
51
  wavs = [
52
  f for f in os.listdir(stems_dir)
53
+ if f.endswith(".wav") and "vocals" not in f.lower()
54
  ]
55
 
56
  signals = []