Curlyblaze commited on
Commit
1dbd358
·
verified ·
1 Parent(s): d8c5268

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -47
app.py CHANGED
@@ -6,15 +6,15 @@ import numpy as np
6
  import random
7
  import uuid
8
 
9
- # Load the model
10
  model = MusicGen.get_pretrained('facebook/musicgen-melody')
11
 
12
  STYLE_MAP = {
13
- "Phonk": "Add aggressive high-pitched cowbell melodies, distorted 808 percussion, and a dark, lo-fi Memphis rap atmosphere. Heavy sidechain compression, 120 BPM, gritty and phonk-style.",
14
- "Hyperpop": "Add high-energy metallic percussion, glitchy synth arpeggios, and bright bubblegum-pop textures. Use sharp, digital drums and a very polished, futuristic sound. 160 BPM.",
15
- "Neo-Soul": "Add a warm Rhodes electric piano layer, subtle jazzy guitar licks, and a laid-back, swinging drum kit with soft rimshots. Soulful, organic, 90 BPM, deep groove.",
16
- "Dark Techno": "Add a heavy, driving industrial kick drum, pulsing white noise textures, and a rhythmic hypnotic synth sequence. Minimalist, dark warehouse vibe, 130 BPM.",
17
- "Lofi Hip-Hop": "Add a dusty, bit-crushed boom-bap drum loop, mellow vinyl crackle, and a soft flute melody in the background. Nostalgic, rainy day vibe, 85 BPM.",
18
  "Custom (Type Below)": ""
19
  }
20
 
@@ -22,27 +22,41 @@ def get_random_style():
22
  choices = [s for s in STYLE_MAP.keys() if s != "Custom (Type Below)"]
23
  return random.choice(choices)
24
 
25
- def finish_my_song(audio_input, style_choice, custom_prompt, duration, temp, top_k, top_p, current_history):
26
  if audio_input is None:
27
  return None, current_history
28
 
29
- final_prompt = custom_prompt if style_choice == "Custom (Type Below)" else STYLE_MAP[style_choice]
 
 
 
 
 
 
 
 
30
 
31
- # APPLY THE CREATIVITY SETTINGS
 
 
 
 
32
  model.set_generation_params(
33
  duration=duration,
34
  temperature=temp,
35
  top_k=top_k,
36
- top_p=top_p
 
37
  )
38
-
39
- sr, data = audio_input
40
- audio_tensor = torch.from_numpy(data).float().t().unsqueeze(0)
41
- if audio_tensor.shape[1] > 1:
42
- audio_tensor = audio_tensor.mean(dim=1, keepdim=True)
43
 
44
- wav = model.generate_with_chroma(descriptions=[final_prompt], melody_wavs=audio_tensor, sr=sr)
 
 
 
 
 
45
 
 
46
  unique_id = str(uuid.uuid4())[:8]
47
  output_path = f"finished_beat_{unique_id}"
48
  audio_write(output_path, wav[0].cpu(), model.sample_rate, strategy="loudness")
@@ -51,43 +65,19 @@ def finish_my_song(audio_input, style_choice, custom_prompt, duration, temp, top
51
  new_history = [full_file_path] + current_history
52
  return full_file_path, new_history
53
 
 
54
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
55
  history_state = gr.State([])
56
 
57
- gr.Markdown("# 🎹 The Song Finisher Pro + Advanced Controls")
 
58
 
59
  with gr.Row():
60
  with gr.Column(scale=2):
61
- audio_in = gr.Audio(label="Upload Chords/Bass")
 
62
  with gr.Row():
63
- style_dropdown = gr.Dropdown(choices=list(STYLE_MAP.keys()), value="Phonk", label="Style")
64
  random_btn = gr.Button("🎲 Random")
65
 
66
- custom_text = gr.Textbox(label="Custom Prompt", placeholder="Type here...")
67
- length = gr.Slider(minimum=5, maximum=30, value=15, step=5, label="Seconds")
68
-
69
- # ADVANCED CONTROLS ACCORDION
70
- with gr.Accordion("🛠️ Advanced Creativity Settings", open=False):
71
- temp_slider = gr.Slider(minimum=0.1, maximum=2.0, value=1.0, step=0.1, label="Temperature (Randomness)")
72
- top_k_slider = gr.Slider(minimum=0, maximum=500, value=250, step=1, label="Top-k (Variety)")
73
- top_p_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.0, step=0.01, label="Top-p (Nucleus Sampling)")
74
- gr.Markdown("*Tip: If the song sounds too messy, lower the Temperature to 0.7.*")
75
-
76
- submit_btn = gr.Button("🔥 Generate Arrangement", variant="primary")
77
- latest_output = gr.Audio(label="Latest Generation", type="filepath")
78
-
79
- with gr.Column(scale=1):
80
- gr.Markdown("### 📜 Session History")
81
- history_gallery = gr.Files(label="Download Past Versions", interactive=False)
82
-
83
- random_btn.click(fn=get_random_style, outputs=style_dropdown)
84
-
85
- submit_btn.click(
86
- fn=finish_my_song,
87
- inputs=[audio_in, style_dropdown, custom_text, length, temp_slider, top_k_slider, top_p_slider, history_state],
88
- outputs=[latest_output, history_state]
89
- ).then(
90
- fn=lambda x: x, inputs=history_state, outputs=history_gallery
91
- )
92
-
93
- demo.launch()
 
