root commited on
Commit
db4c558
·
1 Parent(s): 38b696f
Files changed (1) hide show
  1. app.py +39 -117
app.py CHANGED
@@ -357,36 +357,40 @@ def calculate_detailed_song_structure(audio_data):
357
  "syllables": syllables_info
358
  }
359
 
360
- def generate_lyrics(genre, duration, emotion_results, song_structure=None):
361
- """Generate lyrics based on genre, duration, emotion, and detailed song structure."""
362
- # If no song structure is provided, fall back to the original approach
363
- if song_structure is None:
364
- # Calculate appropriate lyrics length based on audio duration
365
- lines_count = calculate_lyrics_length(duration)
366
-
367
- # Calculate approximate number of verses and chorus
368
- if lines_count <= 6:
369
- # Very short song - one verse and chorus
370
- verse_lines = 2
371
- chorus_lines = 2
372
- elif lines_count <= 10:
373
- # Medium song - two verses and chorus
374
- verse_lines = 3
375
- chorus_lines = 2
376
- else:
377
- # Longer song - two verses, chorus, and bridge
378
- verse_lines = 3
379
- chorus_lines = 2
380
-
381
- # Extract emotion and theme data from analysis results
382
- primary_emotion = emotion_results["emotion_analysis"]["primary_emotion"]
383
- primary_theme = emotion_results["theme_analysis"]["primary_theme"]
384
- tempo = emotion_results["rhythm_analysis"]["tempo"]
385
- key = emotion_results["tonal_analysis"]["key"]
386
- mode = emotion_results["tonal_analysis"]["mode"]
 
387
 
388
- # Create prompt for the LLM
389
- prompt = f"""
 
 
 
390
  You are a talented songwriter who specializes in {genre} music.
391
  Write original {genre} song lyrics for a song that is {duration:.1f} seconds long.
392
 
@@ -409,60 +413,6 @@ The lyrics should:
409
  - Match the song duration of {duration:.1f} seconds
410
  - Keep each line concise and impactful
411
 
412
- Your lyrics:
413
- """
414
-
415
- else:
416
- # Extract emotion and theme data from analysis results
417
- primary_emotion = emotion_results["emotion_analysis"]["primary_emotion"]
418
- primary_theme = emotion_results["theme_analysis"]["primary_theme"]
419
- tempo = emotion_results["rhythm_analysis"]["tempo"]
420
- key = emotion_results["tonal_analysis"]["key"]
421
- mode = emotion_results["tonal_analysis"]["mode"]
422
-
423
- # Create detailed structure instructions for the LLM
424
- structure_instructions = "Follow this exact song structure with specified syllable counts:\n"
425
-
426
- for section in song_structure["syllables"]:
427
- section_type = section["type"].capitalize()
428
- start_time = f"{section['start']:.1f}"
429
- end_time = f"{section['end']:.1f}"
430
- duration = f"{section['duration']:.1f}"
431
- beat_count = section["beat_count"]
432
- syllable_count = section["syllable_count"]
433
-
434
- structure_instructions += f"* {section_type} ({start_time}s - {end_time}s, {duration}s duration):\n"
435
- structure_instructions += f" - {beat_count} beats\n"
436
- structure_instructions += f" - Approximately {syllable_count} syllables\n"
437
-
438
- # Calculate approximate total number of lines based on syllables
439
- total_syllables = sum(section["syllable_count"] for section in song_structure["syllables"])
440
- estimated_lines = max(4, int(total_syllables / 8)) # Rough estimate: average 8 syllables per line
441
-
442
- # Create prompt for the LLM
443
- prompt = f"""
444
- You are a talented songwriter who specializes in {genre} music.
445
- Write original {genre} song lyrics for a song that is {duration:.1f} seconds long.
446
-
447
- Music analysis has detected the following qualities in the music:
448
- - Tempo: {tempo:.1f} BPM
449
- - Key: {key} {mode}
450
- - Primary emotion: {primary_emotion}
451
- - Primary theme: {primary_theme}
452
-
453
- {structure_instructions}
454
-
455
- The lyrics should:
456
- - Perfectly capture the essence and style of {genre} music
457
- - Express the {primary_emotion} emotion and {primary_theme} theme
458
- - Have approximately {estimated_lines} lines total, distributed across sections
459
- - For each line, include a syllable count that matches the beats in that section
460
- - Include timestamps [MM:SS] at the beginning of each section
461
- - Be completely original
462
- - Match the exact song structure provided above
463
-
464
- Important: Each section should have lyrics with syllable counts matching the beats!
465
-
466
  Your lyrics:
467
  """
