Turn audio into structured analysis and annotated visualizations for AI perception
Project description
sense-music
Turn audio into structured analysis and annotated visualizations for AI perception. Liner notes for an AI.
Built by humanjava.com — find this and other tools for the agentic age at huje.tools.
Install
pip install sense-music # core: sections, loops, key, energy, spectrogram, lyrics
pip install "sense-music[full]" # + deep perception (CLAP, madmom, Demucs, Qwen2-Audio)
Deep-perception layers are optional extras (embedding, rhythm, stems, caption, loudness) —
each degrades gracefully if its dependency is absent. ⚠️ On Python 3.12, madmom needs the git build
(pip install git+https://github.com/CPJKU/madmom.git); the PyPI 0.16.1 won't build on 3.12.
Security:
analyze()URL fetching is hardened against SSRF via redirects and DNS rebinding — per-hop address checks, DNS pinning to the vetted IP, a 5-hop redirect cap, and a streamed body size cap. SeeCHANGELOG.md.
Quick Start
from sense_music import analyze
result = analyze("song.mp3")
print(result.summary)
result.save("output/")
Full Example
from sense_music import analyze
result = analyze("song.mp3")
# Structured data
print(f"{result.bpm.tempo} BPM, {result.key.key} {result.key.mode}")
print(f"Genre: {result.genre}, Mood: {', '.join(result.mood)}")
# Sections
for s in result.sections:
print(f" {s.label}: {s.start:.1f}s — {s.end:.1f}s")
# Lyrics (requires whisper)
for line in result.lyrics:
print(f" [{line.start:.1f}s] {line.text}")
# Save everything
result.save("output/") # spectrogram.png, waveform.png, analysis.json, analysis.html
result.render_page("song.html") # self-contained HTML report
Skip Lyrics
If you don't have Whisper installed or want faster analysis:
result = analyze("song.mp3", lyrics=False)
What You Get
| Output | Description |
|---|---|
result.spectrogram |
PIL Image — annotated mel spectrogram with section markers and energy curve |
result.waveform |
PIL Image — waveform with colored section regions |
result.bpm |
BPMInfo(tempo, confidence) |
result.key |
KeyInfo(key, mode, confidence) |
result.sections |
List of Section(label, start, end) |
result.lyrics |
List of LyricLine(start, end, text) |
result.energy_curve |
Per-second normalized energy values |
result.genre |
Simple genre classification |
result.mood |
List of mood descriptors |
result.summary |
Natural language track description |
result.motifs |
Recurring LOOPS (Motif label, count, occurrences) — which sections reprise |
result.structure |
Motif sequence, e.g. "A-B-A-A-C-A" |
result.key_changes |
Modulation timeline (per-section key changes) |
result.rhythm |
madmom beats/downbeats/tempo + bar grid (rhythm=True) |
result.chords |
Chord progression + timeline (chords=True) |
result.loudness |
LUFS + crest factor |
result.clap_tags |
CLAP zero-shot semantic tags (clap_tags=True) |
result.embedding |
CLAP 512-d audio embedding — a similarity metric ("does this sound like X") (embedding=True) |
result.arrangement |
Demucs stem activity + element in/out timeline (stems=True) |
result.caption |
Qwen2-Audio free-text liner notes (caption=True) |
Deep perception (v0.3)
Each layer is an analyze() flag, fail-soft if its dep is missing:
result = analyze("song.mp3", rhythm=True, embedding=True, clap_tags=True,
chords=True, stems=True, caption=False)
- rhythm (madmom) — SOTA beat/downbeat tracking → the BAR grid (the thing video editors cut on).
- embedding + clap_tags (CLAP) — a 512-d audio embedding (the similarity metric) + zero-shot tags.
- stems (Demucs) — source separation → an arrangement timeline (which element enters/exits when).
- chords (madmom) — chord-progression recognition.
- caption (Qwen2-Audio) — natural-language "liner notes" (heavy; loads a 7B model).
Cut grid (for video editing)
from sense_music.cutgrid import edit_points, match_reference
pts = edit_points(result, snap=True) # bar-aligned, ranked edit points
hits = match_reference([4.1, 8.0, 12.2], result) # what song event each reference cut lands on
Dependencies
- librosa — audio analysis · matplotlib — visualization · Pillow — image handling
- openai-whisper — lyrics (optional via
lyrics=False) - Deep-perception extras: transformers (CLAP + Qwen2-Audio), madmom (beat/downbeat/chords), demucs (stems), pyloudnorm (LUFS)
Usage & Copyright
You are responsible for ensuring you have the legal right to analyze any audio you submit to this tool, whether running locally or via the hosted service at huje.tools. sense-music provides compute and analysis only — it does not store, host, or redistribute audio content. By using this tool, you accept full responsibility for the content you process and how you use the results.
For details, see huje.tools/support.
License
MIT — Humanjava Enterprises Inc.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sense_music-0.3.1.tar.gz.
File metadata
- Download URL: sense_music-0.3.1.tar.gz
- Upload date:
- Size: 39.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8422aa45af87745b4a65d5510445311c3654c3002bba04807e7ee149e7a19fef
|
|
| MD5 |
1f902067d33e1cbbf4da060d7819e3a7
|
|
| BLAKE2b-256 |
5b0a01e97145e9e441f37581dffec9e11ee9ac9588cc074985a4f061aefbcbc8
|
File details
Details for the file sense_music-0.3.1-py3-none-any.whl.
File metadata
- Download URL: sense_music-0.3.1-py3-none-any.whl
- Upload date:
- Size: 35.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1deae2461f5766c056be0c4c738fb2c676a65be4a484967eee72bd8620de469c
|
|
| MD5 |
17377bcb5289eb54e183edbf8f1f6fb5
|
|
| BLAKE2b-256 |
31cde09b755ffc818d80b4ff6f6a28e573d0636eadb85d6be08bc3a91e7ffe90
|