import gradio as gr import librosa import numpy as np import os def analyze_music(audio_path): if audio_path is None: return "FEHLER: Bitte lade eine Datei hoch.", "N/A", None if not os.path.exists(audio_path): return "SYSTEM-FEHLER: Datei nicht gefunden.", "N/A", None try: # 1. Audio laden y, sr = librosa.load(audio_path, sr=22050) # --- BPM ERKENNUNG (FIXED) --- y_perc = librosa.effects.percussive(y) # Librosa gibt hier oft ein Array zurück, wir nehmen den Mittelwert tempo_array, _ = librosa.beat.beat_track(y=y_perc, sr=sr) bpm_val = np.mean(tempo_array) bpm_display = f"{float(bpm_val):.1f} BPM" # --- AKKORD ERKENNUNG --- y_harm = librosa.effects.harmonic(y) chroma = librosa.feature.chroma_cqt(y=y_harm, sr=sr) noten = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] templates = { "Dur": [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], "Moll": [1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], "7": [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], "maj7": [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1] } report = f"GAMERJAM.DE - AI CHORD SHEET\n" report += f"Tempo: {bpm_display}\n" report += "----------------------------------------\n\n" report += "ZEIT | AKKORD\n" report += "----------|----------\n" letzter_akkord = "" for i in range(0, chroma.shape[1], 100): frame_chroma = chroma[:, i] best_score = -1 erkannter_name = "" for n in range(12): for typ, temp in templates.items(): rotated_temp = np.roll(temp, n) score = np.dot(frame_chroma, rotated_temp) if score > best_score: best_score = score erkannter_name = f"{noten[n]} {typ}" if erkannter_name != letzter_akkord: zeit = librosa.frames_to_time(i, sr=sr) report += f"{zeit:6.2f}s | {erkannter_name}\n" letzter_akkord = erkannter_name # Datei erstellen file_path = "gamerjam_chord_sheet.txt" with open(file_path, "w", encoding="utf-8") as f: f.write(report) return report, bpm_display, file_path except Exception as e: # Gibt den Fehler im Textfeld aus, falls doch noch was schiefläuft return f"ANALYSE-FEHLER: {str(e)}", "Fehler", None # --- GRADIO INTERFACE --- with gr.Blocks() as demo: gr.Markdown("