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")
|