What is it?
Sonoglyph is a Python library and CLI tool that analyzes audio files and extracts musical features: tempo, key, mood, spectral characteristics, energy, and more. Works out of the box with no ML dependencies, optionally plugs in neural network backends for higher accuracy.
Use cases:
- 🎧 Build smart playlists by tempo, key or mood
- 📊 Analyze your music library in batch (CSV/HTML reports)
- 🤖 Add music understanding to your app via REST API
- 🔬 Research Music Information Retrieval (MIR)
Features
| Feature | Description |
|---|---|
| 🥁 Tempo / BPM | Beat tracking with confidence estimation |
| 🎼 Key detection | Krumhansl-Kessler profiles, tonic + mode |
| 🎨 Spectral features | Centroid, rolloff, ZCR, 13 MFCC coefficients |
| ⚡ Energy | RMS mean/std, dynamic range in dB |
| 😊 Mood | Valence/Arousal + labels + tags |
| 🎭 Extended mood map | Distinguishes melancholic from angry via spectral flatness |
| 💾 Disk cache | SHA-256 keyed, avoids recomputation |
| ⚡ Parallel batch | ProcessPoolExecutor, uses all CPU cores |
| 📤 CSV export | Flat table, Excel-friendly (utf-8-sig) |
| 🌐 HTML report | Dark theme, sortable, filterable, modal with spectrogram |
| 🚀 REST API | FastAPI server for language-agnostic integration |
Installation
Basic:
pip install sonoglyph
With HTML reports:
pip install "sonoglyph[html]"
With REST API server:
pip install "sonoglyph[server]"
Everything:
pip install "sonoglyph[html,server,ml]"
From source:
git clone https://github.com/sonoglyph/sonoglyph.git
cd sonoglyph
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,html,server]"
On Windows, activate the venv with .venv\Scripts\activate instead.
Quick start
CLI — analyze one file
sonoglyph analyze track.mp3
Output:
╭────────────────────────────── Sonoglyph ─────────────────────────────╮
│ track.mp3 │
│ 2:34 · 22050 Hz · 1ch · MP3 │
╰──────────────────────────────────────────────────────────────────────╯
╭─────── 🥁 Tempo ────────╮ ╭──────── 🎼 Key ─────────╮
│ 117.5 BPM │ │ D# minor │
│ 292 beats · conf 0.97 │ │ ♭ minor · conf 0.55 │
╰─────────────────────────╯ ╰──────────────────────────╯
╭────────────────────────── 😊 Mood ───────────────────────────╮
│ MELANCHOLIC (backend: heuristic) │
│ #atmospheric #dark │
│ │
│ Valence ██████████░░░░░░░░░░░░░░ 0.40 │
│ Arousal ███████████████░░░░░░░░░ 0.63 │
│ │
│ Flatness ████░░░░░░░░░░░░ 0.0425 │
╰──────────────────────────────────────────────────────────────╯
╭────── 🎨 Spectral ──────╮ ╭───────── ⚡ Energy ──────────╮
│ Centroid 2260 Hz │ │ RMS 0.1900 ± 0.1015 │
│ Rolloff 4650 Hz │ │ Dynamic 69.6 dB │
│ ZCR 0.0963 │ ╰───────────────────────────────╯
╰─────────────────────────╯
CLI — batch directory
sonoglyph batch ./music/ --pattern "*.mp3" --html report.html --csv library.csv
Generates: progress bar, terminal summary table, report.html (dark-theme modal report) and library.csv.
Python API
from sonoglyph import analyze, analyze_batch
result = analyze("track.mp3")
print(result.tempo.bpm) # 117.5
print(result.key.name) # "D# minor"
print(result.mood.label) # "melancholic"
print(result.mood.tags) # ["atmospheric", "dark"]
print(result.mood.valence) # 0.40
results = analyze_batch(["a.mp3", "b.mp3", "c.mp3"], features=["tempo", "mood"])
from sonoglyph.exporters import to_csv, to_html
to_csv(results, "library.csv")
to_html(results, "report.html", include_spectrograms=True)
REST API
sonoglyph serve --host 127.0.0.1 --port 8000
Then:
curl http://127.0.0.1:8000/api/health
curl -X POST http://127.0.0.1:8000/api/analyze-by-path -H "Content-Type: application/json" -d '{"path": "track.mp3", "features": ["tempo", "mood"]}'
curl -X POST http://127.0.0.1:8000/api/analyze -F "file=@track.mp3" -F "features=tempo,mood"
Interactive docs: http://127.0.0.1:8000/docs
Real examples
Example 1 — Cloud rap, melancholic
{
"tempo": { "bpm": 117.45, "confidence": 0.97, "beat_count": 292 },
"key": { "name": "D# minor", "confidence": 0.55 },
"mood": {
"label": "melancholic",
"valence": 0.40,
"arousal": 0.63,
"tags": ["atmospheric", "dark"],
"spectral_flatness": 0.0425
}
}
Why "melancholic" and not "angry": the track has energetic 808 bass and sharp hi-hats, but also a diffuse, reverberant atmosphere. Sonoglyph uses spectral flatness (p90 percentile) to distinguish the "atmospheric + energetic" quadrant from "aggressive" — a classic mistake for naive valence/arousal classifiers.
Example 2 — Trap, energetic
{
"tempo": { "bpm": 143.55, "confidence": 0.96, "beat_count": 501 },
"key": { "name": "E minor", "confidence": 0.59 },
"mood": {
"label": "happy",
"valence": 0.57,
"arousal": 0.82,
"arousal_rhythmic": 0.66,
"arousal_harmonic": 0.71,
"tags": ["upbeat"],
"spectral_flatness": 0.0204
}
}
Beat stability analysis (from HTML modal):
| Metric | Value |
|---|---|
| Mean interval | 418.0 ms |
| Median interval | 417.9 ms |
| Std deviation | 33.2 ms |
| CV (stability) | 0.0793 |
| BPM from intervals | 143.52 (matches bpm 143.55 ✅) |
Example 3 — HTML report
sonoglyph batch ./music/ --html report.html
Open report.html in a browser. Features:
- Filter by track name, key, tag
- Sort by BPM, mood, valence, arousal
- Click a track → modal with waveform + beat markers, mel spectrogram, beat interval histogram, beat positions timeline, and all stats
Configuration
| Variable | Default | Description |
|---|---|---|
SONOGLYPH_CACHE_DIR |
~/.cache/sonoglyph |
Cache directory |
SONOGLYPH_MOOD_BACKEND |
auto |
auto / heuristic / vibenet |
export SONOGLYPH_CACHE_DIR=/tmp/sonoglyph-cache
export SONOGLYPH_MOOD_BACKEND=heuristic
Project structure
sonoglyph/
├── src/sonoglyph/
│ ├── analyzers/ # Tempo, key, spectral, energy, mood
│ ├── exporters/ # CSV, HTML
│ ├── server/ # FastAPI app
│ ├── api.py # Public API
│ ├── cache.py # Disk cache
│ ├── cli.py # Typer CLI
│ ├── io.py # Audio loading
│ └── schemas.py # Pydantic models
├── tests/ # 18 tests
├── examples/
├── benchmarks/
└── pyproject.toml
License
MIT — see LICENSE.
Acknowledgments
Built on: librosa · soundfile · pydantic · Typer · Rich · FastAPI · uvicorn · matplotlib
Krumhansl-Kessler tonal profiles from Cognitive Foundations of Musical Pitch (1990).
Metadata
Release files for sonoglyph 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sonoglyph-0.1.0.tar.gz | 37.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sonoglyph-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.9 kB
Release files / sonoglyph-0.1.0.tar.gz
| Download URL | sonoglyph-0.1.0.tar.gz |
|---|---|
| Size | 37.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
32d375b4bc639ab91a2b0f19e47278a4c42ef57269e7649f8885322421f83df2
|
|
BLAKE2b-256 checksum How to use checksums |
57532fef143a0c4905ea74222483bf7e69e5e4061c76133515badf9c63e36e85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Release files / sonoglyph-0.1.0-py3-none-any.whl
| Download URL | sonoglyph-0.1.0-py3-none-any.whl |
|---|---|
| Size | 38.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c73da0642aee3db1d20e0d918b7aab18a18f1b7df61944dc91b9be0ab0b2ae1f
|
|
BLAKE2b-256 checksum How to use checksums |
c4e4713de949887731ded8e14645b588bb2524d51e82723754e1eba2a7baffec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|