Spaces:
Running
Running
File size: 5,626 Bytes
ad47dc1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #!/usr/bin/env python3
"""
Audio Visualizer — Gradio Web Interface for Hugging Face Spaces
Upload audio, get 22 visualizations + a zip download ready for Claude.
"""
import matplotlib
matplotlib.use('Agg') # MUST be before any pyplot/librosa import
import gc
import shutil
import tempfile
from pathlib import Path
import gradio as gr
import librosa
import matplotlib.pyplot as plt
import numpy as np
import audio_visualizer
# All 22 visualization functions in order (mirrors the GUI list)
VISUALIZATIONS = [
("Waveform", audio_visualizer.plot_waveform),
("Volume Envelope", audio_visualizer.plot_waveform_envelope),
("Spectrogram", audio_visualizer.plot_spectrogram),
("Mel Spectrogram", audio_visualizer.plot_mel_spectrogram),
("Chromagram", audio_visualizer.plot_chromagram),
("Tonnetz", audio_visualizer.plot_tonnetz),
("Spectral Centroid", audio_visualizer.plot_spectral_centroid),
("Spectral Bandwidth", audio_visualizer.plot_spectral_bandwidth),
("Spectral Rolloff", audio_visualizer.plot_spectral_rolloff),
("RMS Energy", audio_visualizer.plot_rms_energy),
("Zero Crossing Rate", audio_visualizer.plot_zero_crossing_rate),
("Onset Strength", audio_visualizer.plot_onset_strength),
("Beat Tracking", audio_visualizer.plot_beat_track),
("Tempogram", audio_visualizer.plot_tempogram),
("MFCCs", audio_visualizer.plot_mfcc),
("Spectral Contrast", audio_visualizer.plot_spectral_contrast),
("Harmonic/Percussive", audio_visualizer.plot_harmonic_percussive),
("Frequency Bands", audio_visualizer.plot_frequency_bands),
("Dynamic Range", audio_visualizer.plot_dynamic_range),
("Spectral Flatness", audio_visualizer.plot_spectral_flatness),
("Combined Dashboard", audio_visualizer.plot_combined_dashboard),
("3D Spectrogram", audio_visualizer.plot_3d_spectrogram),
]
DPI_OPTIONS = {
"Normal (150 DPI)": 150,
"High (200 DPI)": 200,
"Ultra (300 DPI)": 300,
}
def generate_visualizations(audio_path, quality, progress=gr.Progress()):
"""Generate all 22 visualizations and return gallery images + zip file."""
if audio_path is None:
raise gr.Error("Please upload an audio file first.")
# Set DPI
audio_visualizer.FIGURE_DPI = DPI_OPTIONS.get(quality, 150)
# Load audio
progress(0, desc="Loading audio...")
y, sr = audio_visualizer.load_audio(audio_path)
duration = librosa.get_duration(y=y, sr=sr)
audio_file = Path(audio_path)
title = audio_file.stem
# Create temp output directory
output_tmp = tempfile.mkdtemp(prefix="avis_output_")
output_dir = Path(output_tmp)
# Generate each visualization
total = len(VISUALIZATIONS)
image_paths = []
for i, (name, func) in enumerate(VISUALIZATIONS):
progress((i) / total, desc=f"Generating: {name} ({i + 1}/{total})...")
if func == audio_visualizer.plot_combined_dashboard:
func(y, sr, output_dir, base_path=audio_file)
else:
func(y, sr, output_dir)
plt.close('all')
gc.collect()
# Create visualization guide
progress(0.95, desc="Creating visualization guide...")
tempo, _ = librosa.beat.beat_track(y=y, sr=sr)
audio_visualizer.create_visualization_guide(output_dir, duration, tempo, title)
# Collect all PNG paths (sorted by filename for correct order)
image_paths = sorted(output_dir.glob("*.png"))
# Create zip file
progress(0.98, desc="Creating zip archive...")
zip_tmp = tempfile.mkdtemp(prefix="avis_zip_")
zip_base = Path(zip_tmp) / f"{title}_visualizations"
zip_path = shutil.make_archive(str(zip_base), 'zip', output_dir)
progress(1.0, desc="Done!")
return image_paths, zip_path
# --- Build the Gradio interface ---
with gr.Blocks(
title="Audio Visualizer",
theme=gr.themes.Soft(),
) as demo:
gr.Markdown(
"""
# Audio Visualizer — Let Claude Hear Your Music
Upload any audio file to generate **22 visualizations** that translate sound into sight.
Download the zip and share it with Claude to let AI "listen" to your music.
"""
)
with gr.Row():
with gr.Column(scale=1):
audio_input = gr.Audio(
type="filepath",
label="Upload Audio File",
)
quality_radio = gr.Radio(
choices=list(DPI_OPTIONS.keys()),
value="Normal (150 DPI)",
label="Quality",
)
generate_btn = gr.Button("Generate Visualizations", variant="primary")
with gr.Column(scale=1):
gr.Markdown(
"""
### How it works
1. **Upload** an MP3, WAV, FLAC, OGG, or other audio file
2. **Choose quality** — higher DPI = sharper images but slower
3. **Click Generate** and wait for all 22 visualizations
4. **Download the zip** and upload it to a Claude conversation
Claude can analyze these images to describe the music's rhythm,
melody, dynamics, and texture — even though it can't hear the
audio directly.
"""
)
gallery = gr.Gallery(
label="Visualizations",
columns=4,
object_fit="contain",
height="auto",
)
zip_download = gr.File(label="Download All (Zip)")
generate_btn.click(
fn=generate_visualizations,
inputs=[audio_input, quality_radio],
outputs=[gallery, zip_download],
)
if __name__ == "__main__":
demo.launch()
|