ss
Browse files- README.md +12 -0
- app.py +24 -7
- 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 |
-
|
|
|
|
|
|
|
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 |
-
#
|
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."""
|