Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -26,6 +26,14 @@ import json
|
|
26 |
# Suppress warnings
|
27 |
warnings.filterwarnings("ignore")
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
# === Helper Functions ===
|
30 |
def audiosegment_to_array(audio):
|
31 |
return np.array(audio.get_array_of_samples()), audio.frame_rate
|
@@ -33,7 +41,7 @@ def audiosegment_to_array(audio):
|
|
33 |
def array_to_audiosegment(samples, frame_rate, channels=1):
|
34 |
return AudioSegment(
|
35 |
samples.tobytes(),
|
36 |
-
frame_rate=frame_rate,
|
37 |
sample_width=samples.dtype.itemsize,
|
38 |
channels=channels
|
39 |
)
|
@@ -196,7 +204,7 @@ def ai_mastering_chain(audio_path, genre="Pop", target_lufs=-14.0):
|
|
196 |
final_audio.export(out_path, format="wav")
|
197 |
return out_path
|
198 |
|
199 |
-
# === Harmonic Saturation / Exciter β Now
|
200 |
def harmonic_saturation(audio, saturation_type="Tube", intensity=0.2):
|
201 |
samples = np.array(audio.get_array_of_samples()).astype(np.float32)
|
202 |
|
@@ -361,17 +369,9 @@ preset_choices = {
|
|
361 |
"π« ASMR Vocal": ["Auto Gain", "Low-Pass Filter (3000Hz)", "Noise Gate"],
|
362 |
"πΌ Stage Mode": ["Reverb", "Bass Boost", "Limiter"],
|
363 |
"π΅ Auto-Tune Style": ["Pitch Shift (+1 semitone)", "Normalize", "Treble Boost"],
|
364 |
-
"π· Jazz Vocal": ["Bass Boost (-200-400Hz)", "Treble Boost (-3000Hz)", "Normalize"],
|
365 |
-
"πΉ Jazz Piano": ["Treble Boost (4000-6000Hz)", "Normalize", "Stereo Widening"],
|
366 |
-
"π» Classical Strings": ["Bass Boost (100-500Hz)", "Treble Boost (3000-6000Hz)", "Reverb"],
|
367 |
-
"β Chillhop": ["Noise Gate", "Treble Boost (-3000Hz)", "Reverb"],
|
368 |
-
"π Ambient": ["Reverb", "Noise Gate", "Treble Boost (6000-12000Hz)"],
|
369 |
"π€ R&B Vocal": ["Noise Reduction", "Bass Boost (100-300Hz)", "Treble Boost (2000-4000Hz)"],
|
370 |
"π Soul Vocal": ["Noise Reduction", "Bass Boost (80-200Hz)", "Treble Boost (1500-3500Hz)"],
|
371 |
-
"πΊ Funk Groove": ["Bass Boost (80-200Hz)", "Treble Boost (1000-3000Hz)"
|
372 |
-
"πΉ Jazz Piano Solo": ["Treble Boost (2000-5000Hz)", "Normalize", "Stage Mode"],
|
373 |
-
"πΈ Trap EDM": ["Bass Boost (60-120Hz)", "Treble Boost (2000-5000Hz)", "Limiter"],
|
374 |
-
"πΈ Indie Rock": ["Bass Boost (150-400Hz)", "Treble Boost (2000-5000Hz)", "Compress Dynamic Range"]
|
375 |
}
|
376 |
|
377 |
preset_names = list(preset_choices.keys())
|
@@ -404,10 +404,25 @@ def batch_process_audio(files, selected_effects, isolate_vocals, preset_name, ex
|
|
404 |
# === Vocal Pitch Correction β Auto-Tune Style ===
|
405 |
def auto_tune_vocal(audio_path, target_key="C"):
|
406 |
try:
|
407 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
except Exception as e:
|
|
|
409 |
return None
|
410 |
|
|
|
|
|
|
|
|
|
|
|
411 |
# === Real-Time Spectrum Analyzer + Live EQ Preview ===
|
412 |
def visualize_spectrum(audio_path):
|
413 |
y, sr = torchaudio.load(audio_path)
|
@@ -472,7 +487,7 @@ with gr.Blocks(css="""
|
|
472 |
border-radius: 10px;
|
473 |
padding: 10px 20px;
|
474 |
font-weight: bold;
|
475 |
-
box-shadow: 0 0 10px #
|
476 |
border: none;
|
477 |
font-size: 16px;
|
478 |
}
|
@@ -560,7 +575,7 @@ with gr.Blocks(css="""
|
|
560 |
}
|
561 |
""") as demo:
|
562 |
|
563 |
-
# Header
|
564 |
gr.HTML('''
|
565 |
<div class="studio-header">
|
566 |
<img src="logo.png" width="400" />
|
@@ -675,7 +690,7 @@ with gr.Blocks(css="""
|
|
675 |
)
|
676 |
|
677 |
# --- Vocal Pitch Correction β Auto-Tune Style ===
|
678 |
-
with gr.Tab("
|
679 |
gr.Interface(
|
680 |
fn=auto_tune_vocal,
|
681 |
inputs=[
|
@@ -683,8 +698,9 @@ with gr.Blocks(css="""
|
|
683 |
gr.Textbox(label="Target Key", value="C", lines=1)
|
684 |
],
|
685 |
outputs=gr.Audio(label="Pitch-Corrected Output", type="filepath"),
|
686 |
-
title="Auto-Tune
|
687 |
-
description="Correct vocal pitch automatically"
|
|
|
688 |
)
|
689 |
|
690 |
# --- Frequency Spectrum Tab β Real-time Visualizer ===
|
@@ -737,8 +753,7 @@ with gr.Blocks(css="""
|
|
737 |
],
|
738 |
outputs=gr.File(label="Project File (.aiproj)"),
|
739 |
title="Save Everything Together",
|
740 |
-
description="Save your session, effects, and settings in one file to reuse later."
|
741 |
-
allow_flagging="never"
|
742 |
)
|
743 |
|
744 |
gr.Interface(
|
@@ -756,13 +771,13 @@ with gr.Blocks(css="""
|
|
756 |
with gr.Tab("π Preset Gallery"):
|
757 |
gr.Markdown("### Select a preset visually")
|
758 |
preset_gallery = gr.Gallery(value=[
|
759 |
-
("
|
760 |
-
("
|
761 |
-
("
|
762 |
-
("
|
763 |
-
("
|
764 |
-
("
|
765 |
-
("
|
766 |
], label="Preset Cards", columns=4, height="auto")
|
767 |
|
768 |
preset_name_out = gr.Dropdown(choices=preset_names, label="Selected Preset")
|
|
|
26 |
# Suppress warnings
|
27 |
warnings.filterwarnings("ignore")
|
28 |
|
29 |
+
try:
|
30 |
+
import pyrubberband as pyrb
|
31 |
+
except ImportError:
|
32 |
+
print("Installing pyrubberband...")
|
33 |
+
import subprocess
|
34 |
+
subprocess.run(["pip", "install", "pyrubberband"])
|
35 |
+
import pyrubberband as pyrb
|
36 |
+
|
37 |
# === Helper Functions ===
|
38 |
def audiosegment_to_array(audio):
|
39 |
return np.array(audio.get_array_of_samples()), audio.frame_rate
|
|
|
41 |
def array_to_audiosegment(samples, frame_rate, channels=1):
|
42 |
return AudioSegment(
|
43 |
samples.tobytes(),
|
44 |
+
frame_rate=int(frame_rate),
|
45 |
sample_width=samples.dtype.itemsize,
|
46 |
channels=channels
|
47 |
)
|
|
|
204 |
final_audio.export(out_path, format="wav")
|
205 |
return out_path
|
206 |
|
207 |
+
# === Harmonic Saturation / Exciter β Now Included ===
|
208 |
def harmonic_saturation(audio, saturation_type="Tube", intensity=0.2):
|
209 |
samples = np.array(audio.get_array_of_samples()).astype(np.float32)
|
210 |
|
|
|
369 |
"π« ASMR Vocal": ["Auto Gain", "Low-Pass Filter (3000Hz)", "Noise Gate"],
|
370 |
"πΌ Stage Mode": ["Reverb", "Bass Boost", "Limiter"],
|
371 |
"π΅ Auto-Tune Style": ["Pitch Shift (+1 semitone)", "Normalize", "Treble Boost"],
|
|
|
|
|
|
|
|
|
|
|
372 |
"π€ R&B Vocal": ["Noise Reduction", "Bass Boost (100-300Hz)", "Treble Boost (2000-4000Hz)"],
|
373 |
"π Soul Vocal": ["Noise Reduction", "Bass Boost (80-200Hz)", "Treble Boost (1500-3500Hz)"],
|
374 |
+
"πΊ Funk Groove": ["Bass Boost (80-200Hz)", "Treble Boost (1000-3000Hz)"]
|
|
|
|
|
|
|
375 |
}
|
376 |
|
377 |
preset_names = list(preset_choices.keys())
|
|
|
404 |
# === Vocal Pitch Correction β Auto-Tune Style ===
|
405 |
def auto_tune_vocal(audio_path, target_key="C"):
|
406 |
try:
|
407 |
+
# Load audio
|
408 |
+
audio = AudioSegment.from_file(audio_path)
|
409 |
+
|
410 |
+
# Apply auto-tune
|
411 |
+
semitones = key_to_semitone(target_key)
|
412 |
+
tuned_audio = apply_pitch_shift(audio, semitones)
|
413 |
+
|
414 |
+
out_path = os.path.join(tempfile.gettempdir(), "autotuned_output.wav")
|
415 |
+
tuned_audio.export(out_path, format="wav")
|
416 |
+
return out_path
|
417 |
except Exception as e:
|
418 |
+
print(f"Auto-Tune Error: {e}")
|
419 |
return None
|
420 |
|
421 |
+
def key_to_semitone(key="C"):
|
422 |
+
keys = {"C": 0, "C#": 1, "D": 2, "D#": 3, "E": 4, "F": 5,
|
423 |
+
"F#": 6, "G": 7, "G#": 8, "A": 9, "A#": 10, "B": 11}
|
424 |
+
return keys.get(key, 0)
|
425 |
+
|
426 |
# === Real-Time Spectrum Analyzer + Live EQ Preview ===
|
427 |
def visualize_spectrum(audio_path):
|
428 |
y, sr = torchaudio.load(audio_path)
|
|
|
487 |
border-radius: 10px;
|
488 |
padding: 10px 20px;
|
489 |
font-weight: bold;
|
490 |
+
box-shadow: 0 0 10px #2563eb44;
|
491 |
border: none;
|
492 |
font-size: 16px;
|
493 |
}
|
|
|
575 |
}
|
576 |
""") as demo:
|
577 |
|
578 |
+
# Header with logo and tagline
|
579 |
gr.HTML('''
|
580 |
<div class="studio-header">
|
581 |
<img src="logo.png" width="400" />
|
|
|
690 |
)
|
691 |
|
692 |
# --- Vocal Pitch Correction β Auto-Tune Style ===
|
693 |
+
with gr.Tab("π€ AI Auto-Tune"):
|
694 |
gr.Interface(
|
695 |
fn=auto_tune_vocal,
|
696 |
inputs=[
|
|
|
698 |
gr.Textbox(label="Target Key", value="C", lines=1)
|
699 |
],
|
700 |
outputs=gr.Audio(label="Pitch-Corrected Output", type="filepath"),
|
701 |
+
title="AI Auto-Tune",
|
702 |
+
description="Correct vocal pitch automatically using AI",
|
703 |
+
allow_flagging="never"
|
704 |
)
|
705 |
|
706 |
# --- Frequency Spectrum Tab β Real-time Visualizer ===
|
|
|
753 |
],
|
754 |
outputs=gr.File(label="Project File (.aiproj)"),
|
755 |
title="Save Everything Together",
|
756 |
+
description="Save your session, effects, and settings in one file to reuse later."
|
|
|
757 |
)
|
758 |
|
759 |
gr.Interface(
|
|
|
771 |
with gr.Tab("π Preset Gallery"):
|
772 |
gr.Markdown("### Select a preset visually")
|
773 |
preset_gallery = gr.Gallery(value=[
|
774 |
+
("https://picsum.photos/id/10/150/100", "Pop"),
|
775 |
+
("https://picsum.photos/id/20/150/100", "EDM"),
|
776 |
+
("https://picsum.photos/id/30/150/100", "Rock"),
|
777 |
+
("https://picsum.photos/id/40/150/100", "Hip-Hop"),
|
778 |
+
("https://picsum.photos/id/50/150/100", "R&B"),
|
779 |
+
("https://picsum.photos/id/60/150/100", "Soul"),
|
780 |
+
("https://picsum.photos/id/70/150/100", "Funk")
|
781 |
], label="Preset Cards", columns=4, height="auto")
|
782 |
|
783 |
preset_name_out = gr.Dropdown(choices=preset_names, label="Selected Preset")
|