6
  import random
7
  import uuid
8
 
9
+ # Load the model - using 'melody' to ensure it follows your notes
10
  model = MusicGen.get_pretrained('facebook/musicgen-melody')
11
 
12
  STYLE_MAP = {
13
+ "Phonk": "Aggressive high-pitched cowbell melodies, distorted 808 percussion, dark lo-fi atmosphere, 120 BPM.",
14
+ "Hyperpop": "High-energy metallic percussion, glitchy synth arps, futuristic digital textures, 160 BPM.",
15
+ "Neo-Soul": "Warm Rhodes piano, subtle jazzy guitar licks, laid-back swinging drum kit, organic groove, 90 BPM.",
16
+ "Dark Techno": "Heavy driving industrial kick drum, pulsing white noise, rhythmic hypnotic synth sequence, 130 BPM.",
17
+ "Lofi Hip-Hop": "Dusty boom-bap drum loop, vinyl crackle, soft flute melody, nostalgic vibe, 85 BPM.",
18
  "Custom (Type Below)": ""
19
  }
20
 
 
22
  choices = [s for s in STYLE_MAP.keys() if s != "Custom (Type Below)"]
23
  return random.choice(choices)
24
 
25
+ def finish_my_song(audio_input, style_choice, custom_prompt, duration, temp, top_k, top_p, bpm, current_history):
26
  if audio_input is None:
27
  return None, current_history
28
 
29
+ # 1. Build the Smart Prompt
30
+ style_desc = STYLE_MAP[style_choice] if style_choice != "Custom (Type Below)" else custom_prompt
31
+ final_prompt = f"{style_desc} The tempo is strictly {bpm} BPM. High precision rhythmic alignment, studio quality."
32
+
33
+ # 2. Audio Pre-Processing (Normalization for rough recordings)
34
+ sr, data = audio_input
35
+ audio_data = data.astype(np.float32)
36
+ # Normalize volume
37
+ audio_data /= np.max(np.abs(audio_data)) + 1e-6
38
 
39
+ audio_tensor = torch.from_numpy(audio_data).t().unsqueeze(0)
40
+ if audio_tensor.shape[1] > 1:
41
+ audio_tensor = audio_tensor.mean(dim=1, keepdim=True)
42
+
43
+ # 3. Apply Precision Settings
44
  model.set_generation_params(
45
  duration=duration,
46
  temperature=temp,
47
  top_k=top_k,
48
+ top_p=top_p,
49
+ cfg_coeff=5.0 # High guidance to fix off-beat timing
50
  )
 
 
 
 
 
51
 
52
+ # 4. Generate with Chroma (Extracts the 'DNA' of your chords)
53
+ wav = model.generate_with_chroma(
54
+ descriptions=[final_prompt],
55
+ melody_wavs=audio_tensor,
56
+ sr=sr
57
+ )
58
 
59
+ # 5. Save and Track History
60
  unique_id = str(uuid.uuid4())[:8]
61
  output_path = f"finished_beat_{unique_id}"
62
  audio_write(output_path, wav[0].cpu(), model.sample_rate, strategy="loudness")
 
65
  new_history = [full_file_path] + current_history
66
  return full_file_path, new_history
67
 
68
+ # --- GRADIO UI ---
69
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
70
  history_state = gr.State([])
71
 
72
+ gr.Markdown("# 🎹 The Song Finisher Pro")
73
+ gr.Markdown("Upload your chords/bass. The AI will quantize your timing to the BPM you set.")
74
 
75
  with gr.Row():
76
  with gr.Column(scale=2):
77
+ audio_in = gr.Audio(label="Step 1: Upload Your Rough Track")
78
+
79
  with gr.Row():
80
+ style_dropdown = gr.Dropdown(choices=list(STYLE_MAP.keys()), value="Phonk", label="Step 2: Style")
81
  random_btn = gr.Button("🎲 Random")
82
 
83
+ bpm_slider =