John6666 commited on
Commit
d3ef5f0
Β·
verified Β·
1 Parent(s): b4b51e1

Upload 4 files

Browse files
Files changed (4) hide show
  1. README.md +13 -12
  2. app.py +579 -0
  3. packages.txt +1 -0
  4. requirements.txt +11 -0
README.md CHANGED
@@ -1,12 +1,13 @@
1
- ---
2
- title: GHOSTSONAFB Test
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: gray
6
- sdk: gradio
7
- sdk_version: 5.31.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
+ ---
2
+ title: GhostAI Music Generator Test
3
+ emoji: πŸ‘»
4
+ colorFrom: indigo
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 4.44.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,579 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces
2
+ import os
3
+ import torch
4
+ import torchaudio
5
+ import psutil
6
+ import time
7
+ import sys
8
+ import numpy as np
9
+ import gc
10
+ import gradio as gr
11
+ from pydub import AudioSegment
12
+ from audiocraft.models import MusicGen
13
+ from torch.cuda.amp import autocast
14
+ import warnings
15
+ import random
16
+ from huggingface_hub import snapshot_download
17
+ IS_ZEROGPU = True if os.getenv("SPACES_ZERO_GPU", None) else False
18
+
19
+ # Suppress warnings for cleaner output
20
+ warnings.filterwarnings("ignore")
21
+
22
+ # Set PYTORCH_CUDA_ALLOC_CONF to manage memory fragmentation
23
+ os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:128"
24
+
25
+ # Check critical dependencies
26
+ if np.__version__ != "1.23.5":
27
+ print(f"WARNING: NumPy version {np.__version__} is being used. Tested with numpy==1.23.5.")
28
+ if not torch.__version__.startswith(("2.1.0", "2.3.1")):
29
+ print(f"WARNING: PyTorch version {torch.__version__} may not be compatible. Expected torch==2.1.0 or 2.3.1.")
30
+
31
+ # 1) DEVICE SETUP
32
+ device = "cuda" if torch.cuda.is_available() else "cpu"
33
+ if device != "cuda":
34
+ print("ERROR: CUDA is required for GPU rendering. CPU rendering is disabled.")
35
+ sys.exit(1)
36
+ print(f"CUDA is available. Using GPU: {torch.cuda.get_device_name(0)}")
37
+
38
+ # Pre-run memory cleanup
39
+ torch.cuda.empty_cache()
40
+ gc.collect()
41
+ #torch.cuda.ipc_collect()
42
+ #torch.cuda.synchronize()
43
+
44
+ # 2) LOAD MUSICGEN INTO VRAM
45
+ try:
46
+ print("Loading MusicGen medium model into VRAM...")
47
+ local_model_path = "./models/musicgen-medium"
48
+ if not os.path.exists(local_model_path): snapshot_download(repo_id="facebook/musicgen-medium", local_dir=local_model_path)
49
+ if not os.path.exists(local_model_path):
50
+ print(f"ERROR: Local model path {local_model_path} does not exist.")
51
+ print("Please download the MusicGen medium model weights and place them in the correct directory.")
52
+ sys.exit(1)
53
+ musicgen_model = MusicGen.get_pretrained(local_model_path, device=device)
54
+ musicgen_model.set_generation_params(
55
+ duration=10, # Default chunk duration
56
+ two_step_cfg=False # Disable two-step CFG for stability
57
+ )
58
+ except Exception as e:
59
+ print(f"ERROR: Failed to load MusicGen model: {e}")
60
+ print("Ensure model weights are correctly placed and dependencies are installed.")
61
+ sys.exit(1)
62
+
63
+ # 3) RESOURCE MONITORING FUNCTION
64
+ def print_resource_usage(stage: str):
65
+ print(f"--- {stage} ---")
66
+ print(f"GPU Memory Allocated: {torch.cuda.memory_allocated() / (1024**3):.2f} GB")
67
+ print(f"GPU Memory Reserved: {torch.cuda.memory_reserved() / (1024**3):.2f} GB")
68
+ print(f"CPU Memory Used: {psutil.virtual_memory().percent}%")
69
+ print("---------------")
70
+
71
+ # Check available GPU memory
72
+ def check_vram_availability(required_gb=3.5):
73
+ total_vram = torch.cuda.get_device_properties(0).total_memory / (1024**3)
74
+ allocated_vram = torch.cuda.memory_allocated() / (1024**3)
75
+ available_vram = total_vram - allocated_vram
76
+ if available_vram < required_gb:
77
+ print(f"WARNING: Low VRAM available ({available_vram:.2f} GB). Reduce total_duration or chunk_duration.")
78
+ return available_vram >= required_gb
79
+
80
+ # 4) GENRE PROMPT FUNCTIONS
81
+ def set_red_hot_chili_peppers_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
82
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("strong rhythmic steps" if bpm > 120 else "groovy rhythmic flow")
83
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
84
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
85
+ bass = f", {bass_style}" if bass_style != "none" else ", groovy basslines"
86
+ guitar = f", {guitar_style} guitar riffs" if guitar_style != "none" else ", syncopated guitar riffs"
87
+ return f"Instrumental funk rock{bass}{guitar}{drum}{synth}, Red Hot Chili Peppers-inspired vibe with dynamic energy and funky breakdowns, {rhythm} at {bpm} BPM."
88
+
89
+ def set_nirvana_grunge_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
90
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("intense rhythmic steps" if bpm > 120 else "grungy rhythmic pulse")
91
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
92
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
93
+ bass = f", {bass_style}" if bass_style != "none" else ", melodic basslines"
94
+ guitar = f", {guitar_style} guitar riffs" if guitar_style != "none" else ", raw distorted guitar riffs"
95
+ return f"Instrumental grunge{bass}{guitar}{drum}{synth}, Nirvana-inspired angst-filled sound with quiet-loud dynamics, {rhythm} at {bpm} BPM."
96
+
97
+ def set_pearl_jam_grunge_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
98
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("soulful rhythmic steps" if bpm > 120 else "driving rhythmic flow")
99
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
100
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
101
+ bass = f", {bass_style}" if bass_style != "none" else ", deep bass"
102
+ guitar = f", {guitar_style} guitar leads" if guitar_style != "none" else ", soulful guitar leads"
103
+ return f"Instrumental grunge{bass}{guitar}{drum}{synth}, Pearl Jam-inspired emotional intensity with soaring choruses, {rhythm} at {bpm} BPM."
104
+
105
+ def set_soundgarden_grunge_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
106
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("heavy rhythmic steps" if bpm > 120 else "sludgy rhythmic groove")
107
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
108
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
109
+ bass = f", {bass_style}" if bass_style != "none" else ""
110
+ guitar = f", {guitar_style} guitar riffs" if guitar_style != "none" else ", heavy sludgy guitar riffs"
111
+ return f"Instrumental grunge{bass}{guitar}{drum}{synth}, Soundgarden-inspired dark, psychedelic edge, {rhythm} at {bpm} BPM."
112
+
113
+ def set_foo_fighters_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
114
+ styles = ["anthemic", "gritty", "melodic", "fast-paced", "driving"]
115
+ tempos = ["upbeat", "mid-tempo", "high-energy"]
116
+ moods = ["energetic", "introspective", "rebellious", "uplifting"]
117
+ style = random.choice(styles)
118
+ tempo = random.choice(tempos)
119
+ mood = random.choice(moods)
120
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("powerful rhythmic steps" if bpm > 120 else "catchy rhythmic groove")
121
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
122
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
123
+ bass = f", {bass_style}" if bass_style != "none" else ""
124
+ guitar = f", {guitar_style} guitar riffs" if guitar_style != "none" else f", {style} guitar riffs"
125
+ return f"Instrumental alternative rock{bass}{guitar}{drum}{synth}, Foo Fighters-inspired {mood} vibe with powerful choruses, {rhythm} at {bpm} BPM."
126
+
127
+ def set_smashing_pumpkins_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
128
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("dynamic rhythmic steps" if bpm > 120 else "dreamy rhythmic flow")
129
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
130
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
131
+ bass = f", {bass_style}" if bass_style != "none" else ""
132
+ guitar = f", {guitar_style} guitar textures" if guitar_style != "none" else ", dreamy guitar textures"
133
+ return f"Instrumental alternative rock{bass}{guitar}{drum}{synth}, Smashing Pumpkins-inspired blend of melancholy and aggression, {rhythm} at {bpm} BPM."
134
+
135
+ def set_radiohead_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
136
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("complex rhythmic steps" if bpm > 120 else "intricate rhythmic pulse")
137
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
138
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ", atmospheric synths"
139
+ bass = f", {bass_style}" if bass_style != "none" else ""
140
+ guitar = f", {guitar_style} guitar layers" if guitar_style != "none" else ", intricate guitar layers"
141
+ return f"Instrumental experimental rock{bass}{guitar}{drum}{synth}, Radiohead-inspired blend of introspective and innovative soundscapes, {rhythm} at {bpm} BPM."
142
+
143
+ def set_classic_rock_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
144
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("bluesy rhythmic steps" if bpm > 120 else "steady rhythmic groove")
145
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
146
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
147
+ bass = f", {bass_style}" if bass_style != "none" else ", groovy bass"
148
+ guitar = f", {guitar_style} electric guitars" if guitar_style != "none" else ", bluesy electric guitars"
149
+ return f"Instrumental classic rock{bass}{guitar}{drum}{synth}, Led Zeppelin-inspired raw energy with dynamic solos, {rhythm} at {bpm} BPM."
150
+
151
+ def set_alternative_rock_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
152
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("quirky rhythmic steps" if bpm > 120 else "energetic rhythmic flow")
153
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
154
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
155
+ bass = f", {bass_style}" if bass_style != "none" else ", melodic basslines"
156
+ guitar = f", {guitar_style} guitar riffs" if guitar_style != "none" else ", distorted guitar riffs"
157
+ return f"Instrumental alternative rock{bass}{guitar}{drum}{synth}, Pixies-inspired quirky, energetic vibe, {rhythm} at {bpm} BPM."
158
+
159
+ def set_post_punk_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
160
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("sharp rhythmic steps" if bpm > 120 else "moody rhythmic pulse")
161
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
162
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
163
+ bass = f", {bass_style}" if bass_style != "none" else ", driving basslines"
164
+ guitar = f", {guitar_style} guitars" if guitar_style != "none" else ", jangly guitars"
165
+ return f"Instrumental post-punk{bass}{guitar}{drum}{synth}, Joy Division-inspired moody, atmospheric sound, {rhythm} at {bpm} BPM."
166
+
167
+ def set_indie_rock_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
168
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("catchy rhythmic steps" if bpm > 120 else "jangly rhythmic flow")
169
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
170
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
171
+ bass = f", {bass_style}" if bass_style != "none" else ""
172
+ guitar = f", {guitar_style} guitars" if guitar_style != "none" else ", jangly guitars"
173
+ return f"Instrumental indie rock{bass}{guitar}{drum}{synth}, Arctic Monkeys-inspired blend of catchy riffs, {rhythm} at {bpm} BPM."
174
+
175
+ def set_funk_rock_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
176
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("aggressive rhythmic steps" if bpm > 120 else "funky rhythmic groove")
177
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
178
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ""
179
+ bass = f", {bass_style}" if bass_style != "none" else ", slap bass"
180
+ guitar = f", {guitar_style} guitar chords" if guitar_style != "none" else ", funky guitar chords"
181
+ return f"Instrumental funk rock{bass}{guitar}{drum}{synth}, Rage Against the Machine-inspired mix of groove and aggression, {rhythm} at {bpm} BPM."
182
+
183
+ def set_detroit_techno_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
184
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("pulsing rhythmic steps" if bpm > 120 else "deep rhythmic groove")
185
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ", crisp hi-hats"
186
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ", deep pulsing synths"
187
+ bass = f", {bass_style}" if bass_style != "none" else ", driving basslines"
188
+ guitar = f", {guitar_style} guitars" if guitar_style != "none" else ""
189
+ return f"Instrumental Detroit techno{bass}{guitar}{drum}{synth}, Juan Atkins-inspired rhythmic groove, {rhythm} at {bpm} BPM."
190
+
191
+ def set_deep_house_prompt(bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style):
192
+ rhythm = f" with {rhythmic_steps}" if rhythmic_steps != "none" else ("soulful rhythmic steps" if bpm > 120 else "laid-back rhythmic flow")
193
+ drum = f", {drum_beat} drums" if drum_beat != "none" else ""
194
+ synth = f", {synthesizer} accents" if synthesizer != "none" else ", warm analog synth chords"
195
+ bass = f", {bass_style}" if bass_style != "none" else ", deep basslines"
196
+ guitar = f", {guitar_style} guitars" if guitar_style != "none" else ""
197
+ return f"Instrumental deep house{bass}{guitar}{drum}{synth}, Larry Heard-inspired laid-back groove, {rhythm} at {bpm} BPM."
198
+
199
+ # 5) AUDIO PROCESSING FUNCTIONS
200
+ def apply_eq(segment):
201
+ segment = segment.low_pass_filter(8000)
202
+ segment = segment.high_pass_filter(80)
203
+ return segment
204
+
205
+ def apply_fade(segment, fade_in_duration=1000, fade_out_duration=1000):
206
+ segment = segment.fade_in(fade_in_duration)
207
+ segment = segment.fade_out(fade_out_duration)
208
+ return segment
209
+
210
+ # 6) GENERATION & I/O FUNCTIONS
211
+ @spaces.GPU(duration=120)
212
+ def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p: float, temperature: float, total_duration: int, chunk_duration: int, crossfade_duration: int, bpm: int, drum_beat: str, synthesizer: str, rhythmic_steps: str, bass_style: str, guitar_style: str):
213
+ #global musicgen_model
214
+ if not instrumental_prompt.strip():
215
+ return None, "⚠️ Please enter a valid instrumental prompt!"
216
+ try:
217
+ start_time = time.time()
218
+ total_duration = total_duration # Validated by radio button (30, 60, 90, 120)
219
+ chunk_duration = min(max(chunk_duration, 5), 15)
220
+ num_chunks = max(1, total_duration // chunk_duration)
221
+ chunk_duration = total_duration / num_chunks
222
+ overlap_duration = min(1.0, crossfade_duration / 1000.0)
223
+ generation_duration = chunk_duration + overlap_duration
224
+ sample_rate = musicgen_model.sample_rate
225
+ audio_segments = []
226
+
227
+ if not check_vram_availability(required_gb=3.5):
228
+ return None, "⚠️ Insufficient VRAM for generation. Reduce total_duration or chunk_duration."
229
+
230
+ print("Generating audio...")
231
+ seed = 42
232
+ torch.manual_seed(seed)
233
+ np.random.seed(seed)
234
+
235
+ for i in range(num_chunks):
236
+ chunk_prompt = instrumental_prompt
237
+ print(f"Generating chunk {i+1}/{num_chunks} on GPU (prompt: {chunk_prompt})...")
238
+ musicgen_model.set_generation_params(
239
+ duration=generation_duration,
240
+ use_sampling=True,
241
+ top_k=top_k,
242
+ top_p=top_p,
243
+ temperature=temperature,
244
+ cfg_coef=cfg_scale
245
+ )
246
+
247
+ print_resource_usage(f"Before Chunk {i+1} Generation")
248
+
249
+ with torch.no_grad():
250
+ with autocast():
251
+ audio_chunk = musicgen_model.generate([chunk_prompt], progress=True)[0]
252
+
253
+ audio_chunk = audio_chunk.cpu().to(dtype=torch.float32)
254
+ if audio_chunk.dim() == 1:
255
+ audio_chunk = torch.stack([audio_chunk, audio_chunk], dim=0)
256
+ elif audio_chunk.dim() == 2 and audio_chunk.shape[0] == 1:
257
+ audio_chunk = torch.cat([audio_chunk, audio_chunk], dim=0)
258
+ elif audio_chunk.dim() == 2 and audio_chunk.shape[0] != 2:
259
+ audio_chunk = audio_chunk[:1, :]
260
+ audio_chunk = torch.cat([audio_chunk, audio_chunk], dim=0)
261
+ elif audio_chunk.dim() > 2:
262
+ audio_chunk = audio_chunk.view(2, -1)
263
+
264
+ if audio_chunk.shape[0] != 2:
265
+ raise ValueError(f"Expected stereo audio with shape (2, samples), got shape {audio_chunk.shape}")
266
+
267
+ temp_wav_path = f"temp_chunk_{i}.wav"
268
+ torchaudio.save(temp_wav_path, audio_chunk, sample_rate, bits_per_sample=24)
269
+ segment = AudioSegment.from_wav(temp_wav_path)
270
+ os.remove(temp_wav_path)
271
+ audio_segments.append(segment)
272
+
273
+ torch.cuda.empty_cache()
274
+ gc.collect()
275
+ #torch.cuda.ipc_collect()
276
+ #torch.cuda.synchronize()
277
+ time.sleep(0.5)
278
+ print_resource_usage(f"After Chunk {i+1} Generation")
279
+
280
+ print("Combining audio chunks...")
281
+ final_segment = audio_segments[0]
282
+ for i in range(1, len(audio_segments)):
283
+ next_segment = audio_segments[i]
284
+ next_segment = next_segment + 1
285
+ final_segment = final_segment.append(next_segment, crossfade=crossfade_duration)
286
+
287
+ final_segment = final_segment[:total_duration * 1000]
288
+
289
+ print("Post-processing final track...")
290
+ final_segment = apply_eq(final_segment)
291
+ final_segment = final_segment.normalize(headroom=-9.0)
292
+ final_segment = apply_fade(final_segment)
293
+
294
+ mp3_path = "output_cleaned.mp3"
295
+ final_segment.export(
296
+ mp3_path,
297
+ format="mp3",
298
+ bitrate="128k",
299
+ tags={"title": "GhostAI Instrumental", "artist": "GhostAI"}
300
+ )
301
+ print(f"Saved final audio to {mp3_path}")
302
+
303
+ print_resource_usage("After Final Generation")
304
+ print(f"Total Generation Time: {time.time() - start_time:.2f} seconds")
305
+
306
+ return mp3_path, "βœ… Done! Generated instrumental audio."
307
+ except Exception as e:
308
+ return None, f"❌ Generation failed: {e}"
309
+ finally:
310
+ torch.cuda.empty_cache()
311
+ gc.collect()
312
+ #torch.cuda.ipc_collect()
313
+ #torch.cuda.synchronize()
314
+
315
+ # Function to clear inputs
316
+ def clear_inputs():
317
+ return "", 3.0, 250, 0.9, 1.0, 30, 10, 1000, 120, "none", "none", "none", "none", "none"
318
+
319
+ # 7) CUSTOM CSS
320
+ css = """
321
+ body {
322
+ background: linear-gradient(135deg, #0A0A0A 0%, #1C2526 100%);
323
+ color: #E0E0E0;
324
+ font-family: 'Orbitron', sans-serif;
325
+ }
326
+ .header-container {
327
+ text-align: center;
328
+ padding: 10px 20px;
329
+ background: rgba(0, 0, 0, 0.9);
330
+ border-bottom: 1px solid #00FF9F;
331
+ }
332
+ #ghost-logo {
333
+ font-size: 40px;
334
+ animation: glitch-ghost 1.5s infinite;
335
+ }
336
+ h1 {
337
+ color: #A100FF;
338
+ font-size: 24px;
339
+ animation: glitch-text 2s infinite;
340
+ }
341
+ p {
342
+ color: #E0E0E0;
343
+ font-size: 12px;
344
+ }
345
+ .input-container, .settings-container, .output-container {
346
+ max-width: 1200px;
347
+ margin: 20px auto;
348
+ padding: 20px;
349
+ background: rgba(28, 37, 38, 0.8);
350
+ border-radius: 10px;
351
+ }
352
+ .textbox {
353
+ background: #1A1A1A;
354
+ border: 1px solid #A100FF;
355
+ color: #E0E0E0;
356
+ }
357
+ .genre-buttons {
358
+ display: flex;
359
+ justify-content: center;
360
+ flex-wrap: wrap;
361
+ gap: 15px;
362
+ }
363
+ .genre-btn, button {
364
+ background: linear-gradient(45deg, #A100FF, #00FF9F);
365
+ border: none;
366
+ color: #0A0A0A;
367
+ padding: 10px 20px;
368
+ border-radius: 5px;
369
+ }
370
+ .gradio-container {
371
+ padding: 20px;
372
+ }
373
+ .group-container {
374
+ margin-bottom: 20px;
375
+ padding: 15px;
376
+ border: 1px solid #00FF9F;
377
+ border-radius: 8px;
378
+ }
379
+ @keyframes glitch-ghost {
380
+ 0% { transform: translate(0, 0); opacity: 1; }
381
+ 20% { transform: translate(-5px, 2px); opacity: 0.8; }
382
+ 100% { transform: translate(0, 0); opacity: 1; }
383
+ }
384
+ @keyframes glitch-text {
385
+ 0% { transform: translate(0, 0); }
386
+ 20% { transform: translate(-2px, 1px); }
387
+ 100% { transform: translate(0, 0); }
388
+ }
389
+ @font-face {
390
+ font-family: 'Orbitron';
391
+ src: url('https://fonts.gstatic.com/s/orbitron/v29/yMJRMIlzdpvBhQQL_Qq7dy0.woff2') format('woff2');
392
+ }
393
+ """
394
+
395
+ # 8) BUILD WITH BLOCKS
396
+ with gr.Blocks(css=css) as demo:
397
+ gr.Markdown("""
398
+ <div class="header-container">
399
+ <div id="ghost-logo">πŸ‘»</div>
400
+ <h1>GhostAI Music Generator 🎹</h1>
401
+ <p>Summon the Sound of the Unknown</p>
402
+ </div>
403
+ """)
404
+
405
+ with gr.Column(elem_classes="input-container"):
406
+ gr.Markdown("### 🎸 Prompt Settings")
407
+ instrumental_prompt = gr.Textbox(
408
+ label="Instrumental Prompt ✍️",
409
+ placeholder="Click a genre button or type your own instrumental prompt",
410
+ lines=4,
411
+ elem_classes="textbox"
412
+ )
413
+ with gr.Row(elem_classes="genre-buttons"):
414
+ rhcp_btn = gr.Button("Red Hot Chili Peppers 🌢️", elem_classes="genre-btn")
415
+ nirvana_btn = gr.Button("Nirvana Grunge 🎸", elem_classes="genre-btn")
416
+ pearl_jam_btn = gr.Button("Pearl Jam Grunge πŸ¦ͺ", elem_classes="genre-btn")
417
+ soundgarden_btn = gr.Button("Soundgarden Grunge πŸŒ‘", elem_classes="genre-btn")
418
+ foo_fighters_btn = gr.Button("Foo Fighters 🀘", elem_classes="genre-btn")
419
+ smashing_pumpkins_btn = gr.Button("Smashing Pumpkins πŸŽƒ", elem_classes="genre-btn")
420
+ radiohead_btn = gr.Button("Radiohead 🧠", elem_classes="genre-btn")
421
+ classic_rock_btn = gr.Button("Classic Rock 🎸", elem_classes="genre-btn")
422
+ alternative_rock_btn = gr.Button("Alternative Rock 🎡", elem_classes="genre-btn")
423
+ post_punk_btn = gr.Button("Post-Punk πŸ–€", elem_classes="genre-btn")
424
+ indie_rock_btn = gr.Button("Indie Rock 🎀", elem_classes="genre-btn")
425
+ funk_rock_btn = gr.Button("Funk Rock πŸ•Ί", elem_classes="genre-btn")
426
+ detroit_techno_btn = gr.Button("Detroit Techno πŸŽ›οΈ", elem_classes="genre-btn")
427
+ deep_house_btn = gr.Button("Deep House 🏠", elem_classes="genre-btn")
428
+
429
+ with gr.Column(elem_classes="settings-container"):
430
+ gr.Markdown("### βš™οΈ API Settings")
431
+ with gr.Group(elem_classes="group-container"):
432
+ cfg_scale = gr.Slider(
433
+ label="CFG Scale 🎯",
434
+ minimum=1.0,
435
+ maximum=10.0,
436
+ value=3.0,
437
+ step=0.1,
438
+ info="Controls how closely the music follows the prompt."
439
+ )
440
+ top_k = gr.Slider(
441
+ label="Top-K Sampling πŸ”’",
442
+ minimum=10,
443
+ maximum=500,
444
+ value=250,
445
+ step=10,
446
+ info="Limits sampling to the top k most likely tokens."
447
+ )
448
+ top_p = gr.Slider(
449
+ label="Top-P Sampling 🎰",
450
+ minimum=0.0,
451
+ maximum=1.0,
452
+ value=0.9,
453
+ step=0.05,
454
+ info="Keeps tokens with cumulative probability above p."
455
+ )
456
+ temperature = gr.Slider(
457
+ label="Temperature πŸ”₯",
458
+ minimum=0.1,
459
+ maximum=2.0,
460
+ value=1.0,
461
+ step=0.1,
462
+ info="Controls randomness; higher values increase diversity."
463
+ )
464
+ total_duration = gr.Radio(
465
+ label="Song Length ⏳ (seconds)",
466
+ choices=[30, 60, 90, 120],
467
+ value=30,
468
+ info="Select the total duration of the track."
469
+ )
470
+ chunk_duration = gr.Slider(
471
+ label="Chunk Duration ⏱️ (seconds)",
472
+ minimum=5,
473
+ maximum=15,
474
+ value=10,
475
+ step=1,
476
+ info="Duration of each chunk to render (5 to 15 seconds)."
477
+ )
478
+ crossfade_duration = gr.Slider(
479
+ label="Crossfade Duration 🎢 (ms)",
480
+ minimum=100,
481
+ maximum=2000,
482
+ value=1000,
483
+ step=100,
484
+ info="Crossfade duration between chunks."
485
+ )
486
+
487
+ gr.Markdown("### 🎡 Musical Controls")
488
+ with gr.Group(elem_classes="group-container"):
489
+ bpm = gr.Slider(
490
+ label="Tempo 🎡 (BPM)",
491
+ minimum=60,
492
+ maximum=180,
493
+ value=120,
494
+ step=1,
495
+ info="Beats per minute to set the track's tempo."
496
+ )
497
+ drum_beat = gr.Dropdown(
498
+ label="Drum Beat πŸ₯",
499
+ choices=["none", "standard rock", "funk groove", "techno kick", "jazz swing"],
500
+ value="none",
501
+ info="Select a drum beat style to influence the rhythm."
502
+ )
503
+ synthesizer = gr.Dropdown(
504
+ label="Synthesizer 🎹",
505
+ choices=["none", "analog synth", "digital pad", "arpeggiated synth"],
506
+ value="none",
507
+ info="Select a synthesizer style for electronic accents."
508
+ )
509
+ rhythmic_steps = gr.Dropdown(
510
+ label="Rhythmic Steps πŸ‘£",
511
+ choices=["none", "syncopated steps", "steady steps", "complex steps"],
512
+ value="none",
513
+ info="Select a rhythmic step style to enhance the beat."
514
+ )
515
+ bass_style = gr.Dropdown(
516
+ label="Bass Style 🎸",
517
+ choices=["none", "slap bass", "deep bass", "melodic bass"],
518
+ value="none",
519
+ info="Select a bass style to shape the low end."
520
+ )
521
+ guitar_style = gr.Dropdown(
522
+ label="Guitar Style 🎸",
523
+ choices=["none", "distorted", "clean", "jangle"],
524
+ value="none",
525
+ info="Select a guitar style to define the riffs."
526
+ )
527
+
528
+ with gr.Row(elem_classes="action-buttons"):
529
+ gen_btn = gr.Button("Generate Music πŸš€")
530
+ clr_btn = gr.Button("Clear Inputs 🧹")
531
+
532
+ with gr.Column(elem_classes="output-container"):
533
+ gr.Markdown("### 🎧 Output")
534
+ out_audio = gr.Audio(label="Generated Instrumental Track 🎡", type="filepath")
535
+ status = gr.Textbox(label="Status πŸ“’", interactive=False)
536
+
537
+ rhcp_btn.click(set_red_hot_chili_peppers_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
538
+ nirvana_btn.click(set_nirvana_grunge_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
539
+ pearl_jam_btn.click(set_pearl_jam_grunge_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
540
+ soundgarden_btn.click(set_soundgarden_grunge_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
541
+ foo_fighters_btn.click(set_foo_fighters_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
542
+ smashing_pumpkins_btn.click(set_smashing_pumpkins_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
543
+ radiohead_btn.click(set_radiohead_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
544
+ classic_rock_btn.click(set_classic_rock_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
545
+ alternative_rock_btn.click(set_alternative_rock_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
546
+ post_punk_btn.click(set_post_punk_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
547
+ indie_rock_btn.click(set_indie_rock_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
548
+ funk_rock_btn.click(set_funk_rock_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
549
+ detroit_techno_btn.click(set_detroit_techno_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
550
+ deep_house_btn.click(set_deep_house_prompt, inputs=[bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style], outputs=instrumental_prompt)
551
+ gen_btn.click(
552
+ generate_music,
553
+ inputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, chunk_duration, crossfade_duration, bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style],
554
+ outputs=[out_audio, status]
555
+ )
556
+ clr_btn.click(
557
+ clear_inputs,
558
+ inputs=None,
559
+ outputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, chunk_duration, crossfade_duration, bpm, drum_beat, synthesizer, rhythmic_steps, bass_style, guitar_style]
560
+ )
561
+
562
+ # 9) TURN OFF OPENAPI/DOCS
563
+ demo.launch()
564
+ """
565
+ app = demo.launch(
566
+ server_name="0.0.0.0",
567
+ server_port=9999,
568
+ share=False,
569
+ inbrowser=False,
570
+ show_error=True
571
+ )
572
+ try:
573
+ fastapi_app = demo._server.app
574
+ fastapi_app.docs_url = None
575
+ fastapi_app.redoc_url = None
576
+ fastapi_app.openapi_url = None
577
+ except Exception:
578
+ pass
579
+ """
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ torch==2.1.0
2
+ torchvision==0.16.0
3
+ torchaudio==2.1.0
4
+ numpy==1.23.5
5
+ pydub==0.25.1
6
+ audiocraft==1.3.0
7
+ #gradio==4.44.0
8
+ psutil==5.9.8
9
+ bitsandbytes
10
+ transformers<=4.48.3
11
+ pydantic==2.10.6