Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,6 +4,8 @@ import torch.nn.functional as F
|
|
| 4 |
import librosa
|
| 5 |
import soundfile as sf
|
| 6 |
import numpy as np
|
|
|
|
|
|
|
| 7 |
from huggingface_hub import hf_hub_download
|
| 8 |
|
| 9 |
# ================= MODEL (unchanged) =================
|
|
@@ -41,9 +43,10 @@ def load_model():
|
|
| 41 |
|
| 42 |
model = load_model()
|
| 43 |
|
|
|
|
| 44 |
def separate_audio(path):
|
| 45 |
if not path:
|
| 46 |
-
return [None]*
|
| 47 |
|
| 48 |
mix, sr = librosa.load(path, sr=44100, mono=False)
|
| 49 |
if mix.ndim == 1:
|
|
@@ -69,14 +72,28 @@ def separate_audio(path):
|
|
| 69 |
cnt[:,:,:,s:e] += 1
|
| 70 |
|
| 71 |
stems = (out / cnt.clamp(min=1)).cpu().numpy()[0]
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
css = """
|
| 81 |
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Poppins:wght@400;500;600&display=swap');
|
| 82 |
|
|
@@ -94,7 +111,6 @@ css = """
|
|
| 94 |
html, body, .gradio-container {
|
| 95 |
height: 100%;
|
| 96 |
margin: 0;
|
| 97 |
-
padding: 0;
|
| 98 |
background: linear-gradient(180deg, var(--bg1), var(--bg2)) !important;
|
| 99 |
color: var(--ink);
|
| 100 |
font-family: Poppins, sans-serif;
|
|
@@ -112,7 +128,7 @@ html, body, .gradio-container {
|
|
| 112 |
|
| 113 |
/* brand */
|
| 114 |
.brand { display:flex; flex-direction:column; gap:6px; }
|
| 115 |
-
.logo { font-family: Anton, sans-serif; font-size:46px;
|
| 116 |
.tagline { font-size:14px; color:var(--accent); opacity:0.9; }
|
| 117 |
|
| 118 |
/* layout */
|
|
@@ -130,7 +146,6 @@ html, body, .gradio-container {
|
|
| 130 |
.left .gradio-audio {
|
| 131 |
background: var(--panel) !important;
|
| 132 |
border-radius: var(--radius);
|
| 133 |
-
border: 1px solid rgba(255,255,255,0.04);
|
| 134 |
min-height: 260px;
|
| 135 |
display:flex;
|
| 136 |
align-items:center;
|
|
@@ -171,34 +186,25 @@ html, body, .gradio-container {
|
|
| 171 |
font-size:13px;
|
| 172 |
font-weight:600;
|
| 173 |
color: var(--accent);
|
| 174 |
-
letter-spacing: 0.3px;
|
| 175 |
}
|
| 176 |
|
| 177 |
.stem-info {
|
| 178 |
font-size:11px;
|
| 179 |
color:var(--muted);
|
| 180 |
-
line-height:1.35;
|
| 181 |
opacity:0.85;
|
| 182 |
}
|
| 183 |
|
| 184 |
.stem-surface .gradio-audio label { display:none !important; }
|
| 185 |
.stem-surface audio { width:92%; max-height:36px; }
|
| 186 |
-
|
| 187 |
-
@media (max-width: 980px) {
|
| 188 |
-
.main { grid-template-columns: 1fr; }
|
| 189 |
-
.stems { grid-template-columns: 1fr 1fr; }
|
| 190 |
-
}
|
| 191 |
"""
|
| 192 |
|
| 193 |
with gr.Blocks() as demo:
|
| 194 |
with gr.Column(elem_classes="app"):
|
| 195 |
|
| 196 |
-
# Brand
|
| 197 |
with gr.Row(elem_classes="brand"):
|
| 198 |
gr.HTML('<div class="logo">SWARA STUDIO</div>')
|
| 199 |
gr.HTML('<div class="tagline">Separating Music Into Its elements</div>')
|
| 200 |
|
| 201 |
-
# Main
|
| 202 |
with gr.Row(elem_classes="main"):
|
| 203 |
# LEFT
|
| 204 |
with gr.Column(elem_classes="left"):
|
|
@@ -208,6 +214,7 @@ with gr.Blocks() as demo:
|
|
| 208 |
""")
|
| 209 |
input_audio = gr.Audio(type="filepath")
|
| 210 |
run_btn = gr.Button("Separate", elem_classes="button-primary")
|
|
|
|
| 211 |
|
| 212 |
# RIGHT
|
| 213 |
with gr.Column():
|
|
@@ -241,7 +248,11 @@ with gr.Blocks() as demo:
|
|
| 241 |
""")
|
| 242 |
out_other = gr.Audio(interactive=False)
|
| 243 |
|
| 244 |
-
run_btn.click(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
|
| 246 |
if __name__ == "__main__":
|
| 247 |
demo.launch(css=css, theme=gr.themes.Base())
|
|
|
|
| 4 |
import librosa
|
| 5 |
import soundfile as sf
|
| 6 |
import numpy as np
|
| 7 |
+
import zipfile
|
| 8 |
+
import os
|
| 9 |
from huggingface_hub import hf_hub_download
|
| 10 |
|
| 11 |
# ================= MODEL (unchanged) =================
|
|
|
|
| 43 |
|
| 44 |
model = load_model()
|
| 45 |
|
| 46 |
+
# ================= SEPARATION + ZIP =================
|
| 47 |
def separate_audio(path):
|
| 48 |
if not path:
|
| 49 |
+
return [None]*5
|
| 50 |
|
| 51 |
mix, sr = librosa.load(path, sr=44100, mono=False)
|
| 52 |
if mix.ndim == 1:
|
|
|
|
| 72 |
cnt[:,:,:,s:e] += 1
|
| 73 |
|
| 74 |
stems = (out / cnt.clamp(min=1)).cpu().numpy()[0]
|
| 75 |
+
|
| 76 |
+
stem_files = []
|
| 77 |
+
names = [
|
| 78 |
+
"lead_vocals.wav",
|
| 79 |
+
"mridangam_percussion.wav",
|
| 80 |
+
"tanpura_drone.wav",
|
| 81 |
+
"violin_accompaniment.wav"
|
| 82 |
+
]
|
| 83 |
+
|
| 84 |
+
for i, name in enumerate(names):
|
| 85 |
+
sf.write(name, stems[i].T, sr)
|
| 86 |
+
stem_files.append(name)
|
| 87 |
+
|
| 88 |
+
# Create ZIP
|
| 89 |
+
zip_path = "stems.zip"
|
| 90 |
+
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as z:
|
| 91 |
+
for f in stem_files:
|
| 92 |
+
z.write(f)
|
| 93 |
+
|
| 94 |
+
return [stem_files[0], stem_files[1], stem_files[2], stem_files[3], zip_path]
|
| 95 |
+
|
| 96 |
+
# ================= UI (UNCHANGED VISUALLY) =================
|
| 97 |
css = """
|
| 98 |
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Poppins:wght@400;500;600&display=swap');
|
| 99 |
|
|
|
|
| 111 |
html, body, .gradio-container {
|
| 112 |
height: 100%;
|
| 113 |
margin: 0;
|
|
|
|
| 114 |
background: linear-gradient(180deg, var(--bg1), var(--bg2)) !important;
|
| 115 |
color: var(--ink);
|
| 116 |
font-family: Poppins, sans-serif;
|
|
|
|
| 128 |
|
| 129 |
/* brand */
|
| 130 |
.brand { display:flex; flex-direction:column; gap:6px; }
|
| 131 |
+
.logo { font-family: Anton, sans-serif; font-size:46px; }
|
| 132 |
.tagline { font-size:14px; color:var(--accent); opacity:0.9; }
|
| 133 |
|
| 134 |
/* layout */
|
|
|
|
| 146 |
.left .gradio-audio {
|
| 147 |
background: var(--panel) !important;
|
| 148 |
border-radius: var(--radius);
|
|
|
|
| 149 |
min-height: 260px;
|
| 150 |
display:flex;
|
| 151 |
align-items:center;
|
|
|
|
| 186 |
font-size:13px;
|
| 187 |
font-weight:600;
|
| 188 |
color: var(--accent);
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
.stem-info {
|
| 192 |
font-size:11px;
|
| 193 |
color:var(--muted);
|
|
|
|
| 194 |
opacity:0.85;
|
| 195 |
}
|
| 196 |
|
| 197 |
.stem-surface .gradio-audio label { display:none !important; }
|
| 198 |
.stem-surface audio { width:92%; max-height:36px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
"""
|
| 200 |
|
| 201 |
with gr.Blocks() as demo:
|
| 202 |
with gr.Column(elem_classes="app"):
|
| 203 |
|
|
|
|
| 204 |
with gr.Row(elem_classes="brand"):
|
| 205 |
gr.HTML('<div class="logo">SWARA STUDIO</div>')
|
| 206 |
gr.HTML('<div class="tagline">Separating Music Into Its elements</div>')
|
| 207 |
|
|
|
|
| 208 |
with gr.Row(elem_classes="main"):
|
| 209 |
# LEFT
|
| 210 |
with gr.Column(elem_classes="left"):
|
|
|
|
| 214 |
""")
|
| 215 |
input_audio = gr.Audio(type="filepath")
|
| 216 |
run_btn = gr.Button("Separate", elem_classes="button-primary")
|
| 217 |
+
zip_out = gr.File(label="Download all stems", interactive=False)
|
| 218 |
|
| 219 |
# RIGHT
|
| 220 |
with gr.Column():
|
|
|
|
| 248 |
""")
|
| 249 |
out_other = gr.Audio(interactive=False)
|
| 250 |
|
| 251 |
+
run_btn.click(
|
| 252 |
+
separate_audio,
|
| 253 |
+
input_audio,
|
| 254 |
+
[out_vocals, out_drums, out_bass, out_other, zip_out]
|
| 255 |
+
)
|
| 256 |
|
| 257 |
if __name__ == "__main__":
|
| 258 |
demo.launch(css=css, theme=gr.themes.Base())
|