Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -35,23 +35,26 @@ def analyze_and_separate(audio_file):
|
|
| 35 |
print(f"Analyzing {filename}...")
|
| 36 |
y, sr = librosa.load(audio_file, duration=60, mono=True)
|
| 37 |
tempo, _ = librosa.beat.beat_track(y=y, sr=sr)
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
print(f"Detected BPM: {bpm}")
|
| 40 |
|
| 41 |
# 2. Demucs Separation (Using 6-Stem Model)
|
| 42 |
print("Separating stems (6-Stem Model)...")
|
| 43 |
-
# We use '-n htdemucs_6s' to get Guitar and Piano separation
|
| 44 |
subprocess.run([
|
| 45 |
sys.executable, "-m", "demucs", "-n", "htdemucs_6s", "--out", str(TEMP_DIR), audio_file
|
| 46 |
], check=True, capture_output=True)
|
| 47 |
|
| 48 |
# 3. Locate Stems
|
| 49 |
-
demucs_out = TEMP_DIR / "htdemucs_6s"
|
| 50 |
track_folder = next(demucs_out.iterdir(), None)
|
| 51 |
if not track_folder: raise FileNotFoundError("Demucs failed to output files.")
|
| 52 |
|
| 53 |
-
# Map all 6 stems
|
| 54 |
-
# Note: If a stem (like guitar) is silent, Demucs still creates the file.
|
| 55 |
drums = track_folder / "drums.wav"
|
| 56 |
bass = track_folder / "bass.wav"
|
| 57 |
guitar = track_folder / "guitar.wav"
|
|
@@ -108,14 +111,14 @@ def package_and_export(track_folder_str, bpm, start_offset_sec, cover_art):
|
|
| 108 |
return out_path
|
| 109 |
|
| 110 |
# Generate loops for all 6 stems
|
| 111 |
-
created_loops['melody'] = make_loop(stems['Synths'], "SynthLoop")
|
| 112 |
make_loop(stems['Drums'], "DrumLoop")
|
| 113 |
make_loop(stems['Bass'], "BassLoop")
|
| 114 |
make_loop(stems['Guitar'], "GuitarLoop")
|
| 115 |
make_loop(stems['Piano'], "PianoLoop")
|
| 116 |
make_loop(stems['Vocals'], "VocalChop")
|
| 117 |
|
| 118 |
-
# 3. Generate Video
|
| 119 |
video_path = None
|
| 120 |
if cover_art and created_loops['melody']:
|
| 121 |
print("Rendering Dynamic Video...")
|
|
@@ -126,8 +129,7 @@ def package_and_export(track_folder_str, bpm, start_offset_sec, cover_art):
|
|
| 126 |
# Load and Resize Image
|
| 127 |
img = ImageClip(cover_art).resize(width=1080)
|
| 128 |
|
| 129 |
-
# Simple Zoom Animation
|
| 130 |
-
# We use a lambda function for the resize filter
|
| 131 |
img = img.resize(lambda t : 1 + 0.02*t)
|
| 132 |
img = img.set_position(('center', 'center'))
|
| 133 |
img = img.set_duration(duration)
|
|
@@ -157,8 +159,8 @@ def package_and_export(track_folder_str, bpm, start_offset_sec, cover_art):
|
|
| 157 |
|
| 158 |
|
| 159 |
# --- GUI (Blocks) ---
|
| 160 |
-
|
| 161 |
-
with gr.Blocks(title="Night Pulse | Command Center (6-Stem)"
|
| 162 |
gr.Markdown("# 🎛️ Night Pulse | 6-Stem Command Center")
|
| 163 |
gr.Markdown("Deconstruct audio into 6 stems: Drums, Bass, Guitar, Piano, Vocals, Synths.")
|
| 164 |
|
|
|
|
| 35 |
print(f"Analyzing {filename}...")
|
| 36 |
y, sr = librosa.load(audio_file, duration=60, mono=True)
|
| 37 |
tempo, _ = librosa.beat.beat_track(y=y, sr=sr)
|
| 38 |
+
|
| 39 |
+
# Robust BPM logic
|
| 40 |
+
if np.ndim(tempo) > 0:
|
| 41 |
+
bpm = int(round(tempo[0]))
|
| 42 |
+
else:
|
| 43 |
+
bpm = int(round(tempo))
|
| 44 |
print(f"Detected BPM: {bpm}")
|
| 45 |
|
| 46 |
# 2. Demucs Separation (Using 6-Stem Model)
|
| 47 |
print("Separating stems (6-Stem Model)...")
|
|
|
|
| 48 |
subprocess.run([
|
| 49 |
sys.executable, "-m", "demucs", "-n", "htdemucs_6s", "--out", str(TEMP_DIR), audio_file
|
| 50 |
], check=True, capture_output=True)
|
| 51 |
|
| 52 |
# 3. Locate Stems
|
| 53 |
+
demucs_out = TEMP_DIR / "htdemucs_6s"
|
| 54 |
track_folder = next(demucs_out.iterdir(), None)
|
| 55 |
if not track_folder: raise FileNotFoundError("Demucs failed to output files.")
|
| 56 |
|
| 57 |
+
# Map all 6 stems
|
|
|
|
| 58 |
drums = track_folder / "drums.wav"
|
| 59 |
bass = track_folder / "bass.wav"
|
| 60 |
guitar = track_folder / "guitar.wav"
|
|
|
|
| 111 |
return out_path
|
| 112 |
|
| 113 |
# Generate loops for all 6 stems
|
| 114 |
+
created_loops['melody'] = make_loop(stems['Synths'], "SynthLoop")
|
| 115 |
make_loop(stems['Drums'], "DrumLoop")
|
| 116 |
make_loop(stems['Bass'], "BassLoop")
|
| 117 |
make_loop(stems['Guitar'], "GuitarLoop")
|
| 118 |
make_loop(stems['Piano'], "PianoLoop")
|
| 119 |
make_loop(stems['Vocals'], "VocalChop")
|
| 120 |
|
| 121 |
+
# 3. Generate Video
|
| 122 |
video_path = None
|
| 123 |
if cover_art and created_loops['melody']:
|
| 124 |
print("Rendering Dynamic Video...")
|
|
|
|
| 129 |
# Load and Resize Image
|
| 130 |
img = ImageClip(cover_art).resize(width=1080)
|
| 131 |
|
| 132 |
+
# Simple Zoom Animation
|
|
|
|
| 133 |
img = img.resize(lambda t : 1 + 0.02*t)
|
| 134 |
img = img.set_position(('center', 'center'))
|
| 135 |
img = img.set_duration(duration)
|
|
|
|
| 159 |
|
| 160 |
|
| 161 |
# --- GUI (Blocks) ---
|
| 162 |
+
# FIXED: Removed 'theme=' argument to prevent TypeError
|
| 163 |
+
with gr.Blocks(title="Night Pulse | Command Center (6-Stem)") as app:
|
| 164 |
gr.Markdown("# 🎛️ Night Pulse | 6-Stem Command Center")
|
| 165 |
gr.Markdown("Deconstruct audio into 6 stems: Drums, Bass, Guitar, Piano, Vocals, Synths.")
|
| 166 |
|