Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

track-analyst

Timestamped structural analysis of a music file for scene and edit planning.

track-analyst runs a music file through librosa and writes a markdown report describing the track's structure, energy arc, key, BPM, beat drops, and transient hits — a readable cut sheet you can keep next to your editor or DAW.

It also outputs JSON if you'd rather pipe it into your own tooling.


Why

Hand-annotating a song to plan an edit is tedious: scrub, mark, scrub, mark. This tool gives you a machine-readable map of the track in seconds — section bounds, BPM, energy curve, and exact timestamps for every notable hit.

Typical use cases:

  • Scene planning for music videos, VRChat films, AMVs, dance choreography
  • Cut sheets for editors — beat drops, transient hits, energy arcs
  • DJ / set prep — quickly seeing where the breaks and drops sit
  • Quick exploration — get a sense of a track's structure without scrubbing the waveform

Install

pip install git+https://github.com/thevoidwolf/track-analyst.git

Or clone and install editable:

git clone https://github.com/thevoidwolf/track-analyst.git
cd track-analyst
pip install -e .

Requires Python 3.9+. Pulls in librosa, numpy, and scipy.

Note: librosa needs ffmpeg (or a decoder backend like soundfile) to read MP3. Most systems have one already; if not: apt install ffmpeg / brew install ffmpeg.


Usage

# Print markdown report to stdout
track-analyst song.mp3

# Write to file
track-analyst song.mp3 -o song.analysis.md

# Ask for more (or fewer) structural sections
track-analyst song.mp3 --segments 12

# JSON output for downstream tooling
track-analyst song.mp3 --format json -o song.analysis.json

You can also invoke it as a module:

python -m track_analyst song.mp3

Flags

Flag Default What it does
file Audio file (MP3, WAV, FLAC, OGG, …)
-o, --output stdout Write report to this path
--segments N 8 Target number of structural sections
--format {markdown,json} markdown Output format
--version Print version and exit

What it analyzes

  • Tempo & beat grid — global BPM and per-beat timestamps
  • Estimated key — pitch class (C, C#, D, …); does not distinguish major/minor
  • Structural sections — beat-synced MFCC + agglomerative clustering picks regions of consistent sonic character (e.g. "intro", "verse", "drop", "outro" — though the tool doesn't label them, just bounds them)
  • Energy arc — RMS loudness in 10-second windows, drawn as ASCII bars
  • Sub-bass energy — 20–200 Hz band, useful for spotting drops and bass-heavy moments
  • Spectral brightness — high-frequency content, proxy for "bright" vs. "dark" passages
  • Harmonic / percussive character — each section is tagged Melodic / Driving / Percussive based on H/P ratio
  • Beat drops & energy surges — sudden RMS increases (good cut points)
  • Transient hits — top 10% of onsets by strength, ≥0.5s spacing
  • Bar map — every 4 bars, so you can correlate scene numbers to bar numbers

Sample output

A real, full report is checked in at examples/run-amok.analysis.md. Abbreviated below.

# Track Analysis: `night-drive.mp3`

## Overview
| | |
|---|---|
| **Duration** | 03:42.18 (222s) |
| **BPM** | 128.0 |
| **Est. Key** | F# *(pitch class only — not major/minor)* |
| **Detected Beats** | 472 |

## Structure
| # | Start → End | Dur | Energy | Bass | Brightness | BPM | Character |
|---|-------------|-----|--------|------|------------|-----|-----------|
| 1 | 00:00.00 → 00:16.00 | 16s | Low | Low | Dark | 128 | Melodic |
| 2 | 00:16.00 → 00:48.00 | 32s | Med-Low | Mid | Mid | 128 | Driving |
| 3 | 00:48.00 → 01:20.00 | 32s | High | High | Bright | 128 | Percussive |
| 4 | 01:20.00 → 02:08.00 | 48s | PEAK | High | Bright | 128 | Driving |
|||||||||

## Energy Map  *(10s windows)*
`00:00.00` ██░░░░░░░░ Low
`00:10.00` ████░░░░░░ Med-Low
`00:20.00` ██████░░░░ Medium  ♦
`00:30.00` ████████░░ Med-High  ♦
`00:40.00` ██████████ PEAK  ♦
…

## Notable Events
| Timestamp | Event | Intensity |
|-----------|-------|-----------|
| `00:48.12` | ⚡ Energy surge | ████████ |
| `01:20.04` | 🔨 Strong transient hit | ███████░ |
| `02:08.50` | ⚡ Energy surge | ██████░░ |

Limitations

  • Key detection is pitch-class only — doesn't tell you major vs. minor, and chromagram estimates can be wrong on noisy or atonal material.
  • Section boundaries are approximations. They're acoustic-similarity clusters, not labeled song parts; expect to nudge them by ear.
  • Beat tracking assumes 4/4-ish music. Free time, polyrhythmic, or extreme tempo-change tracks will confuse it.
  • Voice-only or non-musical audio (speech, ambience) gives noisy/unhelpful output.

Programmatic use

from track_analyst import analyze, to_markdown
import json

data = analyze("song.mp3", n_segments=10)
print(to_markdown(data))            # markdown report
print(json.dumps(data, indent=2))   # raw structured data

analyze() returns a dict with filename, duration, bpm, key, total_beats, segments, drops, transients, timeline, and bar_markers.


Contributing

Issues and PRs welcome — especially:

  • Major/minor key detection (Krumhansl-Schmuckler or similar)
  • Per-section labelling (intro / verse / drop / break / outro)
  • A small test fixture and a CI check
  • Faster paths for long tracks

Keep changes scoped and avoid pulling in heavy ML deps unless they meaningfully improve output quality.


License

MIT © 2026 voidwolf

About

Timestamped structural analysis of a music file for scene and edit planning.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages