# 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()