468
 
@@ -479,50 +429,21 @@ Your lyrics:
479
  # Extract and clean generated lyrics
480
  lyrics = response[0]["generated_text"].strip()
481
 
482
- # Add section labels if they're not present (in fallback mode)
483
- if song_structure is None and "Verse" not in lyrics and "Chorus" not in lyrics:
484
  lines = lyrics.split('\n')
485
  formatted_lyrics = []
486
  current_section = "Verse"
487
- verse_count = 0
488
-
489
  for i, line in enumerate(lines):
490
  if i == 0:
491
  formatted_lyrics.append("[Verse]")
492
- verse_count = 1
493
  elif i == verse_lines:
494
  formatted_lyrics.append("\n[Chorus]")
495
  elif i == verse_lines + chorus_lines and lines_count > 10:
496
  formatted_lyrics.append("\n[Bridge]")
497
- elif i == verse_lines + chorus_lines + (2 if lines_count > 10 else 0):
498
- formatted_lyrics.append("\n[Verse]")
499
- verse_count = 2
500
  formatted_lyrics.append(line)
501
-
502
  lyrics = '\n'.join(formatted_lyrics)
503
 
504
- # Add timestamps in detailed mode if needed
505
- elif song_structure is not None:
506
- # Ensure the lyrics have proper section headings with timestamps
507
- for section in song_structure["syllables"]:
508
- section_type = section["type"].capitalize()
509
- start_time_str = f"{int(section['start']) // 60:02d}:{int(section['start']) % 60:02d}"
510
- section_header = f"[{start_time_str}] {section_type}"
511
-
512
- # Check if this section header is missing and add it if needed
513
- if section_header not in lyrics and section["type"] not in ["intro", "outro"]:
514
- # Find where this section might be based on timestamp
515
- time_matches = [
516
- idx for idx, line in enumerate(lyrics.split('\n'))
517
- if f"{int(section['start']) // 60:02d}:{int(section['start']) % 60:02d}" in line
518
- ]
519
-
520
- if time_matches:
521
- lines = lyrics.split('\n')
522
- line_idx = time_matches[0]
523
- lines[line_idx] = section_header
524
- lyrics = '\n'.join(lines)
525
-
526
  return lyrics
527
 
528
  def process_audio(audio_file):
@@ -563,7 +484,8 @@ def process_audio(audio_file):
563
  "emotion_analysis": {"primary_emotion": "Unknown"},
564
  "theme_analysis": {"primary_theme": "Unknown"},
565
  "rhythm_analysis": {"tempo": 0},
566
- "tonal_analysis": {"key": "Unknown", "mode": ""}
 
567
  }
568
 
569
  # Calculate detailed song structure for better lyrics alignment
@@ -574,10 +496,10 @@ def process_audio(audio_file):
574
  # Continue with a simpler approach if this fails
575
  song_structure = None
576
 
577
- # Generate lyrics based on top genre, emotion analysis, and song structure
578
  try:
579
  primary_genre, _ = top_genres[0]
580
- lyrics = generate_lyrics(primary_genre, audio_data["duration"], emotion_results, song_structure)
581
  except Exception as e:
