Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,9 @@ from demucs import pretrained
|
|
10 |
from demucs.apply import apply_model
|
11 |
import torchaudio
|
12 |
from pathlib import Path
|
|
|
|
|
|
|
13 |
|
14 |
# === Helper Functions ===
|
15 |
def audiosegment_to_array(audio):
|
@@ -95,7 +98,7 @@ def apply_vocal_isolation(audio_path):
|
|
95 |
save_track(out_path, vocal_track, model.samplerate)
|
96 |
return out_path
|
97 |
|
98 |
-
# === Preset Loader ===
|
99 |
def load_presets():
|
100 |
try:
|
101 |
preset_files = [f for f in os.listdir("presets") if f.endswith(".json")]
|
@@ -116,15 +119,35 @@ def load_presets():
|
|
116 |
print("Presets folder not found")
|
117 |
return {}
|
118 |
|
119 |
-
# Always define preset_choices, even if empty
|
120 |
preset_choices = load_presets()
|
121 |
|
122 |
-
# Provide fallback if no presets found
|
123 |
if not preset_choices:
|
124 |
-
preset_choices = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
# === Main Processing Function ===
|
127 |
-
def process_audio(audio_file, selected_effects, isolate_vocals, preset_name):
|
128 |
audio = AudioSegment.from_file(audio_file)
|
129 |
|
130 |
effect_map = {
|
@@ -139,7 +162,6 @@ def process_audio(audio_file, selected_effects, isolate_vocals, preset_name):
|
|
139 |
"Normalize": apply_normalize,
|
140 |
}
|
141 |
|
142 |
-
# Apply selected preset or custom effects
|
143 |
effects_to_apply = preset_choices.get(preset_name, selected_effects)
|
144 |
for effect_name in effects_to_apply:
|
145 |
if effect_name in effect_map:
|
@@ -155,8 +177,8 @@ def process_audio(audio_file, selected_effects, isolate_vocals, preset_name):
|
|
155 |
final_audio = audio
|
156 |
|
157 |
output_path = f.name
|
158 |
-
final_audio.export(output_path, format=
|
159 |
-
return output_path
|
160 |
|
161 |
# === Gradio Interface ===
|
162 |
effect_options = [
|
@@ -171,19 +193,21 @@ effect_options = [
|
|
171 |
"Normalize"
|
172 |
]
|
173 |
|
174 |
-
preset_names = list(preset_choices.keys())
|
175 |
-
|
176 |
interface = gr.Interface(
|
177 |
fn=process_audio,
|
178 |
inputs=[
|
179 |
gr.Audio(label="Upload Audio", type="filepath"),
|
180 |
gr.CheckboxGroup(choices=effect_options, label="Apply Effects in Order"),
|
181 |
gr.Checkbox(label="Isolate Vocals After Effects"),
|
182 |
-
gr.Dropdown(choices=preset_names, label="Select Preset", value=preset_names[0] if preset_names else None)
|
|
|
|
|
|
|
|
|
|
|
183 |
],
|
184 |
-
outputs=gr.Audio(label="Processed Audio (MP3)", type="filepath"),
|
185 |
title="AI Audio Studio - Pro Edition",
|
186 |
-
description="Apply multiple effects, isolate vocals, and export polished tracks
|
187 |
allow_flagging="never"
|
188 |
)
|
189 |
|
|
|
10 |
from demucs.apply import apply_model
|
11 |
import torchaudio
|
12 |
from pathlib import Path
|
13 |
+
import matplotlib.pyplot as plt
|
14 |
+
from io import BytesIO
|
15 |
+
from PIL import Image
|
16 |
|
17 |
# === Helper Functions ===
|
18 |
def audiosegment_to_array(audio):
|
|
|
98 |
save_track(out_path, vocal_track, model.samplerate)
|
99 |
return out_path
|
100 |
|
101 |
+
# === Preset Loader with Fallback ===
|
102 |
def load_presets():
|
103 |
try:
|
104 |
preset_files = [f for f in os.listdir("presets") if f.endswith(".json")]
|
|
|
119 |
print("Presets folder not found")
|
120 |
return {}
|
121 |
|
|
|
122 |
preset_choices = load_presets()
|
123 |
|
|
|
124 |
if not preset_choices:
|
125 |
+
preset_choices = {
|
126 |
+
"Default": [],
|
127 |
+
"Clean Podcast": ["Noise Reduction", "Normalize"],
|
128 |
+
"Music Remix": ["Bass Boost", "Stereo Widening"]
|
129 |
+
}
|
130 |
+
|
131 |
+
preset_names = list(preset_choices.keys())
|
132 |
+
|
133 |
+
# === Waveform Generator ===
|
134 |
+
def show_waveform(audio_file):
|
135 |
+
try:
|
136 |
+
audio = AudioSegment.from_file(audio_file)
|
137 |
+
samples = np.array(audio.get_array_of_samples())
|
138 |
+
plt.figure(figsize=(10, 2))
|
139 |
+
plt.plot(samples[:10000], color="blue")
|
140 |
+
plt.axis("off")
|
141 |
+
buf = BytesIO()
|
142 |
+
plt.savefig(buf, format="png", bbox_inches="tight", dpi=100)
|
143 |
+
plt.close()
|
144 |
+
buf.seek(0)
|
145 |
+
return Image.open(buf)
|
146 |
+
except Exception as e:
|
147 |
+
return None
|
148 |
|
149 |
# === Main Processing Function ===
|
150 |
+
def process_audio(audio_file, selected_effects, isolate_vocals, preset_name, export_format):
|
151 |
audio = AudioSegment.from_file(audio_file)
|
152 |
|
153 |
effect_map = {
|
|
|
162 |
"Normalize": apply_normalize,
|
163 |
}
|
164 |
|
|
|
165 |
effects_to_apply = preset_choices.get(preset_name, selected_effects)
|
166 |
for effect_name in effects_to_apply:
|
167 |
if effect_name in effect_map:
|
|
|
177 |
final_audio = audio
|
178 |
|
179 |
output_path = f.name
|
180 |
+
final_audio.export(output_path, format=export_format.lower())
|
181 |
+
return output_path, show_waveform(output_path)
|
182 |
|
183 |
# === Gradio Interface ===
|
184 |
effect_options = [
|
|
|
193 |
"Normalize"
|
194 |
]
|
195 |
|
|
|
|
|
196 |
interface = gr.Interface(
|
197 |
fn=process_audio,
|
198 |
inputs=[
|
199 |
gr.Audio(label="Upload Audio", type="filepath"),
|
200 |
gr.CheckboxGroup(choices=effect_options, label="Apply Effects in Order"),
|
201 |
gr.Checkbox(label="Isolate Vocals After Effects"),
|
202 |
+
gr.Dropdown(choices=preset_names, label="Select Preset", value=preset_names[0] if preset_names else None),
|
203 |
+
gr.Dropdown(choices=["MP3", "WAV"], label="Export Format", value="MP3")
|
204 |
+
],
|
205 |
+
outputs=[
|
206 |
+
gr.Audio(label="Processed Audio", type="filepath"),
|
207 |
+
gr.Image(label="Waveform Preview")
|
208 |
],
|
|
|
209 |
title="AI Audio Studio - Pro Edition",
|
210 |
+
description="Apply multiple effects, isolate vocals, and export polished tracks — all powered by AI!",
|
211 |
allow_flagging="never"
|
212 |
)
|
213 |
|