jacob-c commited on
Commit
8c42b47
·
1 Parent(s): d104d4e
Files changed (3) hide show
  1. README.md +12 -0
  2. app.py +24 -7
  3. beat_analysis.py +12 -5
README.md CHANGED
@@ -28,6 +28,17 @@ This Hugging Face Space application analyzes music files and generates lyrics th
28
  3. View the analysis results showing tempo, key, emotion, theme, and genre
29
  4. Check the generated lyrics tailored to match your music
30
 
 
 
 
 
 
 
 
 
 
 
 
31
  ## Technical Details
32
 
33
  This application uses:
@@ -44,6 +55,7 @@ See requirements.txt for detailed dependencies.
44
 
45
  - Large audio files may take longer to process
46
  - The quality of lyrics generation depends on the clarity of the audio and the detected musical features
 
47
 
48
  ## Credits
49
 
 
28
  3. View the analysis results showing tempo, key, emotion, theme, and genre
29
  4. Check the generated lyrics tailored to match your music
30
 
31
+ ## Supported Genres
32
+
33
+ Lyrics generation is currently limited to the following genres:
34
+ - **Pop**
35
+ - **Rock**
36
+ - **Country**
37
+ - **Disco**
38
+ - **Metal**
39
+
40
+ These genres have consistent syllable-to-beat relationships that work well with our beat-matching algorithm. For other genres, the application will still provide music analysis, but lyrics generation will be disabled.
41
+
42
  ## Technical Details
43
 
44
  This application uses:
 
55
 
56
  - Large audio files may take longer to process
57
  - The quality of lyrics generation depends on the clarity of the audio and the detected musical features
58
+ - Lyrics generation is restricted to specific genres (see Supported Genres section)
59
 
60
  ## Credits
61
 
app.py CHANGED
@@ -151,12 +151,6 @@ def process_audio(audio_file):
151
  genre_results_text = format_genre_results(top_genres)
152
  primary_genre = top_genres[0][0]
153
 
154
- # Generate lyrics using LLM
155
- lyrics = generate_lyrics(music_analysis, primary_genre, duration)
156
-
157
- # Create beat/stress/syllable matching analysis
158
- beat_match_analysis = analyze_lyrics_rhythm_match(lyrics, lyric_templates, primary_genre)
159
-
160
  # Prepare analysis summary
161
  analysis_summary = f"""
162
  ### Music Analysis Results
@@ -184,6 +178,19 @@ def process_audio(audio_file):
184
  - Phrase 2: {lyric_templates[1]['stress_pattern'] if len(lyric_templates) > 1 else 'N/A'}
185
  """
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  return analysis_summary, lyrics, tempo, time_signature, emotion, theme, primary_genre, beat_match_analysis
188
 
189
  except Exception as e:
@@ -594,13 +601,23 @@ def create_interface():
594
  emotion_output, theme_output, genre_output, beat_match_output]
595
  )
596
 
597
- gr.Markdown("""
 
 
 
598
  ## How it works
599
  1. Upload or record a music file
600
  2. The system analyzes tempo, beats, time signature and other musical features
601
  3. It detects emotion, theme, and music genre
602
  4. Using beat patterns and syllable stress analysis, it generates perfectly aligned lyrics
603
  5. Each line of the lyrics is matched to the beat pattern of the corresponding musical phrase
 
 
 
 
 
 
 
604
  """)
605
 
606
  return demo
 
151
  genre_results_text = format_genre_results(top_genres)
152
  primary_genre = top_genres[0][0]
153
 
 
 
 
 
 
 
154
  # Prepare analysis summary
155
  analysis_summary = f"""
156
  ### Music Analysis Results
 
178
  - Phrase 2: {lyric_templates[1]['stress_pattern'] if len(lyric_templates) > 1 else 'N/A'}
179
  """
180
 
181
+ # Check if genre is supported for lyrics generation
182
+ # Use the supported_genres list from BeatAnalyzer
183
+ genre_supported = any(genre.lower() in primary_genre.lower() for genre in beat_analyzer.supported_genres)
184
+
185
+ # Generate lyrics only for supported genres
186
+ if genre_supported:
187
+ lyrics = generate_lyrics(music_analysis, primary_genre, duration)
188
+ beat_match_analysis = analyze_lyrics_rhythm_match(lyrics, lyric_templates, primary_genre)
189
+ else:
190
+ supported_genres_str = ", ".join([genre.capitalize() for genre in beat_analyzer.supported_genres])
191
+ lyrics = f"Lyrics generation is only supported for the following genres: {supported_genres_str}.\n\nDetected genre '{primary_genre}' doesn't have strong syllable-to-beat patterns required for our lyric generation algorithm."
192
+ beat_match_analysis = "Lyrics generation not available for this genre."
193
+
194
  return analysis_summary, lyrics, tempo, time_signature, emotion, theme, primary_genre, beat_match_analysis
195
 
196
  except Exception as e:
 
601
  emotion_output, theme_output, genre_output, beat_match_output]
602
  )
603
 
