Update app.py
Browse filesupdated build fixed issues
app.py
CHANGED
|
@@ -14,22 +14,9 @@ from torch.cuda.amp import autocast
|
|
| 14 |
# Set PYTORCH_CUDA_ALLOC_CONF to manage memory fragmentation
|
| 15 |
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:32"
|
| 16 |
|
| 17 |
-
# Setup instructions:
|
| 18 |
-
# 1. Create a virtual environment: python3 -m venv venv
|
| 19 |
-
# 2. Activate the environment: source venv/bin/activate
|
| 20 |
-
# 3. Install dependencies:
|
| 21 |
-
# pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu121
|
| 22 |
-
# pip install -r requirements.txt
|
| 23 |
-
# 4. Install ffmpeg for MP3 export:
|
| 24 |
-
# sudo apt-get install ffmpeg
|
| 25 |
-
# 5. Ensure model weights are in /home/ubuntu/ghostai_music_generator/models/musicgen-medium
|
| 26 |
-
# 6. Log in to Hugging Face CLI: huggingface-cli login
|
| 27 |
-
# 7. Request access to model if needed: https://huggingface.co/facebook/musicgen-medium
|
| 28 |
-
|
| 29 |
# Check critical dependencies
|
| 30 |
if np.__version__ != "1.23.5":
|
| 31 |
-
print(f"
|
| 32 |
-
sys.exit(1)
|
| 33 |
if not torch.__version__.startswith(("2.1.0", "2.3.1")):
|
| 34 |
print(f"WARNING: PyTorch version {torch.__version__} may not be compatible. Expected torch==2.1.0 or 2.3.1.")
|
| 35 |
|
|
@@ -60,71 +47,77 @@ def print_resource_usage(stage: str):
|
|
| 60 |
print(f"GPU Memory Reserved: {torch.cuda.memory_reserved() / (1024**3):.2f} GB")
|
| 61 |
print("---------------")
|
| 62 |
|
| 63 |
-
# 4) GENRE PROMPT FUNCTIONS (Updated for
|
| 64 |
def set_rock_prompt():
|
| 65 |
-
return "Hard rock with
|
| 66 |
|
| 67 |
def set_techno_prompt():
|
| 68 |
-
return "Techno with
|
| 69 |
|
| 70 |
def set_jazz_prompt():
|
| 71 |
-
return "Smooth jazz with
|
| 72 |
|
| 73 |
def set_classical_prompt():
|
| 74 |
-
return "Classical orchestral piece with
|
| 75 |
|
| 76 |
def set_hiphop_prompt():
|
| 77 |
-
return "Hip-hop with
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
# 5) AUDIO PROCESSING FUNCTIONS
|
| 80 |
def apply_chorus(segment):
|
| 81 |
# Enhanced chorus effect for richer sound
|
| 82 |
-
delayed = segment -
|
| 83 |
delayed = delayed.set_frame_rate(segment.frame_rate)
|
| 84 |
-
return segment.overlay(delayed, position=20)
|
| 85 |
|
| 86 |
def apply_eq(segment):
|
| 87 |
-
#
|
| 88 |
-
segment = segment.low_pass_filter(
|
| 89 |
-
segment = segment.high_pass_filter(
|
| 90 |
return segment
|
| 91 |
|
| 92 |
-
def apply_limiter(segment, max_db=-
|
| 93 |
-
# Apply a
|
| 94 |
if segment.dBFS > max_db:
|
| 95 |
-
segment = segment - (segment.dBFS - max_db)
|
| 96 |
return segment
|
| 97 |
|
| 98 |
# 6) GENERATION & I/O FUNCTIONS
|
| 99 |
def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p: float, temperature: float, total_duration: int, crossfade_duration: int):
|
| 100 |
-
global musicgen_model
|
| 101 |
if not instrumental_prompt.strip():
|
| 102 |
return None, "⚠️ Please enter a valid instrumental prompt!"
|
| 103 |
try:
|
| 104 |
-
# Record start time for total duration calculation
|
| 105 |
start_time = time.time()
|
| 106 |
|
| 107 |
-
# Ensure total duration is within reasonable bounds
|
| 108 |
-
total_duration = min(max(total_duration, 10),
|
| 109 |
-
chunk_duration = 15
|
| 110 |
-
num_chunks = max(2, (total_duration + chunk_duration - 1) // chunk_duration)
|
| 111 |
-
chunk_duration = total_duration / num_chunks
|
| 112 |
|
| 113 |
# Generate slightly longer chunks for overlap
|
| 114 |
-
overlap_duration = min(1.0, crossfade_duration / 1000.0)
|
| 115 |
-
generation_duration = chunk_duration + overlap_duration
|
| 116 |
|
| 117 |
-
# Initialize list to store audio chunks
|
| 118 |
audio_chunks = []
|
| 119 |
sample_rate = musicgen_model.sample_rate
|
| 120 |
|
| 121 |
-
# Generate audio in chunks with
|
| 122 |
for i in range(num_chunks):
|
| 123 |
-
#
|
| 124 |
-
if i == 0:
|
| 125 |
-
chunk_prompt = instrumental_prompt + ", focusing on a dynamic intro and expressive verse"
|
| 126 |
-
else:
|
| 127 |
-
chunk_prompt = instrumental_prompt + ", focusing on a powerful chorus and energetic outro"
|
| 128 |
|
| 129 |
print(f"Generating chunk {i+1}/{num_chunks} on GPU (prompt: {chunk_prompt})...")
|
| 130 |
musicgen_model.set_generation_params(
|
|
@@ -136,17 +129,15 @@ def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p
|
|
| 136 |
cfg_coef=cfg_scale
|
| 137 |
)
|
| 138 |
|
| 139 |
-
# Print resource usage before each chunk
|
| 140 |
print_resource_usage(f"Before Chunk {i+1} Generation")
|
| 141 |
|
| 142 |
with torch.no_grad():
|
| 143 |
-
with autocast():
|
| 144 |
-
audio_chunk = musicgen_model.generate([chunk_prompt], progress=True)[0]
|
| 145 |
|
| 146 |
-
# Normalize to stereo
|
| 147 |
audio_chunk = audio_chunk.cpu().to(dtype=torch.float32)
|
| 148 |
if audio_chunk.dim() == 1:
|
| 149 |
-
audio_chunk = torch.stack([audio_chunk, audio_chunk], dim=0)
|
| 150 |
elif audio_chunk.dim() == 2 and audio_chunk.shape[0] == 1:
|
| 151 |
audio_chunk = torch.cat([audio_chunk, audio_chunk], dim=0)
|
| 152 |
elif audio_chunk.dim() == 2 and audio_chunk.shape[0] != 2:
|
|
@@ -158,45 +149,37 @@ def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p
|
|
| 158 |
if audio_chunk.shape[0] != 2:
|
| 159 |
raise ValueError(f"Expected stereo audio with shape (2, samples), got shape {audio_chunk.shape}")
|
| 160 |
|
| 161 |
-
# Save chunk temporarily as WAV, then convert to MP3
|
| 162 |
temp_wav_path = f"temp_chunk_{i}.wav"
|
| 163 |
chunk_path = f"chunk_{i}.mp3"
|
| 164 |
torchaudio.save(temp_wav_path, audio_chunk, sample_rate, bits_per_sample=24)
|
| 165 |
segment = AudioSegment.from_wav(temp_wav_path)
|
| 166 |
-
segment = apply_limiter(segment, max_db=-8.0) # Apply limiter early to control peaks
|
| 167 |
segment.export(chunk_path, format="mp3", bitrate="320k")
|
| 168 |
-
os.remove(temp_wav_path)
|
| 169 |
audio_chunks.append(chunk_path)
|
| 170 |
|
| 171 |
-
# Free memory after generating each chunk
|
| 172 |
torch.cuda.empty_cache()
|
| 173 |
gc.collect()
|
| 174 |
-
time.sleep(0.5)
|
| 175 |
print_resource_usage(f"After Chunk {i+1} Generation")
|
| 176 |
|
| 177 |
-
# Combine chunks
|
| 178 |
print("Combining audio chunks...")
|
| 179 |
final_segment = AudioSegment.from_mp3(audio_chunks[0])
|
| 180 |
for i in range(1, len(audio_chunks)):
|
| 181 |
next_segment = AudioSegment.from_mp3(audio_chunks[i])
|
| 182 |
-
|
| 183 |
-
next_segment = next_segment + 2 # Boost by 2 dB to avoid amplitude dips
|
| 184 |
-
next_segment = apply_limiter(next_segment, max_db=-8.0) # Re-apply limiter after gain boost
|
| 185 |
final_segment = final_segment.append(next_segment, crossfade=crossfade_duration)
|
| 186 |
|
| 187 |
-
# Trim to exact total duration
|
| 188 |
final_segment = final_segment[:total_duration * 1000]
|
| 189 |
|
| 190 |
-
# Post-process
|
| 191 |
print("Post-processing final track...")
|
| 192 |
final_segment = apply_eq(final_segment)
|
| 193 |
final_segment = apply_chorus(final_segment)
|
|
|
|
|
|
|
| 194 |
|
| 195 |
-
# Apply final limiter and normalization with large headroom
|
| 196 |
-
final_segment = apply_limiter(final_segment, max_db=-8.0)
|
| 197 |
-
final_segment = final_segment.normalize(headroom=-10.0) # Large headroom to prevent clipping
|
| 198 |
-
|
| 199 |
-
# Export as MP3 only
|
| 200 |
mp3_path = "output_cleaned.mp3"
|
| 201 |
final_segment.export(
|
| 202 |
mp3_path,
|
|
@@ -206,11 +189,9 @@ def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p
|
|
| 206 |
)
|
| 207 |
print(f"Saved final audio to {mp3_path}")
|
| 208 |
|
| 209 |
-
# Clean up temporary chunk files
|
| 210 |
for chunk_path in audio_chunks:
|
| 211 |
os.remove(chunk_path)
|
| 212 |
|
| 213 |
-
# Print resource usage after generation
|
| 214 |
print_resource_usage("After Final Generation")
|
| 215 |
print(f"Total Generation Time: {time.time() - start_time:.2f} seconds")
|
| 216 |
|
|
@@ -224,7 +205,7 @@ def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p
|
|
| 224 |
def clear_inputs():
|
| 225 |
return "", 3.0, 300, 0.95, 1.0, 30, 500
|
| 226 |
|
| 227 |
-
# 7) CUSTOM CSS
|
| 228 |
css = """
|
| 229 |
body {
|
| 230 |
background: linear-gradient(135deg, #0A0A0A 0%, #1C2526 100%);
|
|
@@ -375,6 +356,10 @@ with gr.Blocks(css=css) as demo:
|
|
| 375 |
jazz_btn = gr.Button("Jazz", elem_classes="genre-btn")
|
| 376 |
classical_btn = gr.Button("Classical", elem_classes="genre-btn")
|
| 377 |
hiphop_btn = gr.Button("Hip-Hop", elem_classes="genre-btn")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
|
| 379 |
with gr.Column(elem_classes="settings-container"):
|
| 380 |
cfg_scale = gr.Slider(
|
|
@@ -412,10 +397,10 @@ with gr.Blocks(css=css) as demo:
|
|
| 412 |
total_duration = gr.Slider(
|
| 413 |
label="Total Duration (seconds)",
|
| 414 |
minimum=10,
|
| 415 |
-
maximum=
|
| 416 |
value=30,
|
| 417 |
step=1,
|
| 418 |
-
info="Total duration of the track (10 to
|
| 419 |
)
|
| 420 |
crossfade_duration = gr.Slider(
|
| 421 |
label="Crossfade Duration (ms)",
|
|
@@ -438,6 +423,10 @@ with gr.Blocks(css=css) as demo:
|
|
| 438 |
jazz_btn.click(set_jazz_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 439 |
classical_btn.click(set_classical_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 440 |
hiphop_btn.click(set_hiphop_prompt, inputs=None, outputs=[instrumental_prompt])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
gen_btn.click(
|
| 442 |
generate_music,
|
| 443 |
inputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, crossfade_duration],
|
|
@@ -449,17 +438,16 @@ with gr.Blocks(css=css) as demo:
|
|
| 449 |
outputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, crossfade_duration]
|
| 450 |
)
|
| 451 |
|
| 452 |
-
# 9) TURN OFF OPENAPI/DOCS
|
| 453 |
app = demo.launch(
|
| 454 |
server_name="0.0.0.0",
|
| 455 |
server_port=9999,
|
| 456 |
share=False,
|
| 457 |
inbrowser=False,
|
| 458 |
-
show_error=True
|
| 459 |
)
|
| 460 |
-
# Access the underlying FastAPI and disable its docs
|
| 461 |
try:
|
| 462 |
-
fastapi_app = demo._server.app
|
| 463 |
fastapi_app.docs_url = None
|
| 464 |
fastapi_app.redoc_url = None
|
| 465 |
fastapi_app.openapi_url = None
|
|
|
|
| 14 |
# Set PYTORCH_CUDA_ALLOC_CONF to manage memory fragmentation
|
| 15 |
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:32"
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
# Check critical dependencies
|
| 18 |
if np.__version__ != "1.23.5":
|
| 19 |
+
print(f"WARNING: NumPy version {np.__version__} is being used. This script was tested with numpy==1.23.5, but proceeding anyway.")
|
|
|
|
| 20 |
if not torch.__version__.startswith(("2.1.0", "2.3.1")):
|
| 21 |
print(f"WARNING: PyTorch version {torch.__version__} may not be compatible. Expected torch==2.1.0 or 2.3.1.")
|
| 22 |
|
|
|
|
| 47 |
print(f"GPU Memory Reserved: {torch.cuda.memory_reserved() / (1024**3):.2f} GB")
|
| 48 |
print("---------------")
|
| 49 |
|
| 50 |
+
# 4) GENRE PROMPT FUNCTIONS (Updated for consistency, more instruments, and popular styles)
|
| 51 |
def set_rock_prompt():
|
| 52 |
+
return "Hard rock with dynamic electric guitars, heavy steady drums, deep groovy bass, subtle organ layers, and a hint of Red Hot Chili Peppers' funky rock energy, maintaining a cohesive structure throughout"
|
| 53 |
|
| 54 |
def set_techno_prompt():
|
| 55 |
+
return "Techno with pulsing dark synths, driving basslines, fast rhythmic drums, atmospheric pads, and a Daft Punk-inspired house groove, keeping a consistent energetic flow"
|
| 56 |
|
| 57 |
def set_jazz_prompt():
|
| 58 |
+
return "Smooth jazz with warm saxophone leads, expressive piano chords, soft rhythmic drums, upright bass, and a Miles Davis-inspired improvisational feel, maintaining a cohesive smooth vibe"
|
| 59 |
|
| 60 |
def set_classical_prompt():
|
| 61 |
+
return "Classical orchestral piece with gentle strings, expressive piano, subtle woodwinds, dramatic brass, and a Bach-inspired baroque structure, keeping a consistent classical flow"
|
| 62 |
|
| 63 |
def set_hiphop_prompt():
|
| 64 |
+
return "Hip-hop with groovy deep bass, tight crisp drums, funky synths, vinyl scratches, and a modern trap influence, maintaining a consistent rhythmic groove"
|
| 65 |
+
|
| 66 |
+
def set_pop_rock_prompt():
|
| 67 |
+
return "Pop rock with catchy electric guitar riffs, uplifting vocals synths, steady drums, melodic basslines, and a U2-inspired anthemic feel, keeping a consistent uplifting vibe"
|
| 68 |
+
|
| 69 |
+
def set_fusion_jazz_prompt():
|
| 70 |
+
return "Fusion jazz with electric piano, funky basslines, intricate drum patterns, soaring trumpet, and a Herbie Hancock-inspired groove, maintaining a consistent fusion energy"
|
| 71 |
+
|
| 72 |
+
def set_baroque_classical_prompt():
|
| 73 |
+
return "Baroque classical with harpsichord, delicate violin, cello, flute, and a Vivaldi-inspired melodic structure, keeping a consistent baroque elegance"
|
| 74 |
+
|
| 75 |
+
def set_deep_house_prompt():
|
| 76 |
+
return "Deep house with warm synth chords, deep basslines, crisp hi-hats, soulful vocal chops, and a Carl Cox-inspired underground vibe, maintaining a consistent hypnotic groove"
|
| 77 |
|
| 78 |
# 5) AUDIO PROCESSING FUNCTIONS
|
| 79 |
def apply_chorus(segment):
|
| 80 |
# Enhanced chorus effect for richer sound
|
| 81 |
+
delayed = segment - 6 # Reduced gain to -6 dB for a subtler effect
|
| 82 |
delayed = delayed.set_frame_rate(segment.frame_rate)
|
| 83 |
+
return segment.overlay(delayed, position=20)
|
| 84 |
|
| 85 |
def apply_eq(segment):
|
| 86 |
+
# Adjusted EQ for a more balanced sound
|
| 87 |
+
segment = segment.low_pass_filter(8000) # Raised cutoff to 8kHz for brighter highs
|
| 88 |
+
segment = segment.high_pass_filter(80) # Lowered cutoff to 80Hz for deeper bass
|
| 89 |
return segment
|
| 90 |
|
| 91 |
+
def apply_limiter(segment, max_db=-3.0):
|
| 92 |
+
# Apply limiter with a higher threshold to preserve dynamics
|
| 93 |
if segment.dBFS > max_db:
|
| 94 |
+
segment = segment - (segment.dBFS - max_db)
|
| 95 |
return segment
|
| 96 |
|
| 97 |
# 6) GENERATION & I/O FUNCTIONS
|
| 98 |
def generate_music(instrumental_prompt: str, cfg_scale: float, top_k: int, top_p: float, temperature: float, total_duration: int, crossfade_duration: int):
|
| 99 |
+
global musicgen_model
|
| 100 |
if not instrumental_prompt.strip():
|
| 101 |
return None, "⚠️ Please enter a valid instrumental prompt!"
|
| 102 |
try:
|
|
|
|
| 103 |
start_time = time.time()
|
| 104 |
|
| 105 |
+
# Ensure total duration is within reasonable bounds (up to 90 seconds for longer tracks)
|
| 106 |
+
total_duration = min(max(total_duration, 10), 90)
|
| 107 |
+
chunk_duration = 15
|
| 108 |
+
num_chunks = max(2, (total_duration + chunk_duration - 1) // chunk_duration)
|
| 109 |
+
chunk_duration = total_duration / num_chunks
|
| 110 |
|
| 111 |
# Generate slightly longer chunks for overlap
|
| 112 |
+
overlap_duration = min(1.0, crossfade_duration / 1000.0)
|
| 113 |
+
generation_duration = chunk_duration + overlap_duration
|
| 114 |
|
|
|
|
| 115 |
audio_chunks = []
|
| 116 |
sample_rate = musicgen_model.sample_rate
|
| 117 |
|
| 118 |
+
# Generate audio in chunks with a consistent prompt
|
| 119 |
for i in range(num_chunks):
|
| 120 |
+
chunk_prompt = instrumental_prompt # Use the same prompt for all chunks
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
print(f"Generating chunk {i+1}/{num_chunks} on GPU (prompt: {chunk_prompt})...")
|
| 123 |
musicgen_model.set_generation_params(
|
|
|
|
| 129 |
cfg_coef=cfg_scale
|
| 130 |
)
|
| 131 |
|
|
|
|
| 132 |
print_resource_usage(f"Before Chunk {i+1} Generation")
|
| 133 |
|
| 134 |
with torch.no_grad():
|
| 135 |
+
with autocast():
|
| 136 |
+
audio_chunk = musicgen_model.generate([chunk_prompt], progress=True)[0]
|
| 137 |
|
|
|
|
| 138 |
audio_chunk = audio_chunk.cpu().to(dtype=torch.float32)
|
| 139 |
if audio_chunk.dim() == 1:
|
| 140 |
+
audio_chunk = torch.stack([audio_chunk, audio_chunk], dim=0)
|
| 141 |
elif audio_chunk.dim() == 2 and audio_chunk.shape[0] == 1:
|
| 142 |
audio_chunk = torch.cat([audio_chunk, audio_chunk], dim=0)
|
| 143 |
elif audio_chunk.dim() == 2 and audio_chunk.shape[0] != 2:
|
|
|
|
| 149 |
if audio_chunk.shape[0] != 2:
|
| 150 |
raise ValueError(f"Expected stereo audio with shape (2, samples), got shape {audio_chunk.shape}")
|
| 151 |
|
|
|
|
| 152 |
temp_wav_path = f"temp_chunk_{i}.wav"
|
| 153 |
chunk_path = f"chunk_{i}.mp3"
|
| 154 |
torchaudio.save(temp_wav_path, audio_chunk, sample_rate, bits_per_sample=24)
|
| 155 |
segment = AudioSegment.from_wav(temp_wav_path)
|
|
|
|
| 156 |
segment.export(chunk_path, format="mp3", bitrate="320k")
|
| 157 |
+
os.remove(temp_wav_path)
|
| 158 |
audio_chunks.append(chunk_path)
|
| 159 |
|
|
|
|
| 160 |
torch.cuda.empty_cache()
|
| 161 |
gc.collect()
|
| 162 |
+
time.sleep(0.5)
|
| 163 |
print_resource_usage(f"After Chunk {i+1} Generation")
|
| 164 |
|
| 165 |
+
# Combine chunks with crossfade
|
| 166 |
print("Combining audio chunks...")
|
| 167 |
final_segment = AudioSegment.from_mp3(audio_chunks[0])
|
| 168 |
for i in range(1, len(audio_chunks)):
|
| 169 |
next_segment = AudioSegment.from_mp3(audio_chunks[i])
|
| 170 |
+
next_segment = next_segment + 1 # Reduced gain boost to +1 dB
|
|
|
|
|
|
|
| 171 |
final_segment = final_segment.append(next_segment, crossfade=crossfade_duration)
|
| 172 |
|
| 173 |
+
# Trim to exact total duration
|
| 174 |
final_segment = final_segment[:total_duration * 1000]
|
| 175 |
|
| 176 |
+
# Post-process with improved dynamics
|
| 177 |
print("Post-processing final track...")
|
| 178 |
final_segment = apply_eq(final_segment)
|
| 179 |
final_segment = apply_chorus(final_segment)
|
| 180 |
+
final_segment = apply_limiter(final_segment, max_db=-3.0) # Apply limiter only once with higher threshold
|
| 181 |
+
final_segment = final_segment.normalize(headroom=-6.0) # Increased headroom to -6 dB
|
| 182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
mp3_path = "output_cleaned.mp3"
|
| 184 |
final_segment.export(
|
| 185 |
mp3_path,
|
|
|
|
| 189 |
)
|
| 190 |
print(f"Saved final audio to {mp3_path}")
|
| 191 |
|
|
|
|
| 192 |
for chunk_path in audio_chunks:
|
| 193 |
os.remove(chunk_path)
|
| 194 |
|
|
|
|
| 195 |
print_resource_usage("After Final Generation")
|
| 196 |
print(f"Total Generation Time: {time.time() - start_time:.2f} seconds")
|
| 197 |
|
|
|
|
| 205 |
def clear_inputs():
|
| 206 |
return "", 3.0, 300, 0.95, 1.0, 30, 500
|
| 207 |
|
| 208 |
+
# 7) CUSTOM CSS (Unchanged)
|
| 209 |
css = """
|
| 210 |
body {
|
| 211 |
background: linear-gradient(135deg, #0A0A0A 0%, #1C2526 100%);
|
|
|
|
| 356 |
jazz_btn = gr.Button("Jazz", elem_classes="genre-btn")
|
| 357 |
classical_btn = gr.Button("Classical", elem_classes="genre-btn")
|
| 358 |
hiphop_btn = gr.Button("Hip-Hop", elem_classes="genre-btn")
|
| 359 |
+
pop_rock_btn = gr.Button("Pop Rock", elem_classes="genre-btn")
|
| 360 |
+
fusion_jazz_btn = gr.Button("Fusion Jazz", elem_classes="genre-btn")
|
| 361 |
+
baroque_btn = gr.Button("Baroque Classical", elem_classes="genre-btn")
|
| 362 |
+
deep_house_btn = gr.Button("Deep House", elem_classes="genre-btn")
|
| 363 |
|
| 364 |
with gr.Column(elem_classes="settings-container"):
|
| 365 |
cfg_scale = gr.Slider(
|
|
|
|
| 397 |
total_duration = gr.Slider(
|
| 398 |
label="Total Duration (seconds)",
|
| 399 |
minimum=10,
|
| 400 |
+
maximum=90,
|
| 401 |
value=30,
|
| 402 |
step=1,
|
| 403 |
+
info="Total duration of the track (10 to 90 seconds)."
|
| 404 |
)
|
| 405 |
crossfade_duration = gr.Slider(
|
| 406 |
label="Crossfade Duration (ms)",
|
|
|
|
| 423 |
jazz_btn.click(set_jazz_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 424 |
classical_btn.click(set_classical_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 425 |
hiphop_btn.click(set_hiphop_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 426 |
+
pop_rock_btn.click(set_pop_rock_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 427 |
+
fusion_jazz_btn.click(set_fusion_jazz_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 428 |
+
baroque_btn.click(set_baroque_classical_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 429 |
+
deep_house_btn.click(set_deep_house_prompt, inputs=None, outputs=[instrumental_prompt])
|
| 430 |
gen_btn.click(
|
| 431 |
generate_music,
|
| 432 |
inputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, crossfade_duration],
|
|
|
|
| 438 |
outputs=[instrumental_prompt, cfg_scale, top_k, top_p, temperature, total_duration, crossfade_duration]
|
| 439 |
)
|
| 440 |
|
| 441 |
+
# 9) TURN OFF OPENAPI/DOCS
|
| 442 |
app = demo.launch(
|
| 443 |
server_name="0.0.0.0",
|
| 444 |
server_port=9999,
|
| 445 |
share=False,
|
| 446 |
inbrowser=False,
|
| 447 |
+
show_error=True
|
| 448 |
)
|
|
|
|
| 449 |
try:
|
| 450 |
+
fastapi_app = demo._server.app
|
| 451 |
fastapi_app.docs_url = None
|
| 452 |
fastapi_app.redoc_url = None
|
| 453 |
fastapi_app.openapi_url = None
|