Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -607,235 +607,235 @@ harmony_btn.click(
|
|
| 607 |
)
|
| 608 |
|
| 609 |
# --- Batch Processing ---
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
# --- AI Auto-Tune ---
|
| 627 |
-
with gr.Tab("π€ AI Auto-Tune"):
|
| 628 |
-
auto_tune_file = gr.File(label="Source Voice Clip")
|
| 629 |
-
auto_tune_key = gr.Textbox(label="Target Key", value="C", lines=1)
|
| 630 |
-
auto_tune_output = gr.Audio(label="Pitch-Corrected Output", type="filepath")
|
| 631 |
-
auto_tune_btn = gr.Button("Auto-Tune")
|
| 632 |
-
|
| 633 |
-
auto_tune_btn.click(
|
| 634 |
-
fn=auto_tune_vocal,
|
| 635 |
-
inputs=[auto_tune_file, auto_tune_key],
|
| 636 |
-
outputs=auto_tune_output
|
| 637 |
-
)
|
| 638 |
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 644 |
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
loudness_btn = gr.Button("Match Loudness")
|
| 657 |
-
|
| 658 |
-
loudness_btn.click(
|
| 659 |
-
fn=match_loudness,
|
| 660 |
-
inputs=[loudness_input, loudness_target],
|
| 661 |
-
outputs=loudness_output
|
| 662 |
-
)
|
| 663 |
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
loaded_effects_out = gr.CheckboxGroup(choices=preset_choices["Default"], label="Loaded Effects")
|
| 677 |
-
load_proj_btn = gr.Button("Load Project")
|
| 678 |
-
|
| 679 |
-
save_proj_btn.click(
|
| 680 |
-
fn=save_project,
|
| 681 |
-
inputs=[project_audio_file, project_preset, project_effects],
|
| 682 |
-
outputs=project_file_out
|
| 683 |
-
)
|
| 684 |
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
| 689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
prompt_btn = gr.Button("Process Prompt")
|
| 697 |
-
|
| 698 |
-
prompt_btn.click(
|
| 699 |
-
fn=process_prompt,
|
| 700 |
-
inputs=[prompt_audio, prompt_text],
|
| 701 |
-
outputs=prompt_output
|
| 702 |
-
)
|
| 703 |
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
)
|
| 717 |
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
|
| 731 |
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
)
|
| 746 |
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 752 |
|
| 753 |
-
|
| 754 |
-
|
| 755 |
-
|
| 756 |
-
|
| 757 |
-
|
| 758 |
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
|
| 763 |
-
|
| 764 |
-
def load_shared_code(code_str):
|
| 765 |
-
try:
|
| 766 |
-
return json.loads(code_str)
|
| 767 |
-
except Exception:
|
| 768 |
-
return []
|
| 769 |
-
|
| 770 |
-
load_code_btn.click(
|
| 771 |
-
fn=load_shared_code,
|
| 772 |
-
inputs=load_code,
|
| 773 |
-
outputs=loaded_effects
|
| 774 |
-
)
|
| 775 |
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
|
| 791 |
-
|
| 792 |
-
formant_shift = gr.Slider(minimum=-2, maximum=2, value=1.0, step=0.1, label="Formant Shift")
|
| 793 |
-
formant_output = gr.Audio(label="Natural-Sounding Vocal", type="filepath")
|
| 794 |
-
formant_btn = gr.Button("Apply Correction")
|
| 795 |
-
|
| 796 |
-
formant_btn.click(
|
| 797 |
-
fn=formant_correct,
|
| 798 |
-
inputs=[formant_audio, formant_shift],
|
| 799 |
-
outputs=formant_output
|
| 800 |
-
)
|
| 801 |
|
| 802 |
-
|
| 803 |
-
|
| 804 |
-
|
| 805 |
-
|
| 806 |
-
|
| 807 |
-
|
| 808 |
-
|
| 809 |
-
|
| 810 |
-
|
| 811 |
-
|
| 812 |
-
|
| 813 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 814 |
|
| 815 |
-
|
| 816 |
-
|
| 817 |
-
|
| 818 |
-
|
| 819 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 820 |
|
| 821 |
-
|
| 822 |
-
|
| 823 |
-
|
| 824 |
-
|
| 825 |
-
|
| 826 |
|
| 827 |
-
|
| 828 |
-
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 839 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 840 |
|
| 841 |
demo.launch()
|
|
|
|
| 607 |
)
|
| 608 |
|
| 609 |
# --- Batch Processing ---
|
| 610 |
+
# --- Batch Processing ---
|
| 611 |
+
with gr.Tab("π Batch Processing"):
|
| 612 |
+
batch_files = gr.File(label="Upload Multiple Files", file_count="multiple")
|
| 613 |
+
batch_effects = gr.CheckboxGroup(choices=preset_choices["Default"], label="Apply Effects in Order")
|
| 614 |
+
batch_isolate = gr.Checkbox(label="Isolate Vocals After Effects")
|
| 615 |
+
batch_preset_dropdown = gr.Dropdown(choices=preset_names, label="Select Preset", value=preset_names[0])
|
| 616 |
+
batch_export_format = gr.Dropdown(choices=["MP3", "WAV"], label="Export Format", value="MP3")
|
| 617 |
+
batch_process_btn = gr.Button("Process All Files")
|
| 618 |
+
batch_download = gr.File(label="Download ZIP of All Processed Files")
|
| 619 |
+
batch_status = gr.Textbox(label="Status", value="Ready", interactive=False)
|
| 620 |
+
|
| 621 |
+
batch_process_btn.click(
|
| 622 |
+
fn=batch_process_audio,
|
| 623 |
+
inputs=[batch_files, batch_effects, batch_isolate, batch_preset_dropdown, batch_export_format],
|
| 624 |
+
outputs=[batch_download, batch_status]
|
| 625 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 626 |
|
| 627 |
+
# --- AI Auto-Tune ---
|
| 628 |
+
with gr.Tab("π€ AI Auto-Tune"):
|
| 629 |
+
auto_tune_file = gr.File(label="Source Voice Clip")
|
| 630 |
+
auto_tune_key = gr.Textbox(label="Target Key", value="C", lines=1)
|
| 631 |
+
auto_tune_output = gr.Audio(label="Pitch-Corrected Output", type="filepath")
|
| 632 |
+
auto_tune_btn = gr.Button("Auto-Tune")
|
| 633 |
+
|
| 634 |
+
auto_tune_btn.click(
|
| 635 |
+
fn=auto_tune_vocal,
|
| 636 |
+
inputs=[auto_tune_file, auto_tune_key],
|
| 637 |
+
outputs=auto_tune_output
|
| 638 |
+
)
|
| 639 |
|
| 640 |
+
# --- Frequency Spectrum ---
|
| 641 |
+
with gr.Tab("π Frequency Spectrum"):
|
| 642 |
+
spectrum_input = gr.Audio(label="Upload Track", type="filepath")
|
| 643 |
+
spectrum_output = gr.Image(label="Spectrum Analysis")
|
| 644 |
+
spectrum_btn = gr.Button("Visualize Spectrum")
|
| 645 |
|
| 646 |
+
spectrum_btn.click(
|
| 647 |
+
fn=visualize_spectrum,
|
| 648 |
+
inputs=spectrum_input,
|
| 649 |
+
outputs=spectrum_output
|
| 650 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 651 |
|
| 652 |
+
# --- Loudness Graph ---
|
| 653 |
+
with gr.Tab("π Loudness Graph"):
|
| 654 |
+
loudness_input = gr.Audio(label="Upload Track", type="filepath")
|
| 655 |
+
loudness_target = gr.Slider(minimum=-24, maximum=-6, value=-14, step=0.5, label="Target LUFS")
|
| 656 |
+
loudness_output = gr.Audio(label="Normalized Output", type="filepath")
|
| 657 |
+
loudness_btn = gr.Button("Match Loudness")
|
| 658 |
+
|
| 659 |
+
loudness_btn.click(
|
| 660 |
+
fn=match_loudness,
|
| 661 |
+
inputs=[loudness_input, loudness_target],
|
| 662 |
+
outputs=loudness_output
|
| 663 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 664 |
|
| 665 |
+
# --- Save/Load Project ---
|
| 666 |
+
with gr.Tab("π Save/Load Project"):
|
| 667 |
+
with gr.Row():
|
| 668 |
+
with gr.Column(min_width=300):
|
| 669 |
+
project_audio_file = gr.File(label="Original Audio")
|
| 670 |
+
project_preset = gr.Dropdown(choices=preset_names, label="Used Preset", value=preset_names[0])
|
| 671 |
+
project_effects = gr.CheckboxGroup(choices=preset_choices["Default"], label="Applied Effects")
|
| 672 |
+
save_proj_btn = gr.Button("Save Project")
|
| 673 |
+
project_file_out = gr.File(label="Project File (.aiproj)")
|
| 674 |
+
with gr.Column(min_width=300):
|
| 675 |
+
load_proj_file = gr.File(label="Upload .aiproj File")
|
| 676 |
+
loaded_preset_out = gr.Dropdown(choices=preset_names, label="Loaded Preset")
|
| 677 |
+
loaded_effects_out = gr.CheckboxGroup(choices=preset_choices["Default"], label="Loaded Effects")
|
| 678 |
+
load_proj_btn = gr.Button("Load Project")
|
| 679 |
+
|
| 680 |
+
save_proj_btn.click(
|
| 681 |
+
fn=save_project,
|
| 682 |
+
inputs=[project_audio_file, project_preset, project_effects],
|
| 683 |
+
outputs=project_file_out
|
| 684 |
+
)
|
| 685 |
|
| 686 |
+
load_proj_btn.click(
|
| 687 |
+
fn=load_project,
|
| 688 |
+
inputs=load_proj_file,
|
| 689 |
+
outputs=[loaded_preset_out, loaded_effects_out]
|
| 690 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 691 |
|
| 692 |
+
# --- Prompt-Based Editing ---
|
| 693 |
+
with gr.Tab("π§ Prompt-Based Editing"):
|
| 694 |
+
prompt_audio = gr.File(label="Upload Audio", type="filepath")
|
| 695 |
+
prompt_text = gr.Textbox(label="Describe What You Want", lines=5)
|
| 696 |
+
prompt_output = gr.Audio(label="Edited Output", type="filepath")
|
| 697 |
+
prompt_btn = gr.Button("Process Prompt")
|
| 698 |
+
|
| 699 |
+
prompt_btn.click(
|
| 700 |
+
fn=process_prompt,
|
| 701 |
+
inputs=[prompt_audio, prompt_text],
|
| 702 |
+
outputs=prompt_output
|
| 703 |
+
)
|
|
|
|
| 704 |
|
| 705 |
+
# --- Custom EQ Editor ---
|
| 706 |
+
with gr.Tab("π Custom EQ Editor"):
|
| 707 |
+
eq_audio = gr.Audio(label="Upload Track", type="filepath")
|
| 708 |
+
genre_list = list(preset_choices.keys())
|
| 709 |
+
eq_genre = gr.Dropdown(choices=genre_list, value="Pop", label="Genre")
|
| 710 |
+
eq_output = gr.Audio(label="EQ-Enhanced Output", type="filepath")
|
| 711 |
+
eq_btn = gr.Button("Apply EQ")
|
| 712 |
+
|
| 713 |
+
eq_btn.click(
|
| 714 |
+
fn=lambda audio_path, genre: auto_eq(AudioSegment.from_file(audio_path), genre),
|
| 715 |
+
inputs=[eq_audio, eq_genre],
|
| 716 |
+
outputs=eq_output
|
| 717 |
+
)
|
| 718 |
|
| 719 |
+
# --- A/B Compare ---
|
| 720 |
+
with gr.Tab("π― A/B Compare"):
|
| 721 |
+
ab_track1 = gr.Audio(label="Version A", type="filepath")
|
| 722 |
+
ab_track2 = gr.Audio(label="Version B", type="filepath")
|
| 723 |
+
ab_out1 = gr.Audio(label="Version A", type="filepath")
|
| 724 |
+
ab_out2 = gr.Audio(label="Version B", type="filepath")
|
| 725 |
+
ab_btn = gr.Button("Compare")
|
| 726 |
+
|
| 727 |
+
ab_btn.click(
|
| 728 |
+
fn=compare_ab,
|
| 729 |
+
inputs=[ab_track1, ab_track2],
|
| 730 |
+
outputs=[ab_out1, ab_out2]
|
| 731 |
+
)
|
|
|
|
| 732 |
|
| 733 |
+
# --- Loop Playback ---
|
| 734 |
+
with gr.Tab("π Loop Playback"):
|
| 735 |
+
loop_audio = gr.Audio(label="Upload Track", type="filepath")
|
| 736 |
+
loop_start = gr.Slider(minimum=0, maximum=30000, step=100, value=5000, label="Start MS")
|
| 737 |
+
loop_end = gr.Slider(minimum=100, maximum=30000, step=100, value=10000, label="End MS")
|
| 738 |
+
loop_repeats = gr.Slider(minimum=1, maximum=10, value=2, label="Repeat Loops")
|
| 739 |
+
loop_output = gr.Audio(label="Looped Output", type="filepath")
|
| 740 |
+
loop_btn = gr.Button("Loop Section")
|
| 741 |
+
|
| 742 |
+
loop_btn.click(
|
| 743 |
+
fn=loop_section,
|
| 744 |
+
inputs=[loop_audio, loop_start, loop_end, loop_repeats],
|
| 745 |
+
outputs=loop_output
|
| 746 |
+
)
|
| 747 |
|
| 748 |
+
# --- Share Effect Chain ---
|
| 749 |
+
with gr.Tab("π Share Effect Chain"):
|
| 750 |
+
share_effects = gr.CheckboxGroup(choices=preset_choices["Default"], label="Select Effects")
|
| 751 |
+
share_code = gr.Textbox(label="Share Code", lines=2)
|
| 752 |
+
share_btn = gr.Button("Generate Share Code")
|
| 753 |
|
| 754 |
+
share_btn.click(
|
| 755 |
+
fn=lambda x: json.dumps(x),
|
| 756 |
+
inputs=share_effects,
|
| 757 |
+
outputs=share_code
|
| 758 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 759 |
|
| 760 |
+
with gr.Tab("π₯ Load Shared Chain"):
|
| 761 |
+
load_code = gr.Textbox(label="Paste Shared Code", lines=2)
|
| 762 |
+
loaded_effects = gr.CheckboxGroup(choices=preset_choices["Default"], label="Loaded Effects")
|
| 763 |
+
load_code_btn = gr.Button("Load Effects")
|
| 764 |
+
|
| 765 |
+
def load_shared_code(code_str):
|
| 766 |
+
try:
|
| 767 |
+
return json.loads(code_str)
|
| 768 |
+
except Exception:
|
| 769 |
+
return []
|
| 770 |
+
|
| 771 |
+
load_code_btn.click(
|
| 772 |
+
fn=load_shared_code,
|
| 773 |
+
inputs=load_code,
|
| 774 |
+
outputs=loaded_effects
|
| 775 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 776 |
|
| 777 |
+
# --- Keyboard Shortcuts ---
|
| 778 |
+
with gr.Tab("β¨ Keyboard Shortcuts"):
|
| 779 |
+
gr.Markdown("""
|
| 780 |
+
### Keyboard Controls
|
| 781 |
+
- `Ctrl + Z`: Undo last effect
|
| 782 |
+
- `Ctrl + Y`: Redo
|
| 783 |
+
- `Spacebar`: Play/Stop playback
|
| 784 |
+
- `Ctrl + S`: Save current session
|
| 785 |
+
- `Ctrl + O`: Open session
|
| 786 |
+
- `Ctrl + C`: Copy effect chain
|
| 787 |
+
- `Ctrl + V`: Paste effect chain
|
| 788 |
+
""")
|
| 789 |
+
|
| 790 |
+
# --- Vocal Formant Correction ---
|
| 791 |
+
with gr.Tab("π§βπ€ Vocal Formant Correction"):
|
| 792 |
+
formant_audio = gr.Audio(label="Upload Vocal Track", type="filepath")
|
| 793 |
+
formant_shift = gr.Slider(minimum=-2, maximum=2, value=1.0, step=0.1, label="Formant Shift")
|
| 794 |
+
formant_output = gr.Audio(label="Natural-Sounding Vocal", type="filepath")
|
| 795 |
+
formant_btn = gr.Button("Apply Correction")
|
| 796 |
+
|
| 797 |
+
formant_btn.click(
|
| 798 |
+
fn=formant_correct,
|
| 799 |
+
inputs=[formant_audio, formant_shift],
|
| 800 |
+
outputs=formant_output
|
| 801 |
+
)
|
| 802 |
|
| 803 |
+
# --- Voice Swap / Cloning ---
|
| 804 |
+
with gr.Tab("π Voice Swap / Cloning"):
|
| 805 |
+
source_voice = gr.File(label="Source Voice Clip")
|
| 806 |
+
reference_voice = gr.File(label="Reference Voice")
|
| 807 |
+
clone_output = gr.Audio(label="Converted Output", type="filepath")
|
| 808 |
+
clone_btn = gr.Button("Clone Voice")
|
| 809 |
+
|
| 810 |
+
clone_btn.click(
|
| 811 |
+
fn=clone_voice,
|
| 812 |
+
inputs=[source_voice, reference_voice],
|
| 813 |
+
outputs=clone_output
|
| 814 |
+
)
|
| 815 |
|
| 816 |
+
# --- DAW Template Export ---
|
| 817 |
+
with gr.Tab("π DAW Template Export"):
|
| 818 |
+
daw_stems = gr.File(label="Upload Stems", file_count="multiple")
|
| 819 |
+
daw_output = gr.File(label="DAW Template (.json/.als/.flp)")
|
| 820 |
+
daw_btn = gr.Button("Generate Template")
|
| 821 |
|
| 822 |
+
daw_btn.click(
|
| 823 |
+
fn=generate_ableton_template,
|
| 824 |
+
inputs=daw_stems,
|
| 825 |
+
outputs=daw_output
|
| 826 |
+
)
|
| 827 |
+
|
| 828 |
+
# --- Export Full Mix ZIP ---
|
| 829 |
+
with gr.Tab("π Export Full Mix ZIP"):
|
| 830 |
+
stems_files = gr.File(label="Stems", file_count="multiple")
|
| 831 |
+
final_mix_file = gr.File(label="Final Mix")
|
| 832 |
+
full_zip_output = gr.File(label="Full Mix Archive (.zip)")
|
| 833 |
+
export_zip_btn = gr.Button("Export ZIP")
|
| 834 |
+
|
| 835 |
+
export_zip_btn.click(
|
| 836 |
+
fn=export_full_mix,
|
| 837 |
+
inputs=[stems_files, final_mix_file],
|
| 838 |
+
outputs=full_zip_output
|
| 839 |
+
)
|
| 840 |
|
| 841 |
demo.launch()
|