Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
def apply_audacity_fixes(sampling_rate, audio_data, bass_boost_db, fade_sec):
|
| 2 |
-
"""
|
| 3 |
-
1. Saves Raw AI Audio
|
| 4 |
-
2. Masters with Pedalboard (Audacity/Studio Style)
|
| 5 |
-
3. Exports with Bash/FFmpeg (Insane Quality)
|
| 6 |
-
"""
|
| 7 |
temp_raw = "raw_output.wav"
|
| 8 |
temp_mastered = "mastered_temp.wav"
|
| 9 |
|
| 10 |
-
#
|
| 11 |
audio_norm = np.clip(audio_data, -1.0, 1.0)
|
| 12 |
wavfile.write(temp_raw, sampling_rate, (audio_norm * 32767).astype(np.int16))
|
| 13 |
|
| 14 |
-
#
|
| 15 |
with AudioFile(temp_raw) as f:
|
| 16 |
audio_signal = f.read(f.frames)
|
| 17 |
sr = f.sample_rate
|
|
@@ -25,24 +41,62 @@ def apply_audacity_fixes(sampling_rate, audio_data, bass_boost_db, fade_sec):
|
|
| 25 |
|
| 26 |
mastered_signal = board(audio_signal, sr)
|
| 27 |
|
| 28 |
-
# Save the mastered signal to a temporary wav
|
| 29 |
with AudioFile(temp_mastered, 'w', sr, mastered_signal.shape[0]) as f:
|
| 30 |
f.write(mastered_signal)
|
| 31 |
|
| 32 |
-
#
|
| 33 |
audio_segment = AudioSegment.from_wav(temp_mastered)
|
| 34 |
fade_ms = int(fade_sec * 1000)
|
| 35 |
final_pydub = audio_segment.fade_in(fade_ms).fade_out(fade_ms)
|
| 36 |
final_pydub.export("final_wav_stage.wav", format="wav")
|
| 37 |
|
| 38 |
-
#
|
| 39 |
-
#
|
| 40 |
os.system("ffmpeg -y -i final_wav_stage.wav -codec:a libmp3lame -qscale:a 0 studio_master.mp3")
|
| 41 |
|
| 42 |
-
# Cleanup
|
| 43 |
for file in [temp_raw, temp_mastered, "final_wav_stage.wav"]:
|
| 44 |
if os.path.exists(file): os.remove(file)
|
| 45 |
|
| 46 |
-
return "studio_master.mp3"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import torch
|
| 3 |
+
import numpy as np
|
| 4 |
+
import random
|
| 5 |
+
import os
|
| 6 |
+
import subprocess
|
| 7 |
+
import scipy.io.wavfile as wavfile
|
| 8 |
+
from transformers import MusicgenForConditionalGeneration, AutoProcessor
|
| 9 |
+
from pydub import AudioSegment, effects
|
| 10 |
+
from pedalboard import Pedalboard, Compressor, Gain, HighpassFilter, LowShelfFilter
|
| 11 |
+
from pedalboard.io import AudioFile
|
| 12 |
+
|
| 13 |
+
# 1. BASH SETUP (Runs once on startup)
|
| 14 |
+
if os.path.exists("setup.sh"):
|
| 15 |
+
subprocess.run(["sh", "setup.sh"])
|
| 16 |
+
|
| 17 |
+
# 2. LOAD MODEL
|
| 18 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 19 |
+
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-small").to(device)
|
| 20 |
+
processor = AutoProcessor.from_pretrained("facebook/musicgen-small")
|
| 21 |
+
|
| 22 |
def apply_audacity_fixes(sampling_rate, audio_data, bass_boost_db, fade_sec):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
temp_raw = "raw_output.wav"
|
| 24 |
temp_mastered = "mastered_temp.wav"
|
| 25 |
|
| 26 |
+
# STEP 1: Save Raw AI Output
|
| 27 |
audio_norm = np.clip(audio_data, -1.0, 1.0)
|
| 28 |
wavfile.write(temp_raw, sampling_rate, (audio_norm * 32767).astype(np.int16))
|
| 29 |
|
| 30 |
+
# STEP 2: Audacity-Style Mastering (Pedalboard)
|
| 31 |
with AudioFile(temp_raw) as f:
|
| 32 |
audio_signal = f.read(f.frames)
|
| 33 |
sr = f.sample_rate
|
|
|
|
| 41 |
|
| 42 |
mastered_signal = board(audio_signal, sr)
|
| 43 |
|
|
|
|
| 44 |
with AudioFile(temp_mastered, 'w', sr, mastered_signal.shape[0]) as f:
|
| 45 |
f.write(mastered_signal)
|
| 46 |
|
| 47 |
+
# STEP 3: Apply Fades (Pydub)
|
| 48 |
audio_segment = AudioSegment.from_wav(temp_mastered)
|
| 49 |
fade_ms = int(fade_sec * 1000)
|
| 50 |
final_pydub = audio_segment.fade_in(fade_ms).fade_out(fade_ms)
|
| 51 |
final_pydub.export("final_wav_stage.wav", format="wav")
|
| 52 |
|
| 53 |
+
# STEP 4: BASH EXPORT (Highest Quality MP3)
|
| 54 |
+
# This creates the 'studio_master.mp3' file
|
| 55 |
os.system("ffmpeg -y -i final_wav_stage.wav -codec:a libmp3lame -qscale:a 0 studio_master.mp3")
|
| 56 |
|
| 57 |
+
# Cleanup temporary files
|
| 58 |
for file in [temp_raw, temp_mastered, "final_wav_stage.wav"]:
|
| 59 |
if os.path.exists(file): os.remove(file)
|
| 60 |
|
| 61 |
+
return "studio_master.mp3" # ONLY ONE RETURN HERE
|
| 62 |
+
|
| 63 |
+
def generate_music(prompt, duration, instruments, energy, bass_boost_db, fade_sec):
|
| 64 |
+
if not prompt: return None, "Enter a prompt!"
|
| 65 |
+
|
| 66 |
+
inst_text = ", ".join(instruments)
|
| 67 |
+
full_prompt = f"{prompt} with {inst_text}. {energy} energy, studio quality."
|
| 68 |
+
|
| 69 |
+
inputs = processor(text=[full_prompt], padding=True, return_tensors="pt").to(device)
|
| 70 |
|
| 71 |
+
with torch.no_grad():
|
| 72 |
+
audio_values = model.generate(**inputs, max_new_tokens=int(duration * 50), do_sample=True, guidance_scale=4.0)
|
| 73 |
+
|
| 74 |
+
sampling_rate = model.config.audio_encoder.sampling_rate
|
| 75 |
+
audio_data = audio_values[0, 0].cpu().numpy()
|
| 76 |
+
|
| 77 |
+
# Call the mastering function
|
| 78 |
+
final_mp3 = apply_audacity_fixes(sampling_rate, audio_data, bass_boost_db, fade_sec)
|
| 79 |
+
|
| 80 |
+
return final_mp3, f"✅ Mastered {inst_text} Track"
|
| 81 |
+
|
| 82 |
+
# 3. UI LAYOUT
|
| 83 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 84 |
+
gr.Markdown("# 🎹 NEURAL STUDIO PRO")
|
| 85 |
+
with gr.Row():
|
| 86 |
+
with gr.Column():
|
| 87 |
+
txt = gr.Textbox(label="Song Description")
|
| 88 |
+
ins = gr.CheckboxGroup(["Piano", "Drums", "Guitar", "Synth", "Violin"], label="Instruments", value=["Piano"])
|
| 89 |
+
en = gr.Radio(["Low", "Medium", "High"], label="Energy", value="Medium")
|
| 90 |
+
dur = gr.Slider(5, 30, value=10, label="Seconds")
|
| 91 |
+
bass = gr.Slider(0, 10, value=3, label="Bass Boost")
|
| 92 |
+
fade = gr.Slider(0, 5, value=2, label="Fade")
|
| 93 |
+
btn = gr.Button("Generate", variant="primary")
|
| 94 |
+
with gr.Column():
|
| 95 |
+
aud = gr.Audio(label="Result", type="filepath")
|
| 96 |
+
out_txt = gr.Textbox(label="Status")
|
| 97 |
+
|
| 98 |
+
btn.click(generate_music, [txt, dur, ins, en, bass, fade], [aud, out_txt])
|
| 99 |
+
|
| 100 |
+
# 4. START (Crucial for Hugging Face)
|
| 101 |
+
if __name__ == "__main__":
|
| 102 |
+
demo.queue().launch()
|