Skip to main content

MuseCPEval

Measures music context preservation between an original audio file and an edited version of it: how much of the original's harmony, rhythm, structure, and melody survives the edit.

Give it a reference/estimate pair and it returns a JSON object of scores. Give it a manifest or a pair of directories and it scores thousands of pairs in parallel.

Metrics

CLI name Output key Returns
harmony harmony_tonality key_relatedness (distance_steps, distance_norm_0to1), chroma_similarity (chroma_dtw_cosine, mean_chroma_cosine)
rhythm rhythm_meter delta_bpm_folded, beat_mir_eval (F-measure, Information gain)
structure structural_form pairwise_f, ari
melody melodic_content contour_dtw_similarity, motif_3gram_recall

All four run by default. Scoring an identical pair (same file as reference and estimate) returns 1.0 on the similarity metrics and 0.0 on the distance metrics — mean_chroma_cosine lands a few float ulps short of 1.0 rather than exactly on it. That is a quick way to confirm an install is sane.

Install

The metric code needs numpy ≤ 2.2 — librosa depends on numba, and numba refuses newer numpy — so a dedicated environment is the least painful route:

conda create -y -n musecpeval python=3.10
conda activate musecpeval

pip install musecpeval          # or: pip install .        from a clone
                                # or: pip install -e .     to work on the metrics

That installs the musecpeval command and the importable package:

from musecpeval import harmony_score, melody_score, rhythm_score, structural_score

harmony_score("original.wav", "edited.wav")

--metrics structure additionally needs msaf, which is not pulled in by default: its PyPI release is old and pins numpy/scipy versions that fight the rest of the stack, so install it yourself and expect to referee the pins.

pip install msaf                # or: pip install "musecpeval[structure]"

Verify:

musecpeval --ref path/to/file.wav --est path/to/file.wav

python -m musecpeval is equivalent, and python runner.py still works from a clone without installing anything.

Run

Single pair

# JSON to stdout
musecpeval --ref original.wav --est edited.wav

# JSON to a file
musecpeval --ref original.wav --est edited.wav --out-json result.json

# a subset of metrics
musecpeval --ref original.wav --est edited.wav --metrics harmony rhythm

Batch

Exactly one input source is required.

# JSON manifest
musecpeval --batch-json pairs.json --output-dir results/

# CSV manifest
musecpeval --batch-csv pairs.csv --output-dir results/

# two flat directories, paired by filename
musecpeval --ref-dir originals/ --est-dir edited/ --output-dir results/

# nested edits (edited/<section>/<slug>/001.wav) against flat originals
musecpeval --ref-dir originals/ --est-dir edited/ --recursive --output-dir results/
[
  {"ref": "originals/001.wav", "est": "edited/harmony/-3semitone/001.wav",
   "id": "harmony/-3semitone/001", "section": "harmony", "n_steps": -3}
]

Output

--output-dir receives three files:

File Contents
results.jsonl one record per pair, appended and flushed as each finishes
results.json the same records as a single array, written at the end
summary.csv one row per pair, nested scores flattened to dotted columns

results.jsonl is what makes a run resumable, so it is written incrementally; results.json and summary.csv only appear once the run finishes.

Resuming

Rerunning the same command skips pairs already present in results.jsonl, so an interrupted job continues instead of restarting. Ctrl-C exits 130 with partial results intact. Pass --no-resume to discard prior results and start clean.

Pairs are identified by id when present, otherwise by the absolute ref and est paths.

There is no lock file: two runs against the same --output-dir can process the same pairs. Use separate output directories for concurrent jobs.

Options

Flag Meaning
--ref FILE, --est FILE single-pair input
--out-json FILE single mode: write here instead of stdout
--batch-json FILE batch from a JSON manifest
--batch-csv FILE batch from a CSV manifest
--ref-dir DIR, --est-dir DIR batch by pairing two directories
--recursive walk --est-dir subdirectories
--ext EXT extension for directory pairing (default .wav)
--output-dir DIR batch output directory (default ./results)
--metrics ... any of harmony rhythm structure melody (default: all)
--n-workers N worker processes (default min(8, cpus - 1))
--max-cpu use every CPU as a worker
--no-parallel run serially in one process
--no-resume ignore and overwrite prior results
--limit N only the first N pairs, for smoke tests

Worker count is capped at the number of pairs.

Exit codes

Code Meaning
0 everything scored cleanly
1 a pair failed, a metric family failed, or a score was degraded — or bad arguments
130 interrupted; partial results kept and resumable

Repository layout

musecpeval/
  __init__.py          lazily re-exports the four scoring functions
  __main__.py          `python -m musecpeval`
  runner.py            CLI: single-pair and batch evaluation
  metrics/             the four metric families
    harmony_tonality.py  key relatedness, chroma similarity
    rhythm_meter.py      tempo delta, beat F-measure
    structural_form.py   segmentation agreement (needs msaf)
    melody_motif.py      contour DTW, motif n-gram recall
    utils.py             shared helpers
pyproject.toml         deps, the [structure] extra, the `musecpeval` entry point
requirements.txt       mirror of the dependency list, for `pip install -r`
runner.py              shim, so `python runner.py` keeps working from a clone

Each metric module also has its own __main__ block that scores a directory of pairs for that family alone — python -m musecpeval.metrics.rhythm_meter --orig-dir a/ --edit-dir b/. The flag spelling is not consistent between them: rhythm_meter.py takes --orig-dir / --edit-dir, the other three take --orig_dir / --edit_dir.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

musecpeval-0.1.0.tar.gz (29.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

musecpeval-0.1.0-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file musecpeval-0.1.0.tar.gz.

File metadata

  • Download URL: musecpeval-0.1.0.tar.gz
  • Upload date:
  • Size: 29.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.20

File hashes

Hashes for musecpeval-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8b3b7ebf30559829d1bd1d748f96cfb6224ff7f7fa16729939becbb0310f099a
MD5 1c574fb4ea7e01871e0e56d30557b7fc
BLAKE2b-256 c9a57514c7921a83700c9f005ec29de607f151741241267e46171d0b2d4911e0

See more details on using hashes here.

File details

Details for the file musecpeval-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: musecpeval-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.20

File hashes

Hashes for musecpeval-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d05a4917eadca5b69351e7c07af11084aeb5d2e945399b1b8abb434bf637543
MD5 2cc8674b6472ec4b1c89db505adc2992
BLAKE2b-256 7e58a250f98cc6fd197fa25cff7bdbff46e77318115535edce632b58e64e3ead

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page