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.

Data

The audio used for the objective evaluation is available on Google Drive.

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==0.2.0

Pinning the version is the recommended form — the metric numbers are what you cite, so you want them reproducible. pip install musecpeval takes the newest release instead. Published at pypi.org/project/musecpeval.

Installing from GitHub instead

For an unreleased change, or to work on the metrics:

pip install "git+https://github.com/Yashvishe13/MuseCPEval.git"   # straight from main
pip install "git+https://github.com/Yashvishe13/MuseCPEval.git@v0.1.0"  # at a tag

git clone https://github.com/Yashvishe13/MuseCPEval.git && cd MuseCPEval
pip install .                   # from a clone
pip install -e .                # editable, so edits to the metrics take effect

Either way you get 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.2.0.tar.gz (30.7 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.2.0-py3-none-any.whl (32.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for musecpeval-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b8ee70ce40096cd53dd08b758fd166e2b138619e4b050125af63d6e6e59ab519
MD5 7a0aedd8b924da71220d27476d415cf6
BLAKE2b-256 cad3e20ba7d79cc40a0ac5eb83d706ab175c61ee8a19392c40811bfc6a7c7962

See more details on using hashes here.

File details

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

File metadata

  • Download URL: musecpeval-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.6 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 338986cd194b0410e71a9df05e6e4f41670259e27dc4780f0a39d4d279db5db2
MD5 e8407bf41ddb570be4319e8166f54b24
BLAKE2b-256 0853e02cbd7e0401329debbd940e4e35054433a1e831ffa913fd3445fb6c92a7

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 files

0.1.0

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