slslslrhfem commited on
Commit
bb3387d
ยท
1 Parent(s): 412ae23

change design

Browse files
Files changed (1) hide show
  1. app.py +51 -71
app.py CHANGED
@@ -14,9 +14,6 @@ token = os.getenv("HF_TOKEN")
14
 
15
  # Runtime installation of madmom
16
  def install_madmom():
17
- """
18
- Install madmom at runtime after Cython and numpy are available
19
- """
20
  try:
21
  import madmom
22
  print("โœ… madmom already installed")
@@ -42,19 +39,14 @@ try:
42
  from inference import inference
43
  except ImportError as e:
44
  print(f"โš ๏ธ Failed to import inference: {e}")
45
- print("This might be due to missing madmom dependency")
46
 
47
  def inference(audio_file):
48
  return {
49
  'matches': [],
50
- 'message': 'madmom dependency not available'
51
  }
52
 
53
  def download_data_from_hub():
54
- """
55
- Download covers80 and ml_models folders from Dataset repository
56
- (1005_e_4 file is handled by Git LFS in the main repo)
57
- """
58
  base_dir = Path(".")
59
  data_repo_id = "mippia/music-data"
60
 
@@ -64,7 +56,7 @@ def download_data_from_hub():
64
  # 1005_e_4 ํŒŒ์ผ์€ Git LFS๋กœ ์ด๋ฏธ ์žˆ๋Š”์ง€ ํ™•์ธ
65
  lfs_file = base_dir / "1005_e_4"
66
  if lfs_file.exists():
67
- file_size = lfs_file.stat().st_size / (1024*1024) # MB
68
  print(f"โœ… LFS file 1005_e_4: {file_size:.1f} MB")
69
  downloaded_folders["1005_e_4"] = str(lfs_file)
70
  else:
@@ -77,12 +69,10 @@ def download_data_from_hub():
77
 
78
  if not all_folders_exist:
79
  print(f"๐Ÿ“ฅ Downloading data folders from dataset: {data_repo_id}")
80
- print(f" This includes covers80 and ml_models folders (~17k+ files each)")
81
- print(f" 1005_e_4 file is handled by Git LFS in main repo")
82
  print(f" This may take several minutes...")
83
 
84
  try:
