root
commited on
Commit
·
e922466
1
Parent(s):
d6fb232
push
Browse files
app.py
CHANGED
|
@@ -2185,6 +2185,55 @@ Improved lyrics with fixed rhythm:
|
|
| 2185 |
# No analysis found, add a minimal one
|
| 2186 |
lyrics = lyrics + "\n\n[Note: Rhythm Analysis]\nNo rhythm issues detected. All syllables align well with the beat pattern."
|
| 2187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2188 |
return lyrics
|
| 2189 |
|
| 2190 |
def process_audio(audio_file):
|
|
@@ -2245,31 +2294,37 @@ def process_audio(audio_file):
|
|
| 2245 |
# Generate lyrics based on top genre, emotion analysis, and song structure
|
| 2246 |
try:
|
| 2247 |
primary_genre, _ = top_genres[0]
|
| 2248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2249 |
except Exception as e:
|
| 2250 |
print(f"Error generating lyrics: {str(e)}")
|
| 2251 |
lyrics = f"Error generating lyrics: {str(e)}"
|
|
|
|
|
|
|
|
|
|
| 2252 |
|
| 2253 |
# Prepare results dictionary with additional rhythm analysis
|
| 2254 |
results = {
|
| 2255 |
"genre_results": genre_results,
|
| 2256 |
"lyrics": lyrics,
|
|
|
|
|
|
|
|
|
|
| 2257 |
"ast_results": ast_results
|
| 2258 |
}
|
| 2259 |
|
| 2260 |
-
# Extract rhythm analysis if present in the lyrics
|
| 2261 |
-
if isinstance(lyrics, str) and "[Note: Rhythm Analysis]" in lyrics:
|
| 2262 |
-
clean_lyrics = lyrics.split("[Note: Rhythm Analysis]")[0].strip()
|
| 2263 |
-
rhythm_analysis = "[Note: Rhythm Analysis]" + lyrics.split("[Note: Rhythm Analysis]")[1]
|
| 2264 |
-
results["clean_lyrics"] = clean_lyrics
|
| 2265 |
-
results["rhythm_analysis"] = rhythm_analysis
|
| 2266 |
-
# Backwards compatibility with old format
|
| 2267 |
-
elif isinstance(lyrics, str) and "[Note: Potential rhythm mismatches" in lyrics:
|
| 2268 |
-
clean_lyrics = lyrics.split("[Note:")[0].strip()
|
| 2269 |
-
rhythm_analysis = "[Note:" + lyrics.split("[Note:")[1]
|
| 2270 |
-
results["clean_lyrics"] = clean_lyrics
|
| 2271 |
-
results["rhythm_analysis"] = rhythm_analysis
|
| 2272 |
-
|
| 2273 |
return results
|
| 2274 |
|
| 2275 |
except Exception as e:
|
|
@@ -2319,11 +2374,15 @@ with gr.Blocks(title="Music Genre Classifier & Lyrics Generator") as demo:
|
|
| 2319 |
|
| 2320 |
with gr.TabItem("Rhythm Analysis"):
|
| 2321 |
rhythm_analysis_output = gr.Textbox(label="Syllable-Beat Alignment Analysis", lines=16)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2322 |
|
| 2323 |
# Processing function with better handling of results
|
| 2324 |
def display_results(audio_file):
|
| 2325 |
if audio_file is None:
|
| 2326 |
-
return "Please upload an audio file.", "No emotion analysis available.", "No audio classification available.", "No lyrics generated.", "No rhythm analysis available."
|
| 2327 |
|
| 2328 |
try:
|
| 2329 |
# Process audio and get results
|
|
@@ -2331,9 +2390,9 @@ with gr.Blocks(title="Music Genre Classifier & Lyrics Generator") as demo:
|
|
| 2331 |
|
| 2332 |
# Check if we got an error message instead of results
|
| 2333 |
if isinstance(results, str) and "Error" in results:
|
| 2334 |
-
return results, "Error in analysis", "Error in classification", "No lyrics generated", "No rhythm analysis available"
|
| 2335 |
elif isinstance(results, tuple) and isinstance(results[0], str) and "Error" in results[0]:
|
| 2336 |
-
return results[0], "Error in analysis", "Error in classification", "No lyrics generated", "No rhythm analysis available"
|
| 2337 |
|
| 2338 |
# For backwards compatibility, handle both dictionary and tuple returns
|
| 2339 |
if isinstance(results, dict):
|
|
@@ -2344,6 +2403,10 @@ with gr.Blocks(title="Music Genre Classifier & Lyrics Generator") as demo:
|
|
| 2344 |
# Use clean lyrics if available
|
| 2345 |
clean_lyrics = results.get("clean_lyrics", lyrics)
|
| 2346 |
rhythm_analysis = results.get("rhythm_analysis", "No detailed rhythm analysis available")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2347 |
else:
|
| 2348 |
# Handle the old tuple return format
|
| 2349 |
genre_results, lyrics, ast_results = results
|
|
@@ -2360,6 +2423,10 @@ with gr.Blocks(title="Music Genre Classifier & Lyrics Generator") as demo:
|
|
| 2360 |
elif "[Note: Potential rhythm mismatches" in lyrics:
|
| 2361 |
clean_lyrics = lyrics.split("[Note:")[0].strip()
|
| 2362 |
rhythm_analysis = "[Note:" + lyrics.split("[Note:")[1]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2363 |
|
| 2364 |
# Format emotion analysis results
|
| 2365 |
try:
|
|
@@ -2412,19 +2479,19 @@ with gr.Blocks(title="Music Genre Classifier & Lyrics Generator") as demo:
|
|
| 2412 |
else:
|
| 2413 |
ast_text = "No valid audio classification results available."
|
| 2414 |
|
| 2415 |
-
# Return all results
|
| 2416 |
-
return genre_results, emotion_text, ast_text, clean_lyrics, rhythm_analysis
|
| 2417 |
|
| 2418 |
except Exception as e:
|
| 2419 |
error_msg = f"Error: {str(e)}"
|
| 2420 |
print(error_msg)
|
| 2421 |
-
return error_msg, "Error in emotion analysis", "Error in audio classification", "No lyrics generated", "No rhythm analysis available"
|
| 2422 |
|
| 2423 |
-
# Connect the button to the display function
|
| 2424 |
submit_btn.click(
|
| 2425 |
fn=display_results,
|
| 2426 |
inputs=[audio_input],
|
| 2427 |
-
outputs=[genre_output, emotion_output, ast_output, lyrics_output, rhythm_analysis_output]
|
| 2428 |
)
|
| 2429 |
|
| 2430 |
# Enhanced explanation of how the system works
|
|
|
|
| 2185 |
# No analysis found, add a minimal one
|
| 2186 |
lyrics = lyrics + "\n\n[Note: Rhythm Analysis]\nNo rhythm issues detected. All syllables align well with the beat pattern."
|
| 2187 |
|
| 2188 |
+
# Store the syllable guidance for later use
|
| 2189 |
+
syllable_guidance_text = syllable_guidance
|
| 2190 |
+
|
| 2191 |
+
# Before returning, add syllable analysis and prompt template
|
| 2192 |
+
if isinstance(lyrics, str):
|
| 2193 |
+
# Extract clean lyrics and analysis
|
| 2194 |
+
if "[Note: Rhythm Analysis]" in lyrics:
|
| 2195 |
+
clean_lyrics = lyrics.split("[Note: Rhythm Analysis]")[0].strip()
|
| 2196 |
+
rhythm_analysis = lyrics.split("[Note: Rhythm Analysis]")[1]
|
| 2197 |
+
elif "[Note: Potential rhythm mismatches" in lyrics:
|
| 2198 |
+
clean_lyrics = lyrics.split("[Note:")[0].strip()
|
| 2199 |
+
rhythm_analysis = "[Note:" + lyrics.split("[Note:")[1]
|
| 2200 |
+
else:
|
| 2201 |
+
clean_lyrics = lyrics
|
| 2202 |
+
rhythm_analysis = "No rhythm analysis available"
|
| 2203 |
+
|
| 2204 |
+
# Create syllable analysis
|
| 2205 |
+
syllable_analysis = "=== SYLLABLE ANALYSIS ===\n\n"
|
| 2206 |
+
if templates_for_verification:
|
| 2207 |
+
syllable_analysis += "Template Analysis:\n"
|
| 2208 |
+
for i, template in enumerate(templates_for_verification):
|
| 2209 |
+
syllable_analysis += f"Line {i+1}:\n"
|
| 2210 |
+
if isinstance(template, dict):
|
| 2211 |
+
if "syllable_template" in template:
|
| 2212 |
+
syllable_analysis += f" Template: {template['syllable_template']}\n"
|
| 2213 |
+
if "syllable_count" in template:
|
| 2214 |
+
syllable_analysis += f" Expected syllables: {template['syllable_count']}\n"
|
| 2215 |
+
elif isinstance(template, str):
|
| 2216 |
+
syllable_analysis += f" Template: {template}\n"
|
| 2217 |
+
syllable_analysis += "\n"
|
| 2218 |
+
|
| 2219 |
+
# Create prompt template
|
| 2220 |
+
prompt_template = "=== PROMPT TEMPLATE ===\n\n"
|
| 2221 |
+
prompt_template += "Genre: " + genre + "\n"
|
| 2222 |
+
prompt_template += f"Duration: {duration:.1f} seconds\n"
|
| 2223 |
+
prompt_template += f"Tempo: {tempo:.1f} BPM\n"
|
| 2224 |
+
prompt_template += f"Key: {key} {mode}\n"
|
| 2225 |
+
prompt_template += f"Primary Emotion: {primary_emotion}\n"
|
| 2226 |
+
prompt_template += f"Primary Theme: {primary_theme}\n\n"
|
| 2227 |
+
prompt_template += "Syllable Guidance:\n" + syllable_guidance_text
|
| 2228 |
+
|
| 2229 |
+
# Return all components
|
| 2230 |
+
return {
|
| 2231 |
+
"lyrics": clean_lyrics,
|
| 2232 |
+
"rhythm_analysis": rhythm_analysis,
|
| 2233 |
+
"syllable_analysis": syllable_analysis,
|
| 2234 |
+
"prompt_template": prompt_template
|
| 2235 |
+
}
|
| 2236 |
+
|
| 2237 |
return lyrics
|
| 2238 |
|
| 2239 |
def process_audio(audio_file):
|
|
|
|
| 2294 |
# Generate lyrics based on top genre, emotion analysis, and song structure
|
| 2295 |
try:
|
| 2296 |
primary_genre, _ = top_genres[0]
|
| 2297 |
+
lyrics_result = generate_lyrics(primary_genre, audio_data["duration"], emotion_results, song_structure)
|
| 2298 |
+
|
| 2299 |
+
# Handle both old and new return formats
|
| 2300 |
+
if isinstance(lyrics_result, dict):
|
| 2301 |
+
lyrics = lyrics_result["lyrics"]
|
| 2302 |
+
rhythm_analysis = lyrics_result["rhythm_analysis"]
|
| 2303 |
+
syllable_analysis = lyrics_result["syllable_analysis"]
|
| 2304 |
+
prompt_template = lyrics_result["prompt_template"]
|
| 2305 |
+
else:
|
| 2306 |
+
lyrics = lyrics_result
|
| 2307 |
+
rhythm_analysis = "No detailed rhythm analysis available"
|
| 2308 |
+
syllable_analysis = "No syllable analysis available"
|
| 2309 |
+
prompt_template = "No prompt template available"
|
| 2310 |
+
|
| 2311 |
except Exception as e:
|
| 2312 |
print(f"Error generating lyrics: {str(e)}")
|
| 2313 |
lyrics = f"Error generating lyrics: {str(e)}"
|
| 2314 |
+
rhythm_analysis = "No rhythm analysis available"
|
| 2315 |
+
syllable_analysis = "No syllable analysis available"
|
| 2316 |
+
prompt_template = "No prompt template available"
|
| 2317 |
|
| 2318 |
# Prepare results dictionary with additional rhythm analysis
|
| 2319 |
results = {
|
| 2320 |
"genre_results": genre_results,
|
| 2321 |
"lyrics": lyrics,
|
| 2322 |
+
"rhythm_analysis": rhythm_analysis,
|
| 2323 |
+
"syllable_analysis": syllable_analysis,
|
| 2324 |
+
"prompt_template": prompt_template,
|
| 2325 |
"ast_results": ast_results
|
| 2326 |
}
|
| 2327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2328 |
return results
|
| 2329 |
|
| 2330 |
except Exception as e:
|
|
|
|
| 2374 |
|
| 2375 |
with gr.TabItem("Rhythm Analysis"):
|
| 2376 |
rhythm_analysis_output = gr.Textbox(label="Syllable-Beat Alignment Analysis", lines=16)
|
| 2377 |
+
|
| 2378 |
+
with gr.TabItem("Syllable Analysis"):
|
| 2379 |
+
syllable_analysis_output = gr.Textbox(label="Detailed Syllable Analysis", lines=16)
|
| 2380 |
+
prompt_template_output = gr.Textbox(label="Prompt Template", lines=16)
|
| 2381 |
|
| 2382 |
# Processing function with better handling of results
|
| 2383 |
def display_results(audio_file):
|
| 2384 |
if audio_file is None:
|
| 2385 |
+
return "Please upload an audio file.", "No emotion analysis available.", "No audio classification available.", "No lyrics generated.", "No rhythm analysis available.", "No syllable analysis available.", "No prompt template available."
|
| 2386 |
|
| 2387 |
try:
|
| 2388 |
# Process audio and get results
|
|
|
|
| 2390 |
|
| 2391 |
# Check if we got an error message instead of results
|
| 2392 |
if isinstance(results, str) and "Error" in results:
|
| 2393 |
+
return results, "Error in analysis", "Error in classification", "No lyrics generated", "No rhythm analysis available", "No syllable analysis available", "No prompt template available"
|
| 2394 |
elif isinstance(results, tuple) and isinstance(results[0], str) and "Error" in results[0]:
|
| 2395 |
+
return results[0], "Error in analysis", "Error in classification", "No lyrics generated", "No rhythm analysis available", "No syllable analysis available", "No prompt template available"
|
| 2396 |
|
| 2397 |
# For backwards compatibility, handle both dictionary and tuple returns
|
| 2398 |
if isinstance(results, dict):
|
|
|
|
| 2403 |
# Use clean lyrics if available
|
| 2404 |
clean_lyrics = results.get("clean_lyrics", lyrics)
|
| 2405 |
rhythm_analysis = results.get("rhythm_analysis", "No detailed rhythm analysis available")
|
| 2406 |
+
|
| 2407 |
+
# Extract syllable analysis and prompt template
|
| 2408 |
+
syllable_analysis = results.get("syllable_analysis", "No syllable analysis available")
|
| 2409 |
+
prompt_template = results.get("prompt_template", "No prompt template available")
|
| 2410 |
else:
|
| 2411 |
# Handle the old tuple return format
|
| 2412 |
genre_results, lyrics, ast_results = results
|
|
|
|
| 2423 |
elif "[Note: Potential rhythm mismatches" in lyrics:
|
| 2424 |
clean_lyrics = lyrics.split("[Note:")[0].strip()
|
| 2425 |
rhythm_analysis = "[Note:" + lyrics.split("[Note:")[1]
|
| 2426 |
+
|
| 2427 |
+
# Default values for new fields
|
| 2428 |
+
syllable_analysis = "No syllable analysis available"
|
| 2429 |
+
prompt_template = "No prompt template available"
|
| 2430 |
|
| 2431 |
# Format emotion analysis results
|
| 2432 |
try:
|
|
|
|
| 2479 |
else:
|
| 2480 |
ast_text = "No valid audio classification results available."
|
| 2481 |
|
| 2482 |
+
# Return all results including new fields
|
| 2483 |
+
return genre_results, emotion_text, ast_text, clean_lyrics, rhythm_analysis, syllable_analysis, prompt_template
|
| 2484 |
|
| 2485 |
except Exception as e:
|
| 2486 |
error_msg = f"Error: {str(e)}"
|
| 2487 |
print(error_msg)
|
| 2488 |
+
return error_msg, "Error in emotion analysis", "Error in audio classification", "No lyrics generated", "No rhythm analysis available", "No syllable analysis available", "No prompt template available"
|
| 2489 |
|
| 2490 |
+
# Connect the button to the display function with updated outputs
|
| 2491 |
submit_btn.click(
|
| 2492 |
fn=display_results,
|
| 2493 |
inputs=[audio_input],
|
| 2494 |
+
outputs=[genre_output, emotion_output, ast_output, lyrics_output, rhythm_analysis_output, syllable_analysis_output, prompt_template_output]
|
| 2495 |
)
|
| 2496 |
|
| 2497 |
# Enhanced explanation of how the system works
|