ChrodyFy / app.py
Renday's picture
Update app.py
d4f9017 verified
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("<h1 style='text-align:center;'>🎸 CHRODYFY ENGINE v4.1</h1>")
with gr.Row():
with gr.Column(scale=2):
audio_input = gr.Audio(type="filepath", label="1. Audio hochladen")
btn = gr.Button("🔥 ANALYSE STARTEN", variant="primary")
with gr.Column(scale=1):
bpm_output = gr.Label(label="Tempo")
download_file = gr.File(label="2. Download Chord-Sheet")
output_text = gr.Textbox(label="Vorschau", lines=15, interactive=False)
btn.click(fn=analyze_music, inputs=audio_input, outputs=[output_text, bpm_output, download_file])
if __name__ == "__main__":
demo.launch(css=".gradio-container {background-color: #0f172a; color: #facc15;}")