85
- # Dataset ์ €์žฅ์†Œ์—์„œ ์ „์ฒด ๋‹ค์šด๋กœ๋“œ
86
  downloaded_path = snapshot_download(
87
  repo_id=data_repo_id,
88
  repo_type="dataset",
@@ -94,7 +84,6 @@ def download_data_from_hub():
94
 
95
  print(f"โœ… Dataset downloaded successfully")
96
 
97
- # ๊ฐ ํด๋” ํ™•์ธ ๋ฐ ํŒŒ์ผ ์ˆ˜ ์นด์šดํŠธ
98
  for folder_name in folders_to_check:
99
  folder_path = base_dir / folder_name
100
  if folder_path.exists():
@@ -107,7 +96,6 @@ def download_data_from_hub():
107
 
108
  except Exception as e:
109
  print(f"โš ๏ธ Failed to download dataset: {e}")
110
- print(f" Dataset: {data_repo_id}")
111
  for folder_name in folders_to_check:
112
  downloaded_folders[folder_name] = None
113
  else:
@@ -124,9 +112,6 @@ def download_data_from_hub():
124
  return downloaded_folders
125
 
126
  def find_song_file_by_title(song_title):
127
- """
128
- covers80 ํด๋”์—์„œ ๊ณก ์ œ๋ชฉ์œผ๋กœ mp3 ํŒŒ์ผ์„ ์ฐพ์Œ
129
- """
130
  covers80_path = Path("covers80")
131
 
132
  if not covers80_path.exists():
@@ -144,10 +129,10 @@ def find_song_file_by_title(song_title):
144
  if matches:
145
  return str(matches[0])
146
 
147
- # ๋ถ€๋ถ„ ๋งค์น˜ ์‹œ๋„ (song_title์˜ ์ผ๋ถ€๋ถ„๋“ค๋กœ)
148
  song_parts = song_title.replace('_', ' ').split()
149
  for part in song_parts:
150
- if len(part) > 3: # ๋„ˆ๋ฌด ์งง์€ ๋‹จ์–ด๋Š” ์ œ์™ธ
151
  matches = list(covers80_path.glob(f"*{part}*.mp3"))
152
  if matches:
153
  return str(matches[0])
@@ -156,37 +141,33 @@ def find_song_file_by_title(song_title):
156
 
157
  @spaces.GPU
158
  def process_audio_for_matching(audio_file):
159
- """
160
- Process the uploaded audio file and return matching results with timestamp playback
161
- """
162
  if audio_file is None:
163
  return """
164
- <div style='text-align: center; color: #ff6b6b; padding: 30px; background: #fff5f5; border-radius: 15px; border: 2px dashed #ff6b6b;'>
165
- <h3>๐ŸŽต No Audio File</h3>
166
  <p>Please upload an audio file to get started!</p>
167
  </div>
168
  """
169
 
170
  try:
171
- # inference ํ•จ์ˆ˜ ํ˜ธ์ถœ
172
  result = inference(audio_file)
173
 
174
  if result.get('message') != 'success':
175
  return f"""
176
- <div style="text-align: center; padding: 25px; background: #fff3cd; border-radius: 15px; border: 1px solid #ffeaa7; margin: 10px 0;">
177
- <h3 style="color: #856404; margin-bottom: 15px;">โš ๏ธ No Matches Found</h3>
178
- <p style="color: #856404; font-size: 1.1em;">{result.get('message', 'Unknown error occurred')}</p>
179
- <p style="color: #856404; font-size: 0.9em; margin-top: 10px;">Try uploading a clearer audio sample or a different part of the song.</p>
180
  </div>
181
  """
182
 
183
  matches = result.get('matches', [])
184
  if not matches:
185
  return """
186
- <div style="text-align: center; padding: 25px; background: #fff3cd; border-radius: 15px; border: 1px solid #ffeaa7; margin: 10px 0;">
187
- <h3 style="color: #856404; margin-bottom: 15px;">๐Ÿ” No Matches Found</h3>
188
- <p style="color: #856404; font-size: 1.1em;">Sorry, we couldn't find any matching songs in our database.</p>
189
- <p style="color: #856404; font-size: 0.9em; margin-top: 10px;">Try uploading a different audio sample.</p>
190
  </div>
191
  """
192
 
@@ -200,8 +181,8 @@ def process_audio_for_matching(audio_file):
200
  library_time = match.get('library_time', 0)
201
 
202
  # ๋žญํ‚น์— ๋”ฐ๋ฅธ ์ƒ‰์ƒ ์„ค์ •
203
- rank_colors = {1: '#e74c3c', 2: '#f39c12', 3: '#27ae60'}
204
- rank_color = rank_colors.get(rank, '#7f8c8d')
205
 
206
  # ๊ณก ํŒŒ์ผ ์ฐพ๊ธฐ
207
  song_file_path = find_song_file_by_title(song_title)
@@ -209,7 +190,6 @@ def process_audio_for_matching(audio_file):
209
  # ์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด ์ƒ์„ฑ
210
  audio_player = ""
211
  if song_file_path and os.path.exists(song_file_path):
212
- # ์ƒ๋Œ€ ๊ฒฝ๋กœ๋กœ ๋ณ€๊ฒฝ
213
  rel_song_path = os.path.relpath(song_file_path)
214
  audio_player = f"""
215
  <div style="margin: 15px 0; padding: 15px; background: #f8fafc; border-radius: 8px;">
@@ -235,9 +215,9 @@ def process_audio_for_matching(audio_file):
235
  file_info = f"Found: {os.path.basename(song_file_path)}"
236
  else:
237
  audio_player = f"""
238
- <div style="margin: 10px 0; padding: 10px; background: #fff3cd; border-radius: 8px; text-align: center;">
239
- <p style="color: #856404; margin: 0;">๐Ÿ” Song file not found for playback</p>
240
- <p style="font-size: 0.8em; color: #856404; margin: 5px 0 0 0;">Match at {library_time:.1f}s in "{song_title}"</p>
241
  </div>
242
  """
243
  file_info = f"Song file not found: {song_title}"
@@ -246,52 +226,52 @@ def process_audio_for_matching(audio_file):
246
  <div style="background: #ffffff; border-radius: 12px; padding: 20px; margin: 15px 0;
247
  border-left: 5px solid {rank_color}; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
248
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
249
- <h3 style="color: #2c3e50; margin: 0; font-size: 1.2em;">
250
  <span style="background: {rank_color}; color: white; padding: 4px 8px; border-radius: 15px; font-size: 0.8em; margin-right: 10px;">
251
  #{rank}
252
  </span>
253
  {song_title}
254
  </h3>
255
- <span style="background: #ecf0f1; color: #2c3e50; padding: 6px 12px; border-radius: 20px; font-weight: 600;">
256
  {confidence}
257
  </span>
258
  </div>
259
 
260
- <div style="background: #f8f9fa; border-radius: 8px; padding: 12px; margin: 10px 0;">
261
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; text-align: center;">
262
  <div>
263
- <strong style="color: #3498db;">Your Audio</strong>
264
- <br><span style="color: #e74c3c; font-size: 1.1em;">{test_time:.1f}s</span>
265
  </div>
266
  <div>
267
- <strong style="color: #3498db;">Matched At</strong>
268
- <br><span style="color: #27ae60; font-size: 1.1em;">{library_time:.1f}s</span>
269
  </div>
270
  </div>
271
  </div>
272
 
273
  {audio_player}
274
 
275
- <div style="font-size: 0.9em; color: #7f8c8d; text-align: center; margin-top: 10px;">
276
- ๐Ÿ“ {file_info}
277
  </div>
278
  </div>
279
  """
280
 
281
  formatted_result = f"""
282
- <div style="background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-radius: 20px; padding: 30px;
283
- box-shadow: 0 8px 25px rgba(0,0,0,0.1); border: 1px solid #dee2e6; margin: 10px 0;">
284
  <div style="text-align: center; margin-bottom: 25px;">
285
- <h2 style="color: #2c3e50; margin-bottom: 10px; font-size: 1.8em;">๐ŸŽต Matching Results</h2>
286
- <p style="color: #7f8c8d; font-size: 1.1em;">Found {len(matches)} potential matches in our database</p>
287
  </div>
288
 
289
  {matches_html}
290
 
291
- <div style="text-align: center; margin-top: 25px; padding: 15px; background: #e8f5e8; border-radius: 10px;">
292
- <p style="color: #27ae60; margin: 0; font-size: 0.95em;">
293
- ๐Ÿ’ก <strong>How to read results:</strong> The times show where similar segments were found.
294
- Use the audio player to listen from the matched timestamp.
295
  </p>
296
  </div>
297
  </div>
@@ -308,14 +288,14 @@ def process_audio_for_matching(audio_file):
308
 
309
  except Exception as e:
310
  return f"""
311
- <div style="text-align: center; padding: 20px; background: #f8d7da; border-radius: 10px; border: 1px solid #f5c6cb; color: #721c24; margin: 10px 0;">
312
- <h3>โŒ Error Processing Audio</h3>
313
  <p>Error details: {str(e)}</p>
314
  <p style="font-size: 0.9em; margin-top: 10px;">Please try again with a different audio file.</p>
315
  </div>
316
  """
317
 
318
- # ๊น”๋”ํ•œ CSS ์Šคํƒ€์ผ
319
  custom_css = """
320
  .gradio-container {
321
  background: #f8fafc !important;
@@ -403,22 +383,22 @@ demo = gr.Interface(
403
  fn=process_audio_for_matching,
404
  inputs=gr.Audio(
405
  type="filepath",
406
- label="๐ŸŽต Upload Your Audio File",
407
  elem_classes=["upload-container"]
408
  ),
409
  outputs=gr.HTML(
410
- label="๐Ÿ” Similarity Results",
411
  elem_classes=["output-container"]
412
  ),
413
- title="๐ŸŽต Music Similarity Detector",
414
  description="""
415
- <div style="text-align: center; font-size: 1.1em; color: #555; margin: 25px 0; line-height: 1.6;">
416
- <p><strong>๐ŸŽฏ Upload any audio clip and find similar segments in our music database!</strong></p>
417
- <p>Our AI analyzes your audio and finds the most similar segments from known songs with precise timestamps.</p>
418
- <p style="font-size: 0.95em; color: #777; margin-top: 15px;">
419
- ๐Ÿ“ Supported formats: MP3, WAV, M4A, FLAC<br>
420
- โฑ๏ธ Processing time: ~15-30 seconds per file<br>
421
- ๐ŸŽผ Database: 160 songs with timestamp-based matching
422
  </p>
423
  </div>
424
  """,
@@ -426,7 +406,7 @@ demo = gr.Interface(
426
  css=custom_css,
427
  theme=gr.themes.Soft(
428
  primary_hue="blue",
429
- secondary_hue="purple",
430
  neutral_hue="gray",
431
  font=[gr.themes.GoogleFont("Inter"), "Arial", "sans-serif"]
432
  ),
 
14
 
15
  # Runtime installation of madmom
16
  def install_madmom():
 
 
 
17
  try:
18
  import madmom
19
  print("โœ… madmom already installed")
 
39
  from inference import inference
40
  except ImportError as e:
41
  print(f"โš ๏ธ Failed to import inference: {e}")
 
42
 
43
  def inference(audio_file):
44
  return {
45
  'matches': [],
46
+ 'message': 'inference module not available'
47
  }
48
 
49
  def download_data_from_hub():
 
 
 
 
50
  base_dir = Path(".")
51
  data_repo_id = "mippia/music-data"
52
 
 
56
  # 1005_e_4 ํŒŒ์ผ์€ Git LFS๋กœ ์ด๋ฏธ ์žˆ๋Š”์ง€ ํ™•์ธ
57
  lfs_file = base_dir / "1005_e_4"
58
  if lfs_file.exists():
59
+ file_size = lfs_file.stat().st_size / (1024*1024)
60
  print(f"โœ… LFS file 1005_e_4: {file_size:.1f} MB")
61
  downloaded_folders["1005_e_4"] = str(lfs_file)
62
  else:
 
69
 
70
  if not all_folders_exist:
71
  print(f"๐Ÿ“ฅ Downloading data folders from dataset: {data_repo_id}")
72
+ print(f" This includes covers80 and ml_models folders")
 
73
  print(f" This may take several minutes...")
74
 
75
  try:
 
76
  downloaded_path = snapshot_download(
77
  repo_id=data_repo_id,
78
  repo_type="dataset",
 
84
 
85
  print(f"โœ… Dataset downloaded successfully")
86
 
 
87
  for folder_name in folders_to_check:
88
  folder_path = base_dir / folder_name
89
  if folder_path.exists():
 
96
 
97
  except Exception as e:
98
  print(f"โš ๏ธ Failed to download dataset: {e}")
 
99
  for folder_name in folders_to_check:
100
  downloaded_folders[folder_name] = None
101
  else:
 
112
  return downloaded_folders
113
 
114
  def find_song_file_by_title(song_title):
 
 
 
115
  covers80_path = Path("covers80")
116
 
117
  if not covers80_path.exists():
 
129
  if matches:
130
  return str(matches[0])
131
 
132
+ # ๋ถ€๋ถ„ ๋งค์น˜ ์‹œ๋„
133
  song_parts = song_title.replace('_', ' ').split()
134
  for part in song_parts:
135
+ if len(part) > 3:
136
  matches = list(covers80_path.glob(f"*{part}*.mp3"))
137
  if matches:
138
  return str(matches[0])
 
141
 
142
  @spaces.GPU
143
  def process_audio_for_matching(audio_file):
 
 
 
144
  if audio_file is None:
145
  return """
146
+ <div style='text-align: center; color: #ef4444; padding: 30px; background: #fef2f2; border-radius: 12px; border: 2px dashed #fecaca;'>
147
+ <h3>No Audio File</h3>
148
  <p>Please upload an audio file to get started!</p>
149
  </div>
150
  """
151
 
152
  try:
 
153
  result = inference(audio_file)
154
 
155
  if result.get('message') != 'success':
156
  return f"""
157
+ <div style="text-align: center; padding: 25px; background: #fef3c7; border-radius: 12px; border: 1px solid #fde68a; margin: 10px 0;">
158
+ <h3 style="color: #92400e; margin-bottom: 15px;">No Matches Found</h3>
159
+ <p style="color: #92400e; font-size: 1.1em;">{result.get('message', 'Unknown error occurred')}</p>
160
+ <p style="color: #92400e; font-size: 0.9em; margin-top: 10px;">Try uploading a different vocal sample.</p>
161
  </div>
162
  """
163
 
164
  matches = result.get('matches', [])
165
  if not matches:
166
  return """
167
+ <div style="text-align: center; padding: 25px; background: #fef3c7; border-radius: 12px; border: 1px solid #fde68a; margin: 10px 0;">
168
+ <h3 style="color: #92400e; margin-bottom: 15px;">No Matches Found</h3>
169
+ <p style="color: #92400e; font-size: 1.1em;">Sorry, we couldn't find any matching vocals in our database.</p>
170
+ <p style="color: #92400e; font-size: 0.9em; margin-top: 10px;">Try uploading a different vocal sample.</p>
171
  </div>
172
  """
173
 
 
181
  library_time = match.get('library_time', 0)
182
 
183
  # ๋žญํ‚น์— ๋”ฐ๋ฅธ ์ƒ‰์ƒ ์„ค์ •
184
+ rank_colors = {1: '#ef4444', 2: '#f97316', 3: '#22c55e'}
185
+ rank_color = rank_colors.get(rank, '#6b7280')
186
 
187
  # ๊ณก ํŒŒ์ผ ์ฐพ๊ธฐ
188
  song_file_path = find_song_file_by_title(song_title)
 
190
  # ์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด ์ƒ์„ฑ
191
  audio_player = ""
192
  if song_file_path and os.path.exists(song_file_path):
 
193
  rel_song_path = os.path.relpath(song_file_path)
194
  audio_player = f"""
195
  <div style="margin: 15px 0; padding: 15px; background: #f8fafc; border-radius: 8px;">
 
215
  file_info = f"Found: {os.path.basename(song_file_path)}"
216
  else:
217
  audio_player = f"""
218
+ <div style="margin: 10px 0; padding: 10px; background: #fef3c7; border-radius: 8px; text-align: center;">
219
+ <p style="color: #92400e; margin: 0;">Song file not found for playback</p>
220
+ <p style="font-size: 0.8em; color: #92400e; margin: 5px 0 0 0;">Match at {library_time:.1f}s in "{song_title}"</p>
221
  </div>
222
  """
223
  file_info = f"Song file not found: {song_title}"
 
226
  <div style="background: #ffffff; border-radius: 12px; padding: 20px; margin: 15px 0;
227
  border-left: 5px solid {rank_color}; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
228
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
229
+ <h3 style="color: #1e293b; margin: 0; font-size: 1.2em;">
230
  <span style="background: {rank_color}; color: white; padding: 4px 8px; border-radius: 15px; font-size: 0.8em; margin-right: 10px;">
231
  #{rank}
232
  </span>
233
  {song_title}
234
  </h3>
235
+ <span style="background: #f1f5f9; color: #1e293b; padding: 6px 12px; border-radius: 20px; font-weight: 600;">
236
  {confidence}
237
  </span>
238
  </div>
239
 
240
+ <div style="background: #f8fafc; border-radius: 8px; padding: 12px; margin: 10px 0;">
241
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; text-align: center;">
242
  <div>
243
+ <strong style="color: #3b82f6;">Your Audio</strong>
244
+ <br><span style="color: #ef4444; font-size: 1.1em;">{test_time:.1f}s</span>
245
  </div>
246
  <div>
247
+ <strong style="color: #3b82f6;">Matched At</strong>
248
+ <br><span style="color: #22c55e; font-size: 1.1em;">{library_time:.1f}s</span>
249
  </div>
250
  </div>
251
  </div>
252
 
253
  {audio_player}
254
 
255
+ <div style="font-size: 0.9em; color: #64748b; text-align: center; margin-top: 10px;">
256
+ {file_info}
257
  </div>
258
  </div>
259
  """
260
 
261
  formatted_result = f"""
262
+ <div style="background: #ffffff; border-radius: 16px; padding: 30px;
263
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08); border: 1px solid #e2e8f0; margin: 10px 0;">
264
  <div style="text-align: center; margin-bottom: 25px;">
265
+ <h2 style="color: #1e293b; margin-bottom: 10px; font-size: 1.8em;">Vocal Matching Results</h2>
266
+ <p style="color: #64748b; font-size: 1.1em;">Found {len(matches)} similar vocals in Covers80 dataset</p>
267
  </div>
268
 
269
  {matches_html}
270
 
271
+ <div style="text-align: center; margin-top: 25px; padding: 15px; background: #f1f5f9; border-radius: 8px;">
272
+ <p style="color: #475569; margin: 0; font-size: 0.95em;">
273
+ <strong>How to read results:</strong> Vocal similarity scores with timestamp locations.
274
+ Play the audio to hear the matched vocal sections.
275
  </p>
276
  </div>
277
  </div>
 
288
 
289
  except Exception as e:
290
  return f"""
291
+ <div style="text-align: center; padding: 20px; background: #fef2f2; border-radius: 10px; border: 1px solid #fecaca; color: #991b1b; margin: 10px 0;">
292
+ <h3>Error Processing Audio</h3>
293
  <p>Error details: {str(e)}</p>
294
  <p style="font-size: 0.9em; margin-top: 10px;">Please try again with a different audio file.</p>
295
  </div>
296
  """
297
 
298
+ # CSS ์Šคํƒ€์ผ
299
  custom_css = """
300
  .gradio-container {
301
  background: #f8fafc !important;
 
383
  fn=process_audio_for_matching,
384
  inputs=gr.Audio(
385
  type="filepath",
386
+ label="Upload Your Audio File",
387
  elem_classes=["upload-container"]
388
  ),
389
  outputs=gr.HTML(
390
+ label="Similarity Results",
391
  elem_classes=["output-container"]
392
  ),
393
+ title="Music Similarity Detection",
394
  description="""
395
+ <div style="text-align: center; font-size: 1.1em; color: #64748b; margin: 25px 0; line-height: 1.6;">
396
+ <p><strong>Upload a vocal audio clip to find similar vocals in our database.</strong></p>
397
+ <p>This system analyzes vocal characteristics only - not instrumental parts.</p>
398
+ <p style="font-size: 0.95em; color: #94a3b8; margin-top: 15px;">
399
+ Supported formats: MP3, WAV, M4A, FLAC<br>
400
+ Database: Covers80 dataset (cover song vocals)<br>
401
+ Processing time: ~15-30 seconds
402
  </p>
403
  </div>
404
  """,
 
406
  css=custom_css,
407
  theme=gr.themes.Soft(
408
  primary_hue="blue",
409
+ secondary_hue="gray",
410
  neutral_hue="gray",
411
  font=[gr.themes.GoogleFont("Inter"), "Arial", "sans-serif"]
412
  ),