604
+ # Format supported genres for display
605
+ supported_genres_md = "\n".join([f"- {genre.capitalize()}" for genre in beat_analyzer.supported_genres])
606
+
607
+ gr.Markdown(f"""
608
  ## How it works
609
  1. Upload or record a music file
610
  2. The system analyzes tempo, beats, time signature and other musical features
611
  3. It detects emotion, theme, and music genre
612
  4. Using beat patterns and syllable stress analysis, it generates perfectly aligned lyrics
613
  5. Each line of the lyrics is matched to the beat pattern of the corresponding musical phrase
614
+
615
+ ## Supported Genres
616
+ **Note:** Lyrics generation is currently only supported for the following genres:
617
+ {supported_genres_md}
618
+
619
+ These genres have consistent syllable-to-beat patterns that work well with our algorithm.
620
+ For other genres, only music analysis will be provided.
621
  """)
622
 
623
  return demo
beat_analysis.py CHANGED
@@ -32,25 +32,32 @@ class BeatAnalyzer:
32
 
33
  # Genre-specific syllable-to-beat ratio guidelines
34
  self.genre_syllable_ratios = {
35
- # Genre: (min_ratio, typical_ratio, max_ratio)
36
  'pop': (0.9, 1.5, 2.2), # Pop tends to have more syllables per beat
37
- 'rock': (0.8, 1.2, 1.8), # Rock can vary widely
 
 
 
 
 
38
  'hiphop': (1.8, 2.5, 3.5), # Hip hop often has many syllables per beat
39
  'rap': (2.0, 3.0, 4.0), # Rap often has very high syllable counts
40
  'folk': (0.8, 1.0, 1.3), # Folk often has close to 1:1 ratio
41
- 'country': (0.8, 1.2, 1.6), # Country tends to be moderate
42
  'jazz': (0.7, 1.0, 1.5), # Jazz can be very flexible
43
  'reggae': (0.7, 1.0, 1.3), # Reggae often emphasizes specific beats
44
  'soul': (0.8, 1.2, 1.6), # Soul music tends to be expressive
45
  'r&b': (1.0, 1.5, 2.0), # R&B can have melisma
46
  'electronic': (0.7, 1.0, 1.5), # Electronic music varies widely
47
- 'disco': (1.0, 1.5, 2.0), # Disco tends to have more syllables
48
  'classical': (0.7, 1.0, 1.4), # Classical can vary by subgenre
49
- 'metal': (0.8, 1.5, 2.0), # Metal often has more syllables on strong beats
50
  'blues': (0.6, 0.8, 1.2), # Blues often extends syllables
51
  'default': (0.9, 1.5, 2.0) # Default for unknown genres
52
  }
53
 
 
 
 
 
 
54
  @lru_cache(maxsize=128)
55
  def count_syllables(self, word):
56
  """Count syllables in a word using CMU dictionary if available, otherwise use rule-based method."""
 
32
 
33
  # Genre-specific syllable-to-beat ratio guidelines
34
  self.genre_syllable_ratios = {
35
+ # Supported genres with strong syllable-to-beat patterns
36
  'pop': (0.9, 1.5, 2.2), # Pop tends to have more syllables per beat
37
+ 'rock': (0.8, 1.2, 1.8), # Rock can vary widely but maintains beat alignment
38
+ 'country': (0.8, 1.2, 1.6), # Country tends to be moderate and clear in syllable matching
39
+ 'disco': (1.0, 1.5, 2.0), # Disco tends to have more syllables with clear beat patterns
40
+ 'metal': (0.8, 1.5, 2.0), # Metal often has more syllables on strong beats
41
+
42
+ # Other genres (analysis only, no lyrics generation)
43
  'hiphop': (1.8, 2.5, 3.5), # Hip hop often has many syllables per beat
44
  'rap': (2.0, 3.0, 4.0), # Rap often has very high syllable counts
45
  'folk': (0.8, 1.0, 1.3), # Folk often has close to 1:1 ratio
 
46
  'jazz': (0.7, 1.0, 1.5), # Jazz can be very flexible
47
  'reggae': (0.7, 1.0, 1.3), # Reggae often emphasizes specific beats
48
  'soul': (0.8, 1.2, 1.6), # Soul music tends to be expressive
49
  'r&b': (1.0, 1.5, 2.0), # R&B can have melisma
50
  'electronic': (0.7, 1.0, 1.5), # Electronic music varies widely
 
51
  'classical': (0.7, 1.0, 1.4), # Classical can vary by subgenre
 
52
  'blues': (0.6, 0.8, 1.2), # Blues often extends syllables
53
  'default': (0.9, 1.5, 2.0) # Default for unknown genres
54
  }
55
 
56
+ # List of genres supported for lyrics generation
57
+ # These genres have the most predictable and consistent syllable-to-beat relationships,
58
+ # making them ideal for our beat-matching algorithm
59
+ self.supported_genres = ['pop', 'rock', 'country', 'disco', 'metal']
60
+
61
  @lru_cache(maxsize=128)
62
  def count_syllables(self, word):
63
  """Count syllables in a word using CMU dictionary if available, otherwise use rule-based method."""