Spaces:
Sleeping
Sleeping
Gradio bug workaround
Browse files- app.py +21 -6
- src/neighbours.py +11 -6
app.py
CHANGED
|
@@ -19,6 +19,17 @@ import cfg
|
|
| 19 |
logging.basicConfig(level=logging.INFO)
|
| 20 |
logger = logging.getLogger(__name__)
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
# Load models and data
|
| 23 |
logging.info("Loading models and data...")
|
| 24 |
all_labels = pd.read_csv(cfg.LABELS_LOCATION)
|
|
@@ -139,9 +150,11 @@ def analyze_chord_sequence_text(chord_text: str) -> tuple[Optional[float], Optio
|
|
| 139 |
return None, None
|
| 140 |
|
| 141 |
def _format_chord_analysis_for_ui(chord_text):
|
|
|
|
| 142 |
score, neighbours = analyze_chord_sequence_text(chord_text)
|
| 143 |
if score is None:
|
| 144 |
-
|
|
|
|
| 145 |
scores_text = f"**Originality Score:** {score:.4f}"
|
| 146 |
neighbours_text = "**Similar Songs:**\n"
|
| 147 |
if neighbours:
|
|
@@ -152,7 +165,7 @@ def _format_chord_analysis_for_ui(chord_text):
|
|
| 152 |
neighbours_text += f"{i}. {title} by {artist} (similarity: {similarity:.3f})\n"
|
| 153 |
else:
|
| 154 |
neighbours_text += "No similar songs found."
|
| 155 |
-
|
| 156 |
|
| 157 |
|
| 158 |
def analyze_music_file(audio_file: str) -> tuple[str, float, list[dict]]:
|
|
@@ -169,9 +182,11 @@ def analyze_music_file(audio_file: str) -> tuple[str, float, list[dict]]:
|
|
| 169 |
return None, None, None
|
| 170 |
|
| 171 |
def _format_music_analysis_for_ui(audio_file):
|
|
|
|
| 172 |
file_info, score, neighbours = analyze_music_file(audio_file)
|
| 173 |
if score is None:
|
| 174 |
-
|
|
|
|
| 175 |
scores_text = f"**Originality Score:** {score:.4f}"
|
| 176 |
neighbours_text = "**Similar Songs:**\n"
|
| 177 |
if neighbours:
|
|
@@ -183,7 +198,7 @@ def _format_music_analysis_for_ui(audio_file):
|
|
| 183 |
else:
|
| 184 |
neighbours_text += "No similar songs found."
|
| 185 |
file_info_text = f"**File analyzed:** {file_info}" if file_info else ""
|
| 186 |
-
|
| 187 |
|
| 188 |
_preamble = (
|
| 189 |
"Enter chords separated by commas or spaces. "
|
|
@@ -237,9 +252,9 @@ with gr.Blocks(title="Harmonic Analysis Tool", theme=gr.themes.Soft()) as app:
|
|
| 237 |
|
| 238 |
with gr.Row():
|
| 239 |
with gr.Column(scale=1):
|
| 240 |
-
audio_input = gr.
|
| 241 |
label="Upload Audio File",
|
| 242 |
-
|
| 243 |
)
|
| 244 |
upload_btn = gr.Button("Analyze Audio", variant="primary")
|
| 245 |
|
|
|
|
| 19 |
logging.basicConfig(level=logging.INFO)
|
| 20 |
logger = logging.getLogger(__name__)
|
| 21 |
|
| 22 |
+
# Gradio 5.49 bug: monitoring/summary serialises function stats with integer keys,
|
| 23 |
+
# which orjson rejects. Patch _render to allow non-string keys.
|
| 24 |
+
import orjson
|
| 25 |
+
import gradio.routes as _gr_routes
|
| 26 |
+
|
| 27 |
+
@staticmethod
|
| 28 |
+
def _patched_render(content):
|
| 29 |
+
return orjson.dumps(content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY)
|
| 30 |
+
|
| 31 |
+
_gr_routes.ORJSONResponse._render = _patched_render
|
| 32 |
+
|
| 33 |
# Load models and data
|
| 34 |
logging.info("Loading models and data...")
|
| 35 |
all_labels = pd.read_csv(cfg.LABELS_LOCATION)
|
|
|
|
| 150 |
return None, None
|
| 151 |
|
| 152 |
def _format_chord_analysis_for_ui(chord_text):
|
| 153 |
+
yield "⏳ Analysing...", ""
|
| 154 |
score, neighbours = analyze_chord_sequence_text(chord_text)
|
| 155 |
if score is None:
|
| 156 |
+
yield "Please enter some chords!", ""
|
| 157 |
+
return
|
| 158 |
scores_text = f"**Originality Score:** {score:.4f}"
|
| 159 |
neighbours_text = "**Similar Songs:**\n"
|
| 160 |
if neighbours:
|
|
|
|
| 165 |
neighbours_text += f"{i}. {title} by {artist} (similarity: {similarity:.3f})\n"
|
| 166 |
else:
|
| 167 |
neighbours_text += "No similar songs found."
|
| 168 |
+
yield scores_text, neighbours_text
|
| 169 |
|
| 170 |
|
| 171 |
def analyze_music_file(audio_file: str) -> tuple[str, float, list[dict]]:
|
|
|
|
| 182 |
return None, None, None
|
| 183 |
|
| 184 |
def _format_music_analysis_for_ui(audio_file):
|
| 185 |
+
yield "", "⏳ Analysing...", ""
|
| 186 |
file_info, score, neighbours = analyze_music_file(audio_file)
|
| 187 |
if score is None:
|
| 188 |
+
yield "Please upload a music file!", "", ""
|
| 189 |
+
return
|
| 190 |
scores_text = f"**Originality Score:** {score:.4f}"
|
| 191 |
neighbours_text = "**Similar Songs:**\n"
|
| 192 |
if neighbours:
|
|
|
|
| 198 |
else:
|
| 199 |
neighbours_text += "No similar songs found."
|
| 200 |
file_info_text = f"**File analyzed:** {file_info}" if file_info else ""
|
| 201 |
+
yield file_info_text, scores_text, neighbours_text
|
| 202 |
|
| 203 |
_preamble = (
|
| 204 |
"Enter chords separated by commas or spaces. "
|
|
|
|
| 252 |
|
| 253 |
with gr.Row():
|
| 254 |
with gr.Column(scale=1):
|
| 255 |
+
audio_input = gr.File(
|
| 256 |
label="Upload Audio File",
|
| 257 |
+
file_types=["audio", ".mid", ".midi"],
|
| 258 |
)
|
| 259 |
upload_btn = gr.Button("Analyze Audio", variant="primary")
|
| 260 |
|
src/neighbours.py
CHANGED
|
@@ -45,15 +45,20 @@ class EmbeddingClosestNeighbours:
|
|
| 45 |
sorted_labels = labels[sorted_indices]
|
| 46 |
sorted_distances = distances[sorted_indices]
|
| 47 |
sorted_lengths = lengths[sorted_indices]
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
distance=float(sorted_distances[j]),
|
| 51 |
label=sorted_labels[j],
|
| 52 |
length=int(sorted_lengths[j]),
|
| 53 |
-
metadata=
|
| 54 |
-
)
|
| 55 |
-
for j in range(len(sorted_labels))
|
| 56 |
-
]
|
| 57 |
if limit is not None:
|
| 58 |
neighbours = neighbours[:limit]
|
| 59 |
all_neighbours.append(neighbours)
|
|
|
|
| 45 |
sorted_labels = labels[sorted_indices]
|
| 46 |
sorted_distances = distances[sorted_indices]
|
| 47 |
sorted_lengths = lengths[sorted_indices]
|
| 48 |
+
seen_songs = set()
|
| 49 |
+
neighbours = []
|
| 50 |
+
for j in range(len(sorted_labels)):
|
| 51 |
+
meta = self._metadata.loc[sorted_labels[j]].to_dict()
|
| 52 |
+
key = (meta.get('title'), meta.get('artist'))
|
| 53 |
+
if key in seen_songs:
|
| 54 |
+
continue
|
| 55 |
+
seen_songs.add(key)
|
| 56 |
+
neighbours.append(Neighbour(
|
| 57 |
distance=float(sorted_distances[j]),
|
| 58 |
label=sorted_labels[j],
|
| 59 |
length=int(sorted_lengths[j]),
|
| 60 |
+
metadata=meta,
|
| 61 |
+
))
|
|
|
|
|
|
|
| 62 |
if limit is not None:
|
| 63 |
neighbours = neighbours[:limit]
|
| 64 |
all_neighbours.append(neighbours)
|