| 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: |
| |
| y, sr = librosa.load(audio_path, sr=22050) |
| |
| |
| y_perc = librosa.effects.percussive(y) |
| |
| 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" |
|
|
| |
| 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 |
| |
| |
| 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: |
| |
| return f"ANALYSE-FEHLER: {str(e)}", "Fehler", None |
|
|
| |
| 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;}") |