jsd219's picture
Update app.py
ac2c136 verified
# app.py
import gradio as gr
import librosa
import numpy as np
def estimate_genre(filepath):
print(f"[DEBUG] Filepath received: {filepath}")
try:
y, sr = librosa.load(filepath, duration=30)
except Exception as e:
return {"Error": f"Failed to load audio: {str(e)}"}
try:
# Tempo
tempo_array, _ = librosa.beat.beat_track(y=y, sr=sr)
tempo = float(tempo_array)
# Spectral centroid (brightness)
centroid = librosa.feature.spectral_centroid(y=y, sr=sr)
centroid_mean = float(np.mean(centroid))
centroid_std = float(np.std(centroid))
# Chroma
chroma = librosa.feature.chroma_stft(y=y, sr=sr)
chroma_mean = float(np.mean(chroma))
chroma_std = float(np.std(chroma))
# Zero crossing rate
zcr = librosa.feature.zero_crossing_rate(y)
zcr_mean = float(np.mean(zcr))
# RMS (energy)
rms = librosa.feature.rms(y=y)
rms_mean = float(np.mean(rms))
except Exception as e:
return {"Error": f"Feature extraction failed: {str(e)}"}
# Heuristic genre rules (updated)
if tempo > 140 and centroid_mean > 2500 and rms_mean > 0.05:
genre = "Electronic / Dance"
elif tempo < 90 and chroma_mean < 0.3 and zcr_mean > 0.1:
genre = "Hip Hop / Trap"
elif 100 < tempo < 130 and centroid_mean > 2200 and chroma_std > 0.5:
genre = "Pop / Rock"
elif centroid_mean < 1800 and chroma_mean > 0.9 and rms_mean < 0.05:
genre = "Jazz / Soul"
else:
genre = "Unknown"
return {
"Predicted Genre": genre,
"Tempo (BPM)": round(float(tempo), 1),
"Brightness (Centroid Mean)": round(centroid_mean, 1),
"Brightness (Centroid Std)": round(centroid_std, 1),
"Chroma Mean": round(chroma_mean, 3),
"Chroma Std": round(chroma_std, 3),
"Zero Crossing Rate": round(zcr_mean, 4),
"RMS Energy": round(rms_mean, 4),
}
gr.Interface(
fn=estimate_genre,
inputs=gr.Audio(type="filepath", label="Upload audio file"),
outputs=gr.JSON(),
title="๐ŸŽถ Smarter Genre Estimator",
description="Estimates genre based on tempo, brightness, energy, and harmonic content using librosa features."
).launch()