582
  print(f"Error generating lyrics: {str(e)}")
583
  lyrics = f"Error generating lyrics: {str(e)}"
 
357
  "syllables": syllables_info
358
  }
359
 
360
+ def generate_lyrics(genre, duration, emotion_results):
361
+ """Generate lyrics based on the genre and with appropriate length."""
362
+ # Calculate appropriate lyrics length based on audio duration
363
+ lines_count = calculate_lyrics_length(duration)
364
+
365
+ # Calculate approximate number of verses and chorus
366
+ if lines_count <= 6:
367
+ # Very short song - one verse and chorus
368
+ verse_lines = 2
369
+ chorus_lines = 2
370
+ elif lines_count <= 10:
371
+ # Medium song - two verses and chorus
372
+ verse_lines = 3
373
+ chorus_lines = 2
374
+ else:
375
+ # Longer song - two verses, chorus, and bridge
376
+ verse_lines = 3
377
+ chorus_lines = 2
378
+
379
+ # Extract emotion and theme data from analysis results
380
+ primary_emotion = emotion_results["emotion_analysis"]["primary_emotion"]
381
+ primary_theme = emotion_results["theme_analysis"]["primary_theme"]
382
+
383
+ # Extract numeric values safely with fallbacks
384
+ try:
385
+ tempo = float(emotion_results["rhythm_analysis"]["tempo"])
386
+ except (KeyError, ValueError, TypeError):
387
+ tempo = 0.0
388
 
389
+ key = emotion_results["tonal_analysis"]["key"]
390
+ mode = emotion_results["tonal_analysis"]["mode"]
391
+
392
+ # Create prompt for the LLM
393
+ prompt = f"""
394
  You are a talented songwriter who specializes in {genre} music.
395
  Write original {genre} song lyrics for a song that is {duration:.1f} seconds long.
396
 
 
413
  - Match the song duration of {duration:.1f} seconds
414
  - Keep each line concise and impactful
415
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  Your lyrics:
417
  """
418
 
 
429
  # Extract and clean generated lyrics
430
  lyrics = response[0]["generated_text"].strip()
431
 
432
+ # Add section labels if they're not present
433
+ if "Verse" not in lyrics and "Chorus" not in lyrics:
434
  lines = lyrics.split('\n')
435
  formatted_lyrics = []
436
  current_section = "Verse"
 
 
437
  for i, line in enumerate(lines):
438
  if i == 0:
439
  formatted_lyrics.append("[Verse]")
 
440
  elif i == verse_lines:
441
  formatted_lyrics.append("\n[Chorus]")
442
  elif i == verse_lines + chorus_lines and lines_count > 10:
443
  formatted_lyrics.append("\n[Bridge]")
 
 
 
444
  formatted_lyrics.append(line)
 
445
  lyrics = '\n'.join(formatted_lyrics)
446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  return lyrics
448
 
449
  def process_audio(audio_file):
 
484
  "emotion_analysis": {"primary_emotion": "Unknown"},
485
  "theme_analysis": {"primary_theme": "Unknown"},
486
  "rhythm_analysis": {"tempo": 0},
487
+ "tonal_analysis": {"key": "Unknown", "mode": ""},
488
+ "summary": {"tempo": 0, "key": "Unknown", "mode": "", "primary_emotion": "Unknown", "primary_theme": "Unknown"}
489
  }
490
 
491
  # Calculate detailed song structure for better lyrics alignment
 
496
  # Continue with a simpler approach if this fails
497
  song_structure = None
498
 
499
+ # Generate lyrics based on top genre and emotion analysis
500
  try:
501
  primary_genre, _ = top_genres[0]
502
+ lyrics = generate_lyrics(primary_genre, audio_data["duration"], emotion_results)
503
  except Exception as e:
504
  print(f"Error generating lyrics: {str(e)}")
505
  lyrics = f"Error generating lyrics: {str(e)}"