track_io

Track data model, on-disk file I/O, and lookup helpers for this project’s own tracks/+annotations/ dataset format (see docs/source/data.rst).

Shared by the annotator (tools/annotator/data.py), the migration tools (tools/migrate_*.py), and the training loaders (musicality/loaders/), so none of them can drift out of sync about the on-disk layout.

Functions

annotation_path(track)

Return the canonical save path for a track's annotations (.beats file).

bpm_stats(beat_times)

Mean/median/std BPM from inter-beat intervals.

list_migrated_track_ids(dataset_name[, ...])

Return every track id with a default-slot .beats file for dataset_name.

list_track_refs(name[, data_home, contains])

Return every migrated track for name, wrapped as TrackRef.

load_metadata(dataset_name, track_id[, ...])

Load a track's metadata for annotator_id's slot, or None if unsaved.

metadata_path(dataset_name, track_id[, ...])

Return the canonical save path for a track's metadata (.meta.json file).

read_beats_file(path)

Read a .beats file into (times, positions).

resolve_track_audio(dataset_name, track_id)

Return the on-disk audio path for track_id in dataset_name, or None if no tracks/<track_id>.wav exists.

sanitize_track_name(name)

Turn free-form user input into a filesystem-safe track id.

save_annotations(track, path)

Persist beat annotations to a .beats file — see read_beats_file() for the format.

save_metadata(dataset_name, track_id, metadata)

Persist track metadata as JSON, next to that track's .beats file.

Classes

TrackData(dataset_name, track_id, ...[, ...])

All annotation data for a single track.

TrackMetadata([location, device, structure, ...])

Free-form descriptive info about a track, separate from its beats.

TrackRef(dataset_name, track_id, data_home)

One track's identity plus where to resolve its audio/annotations from.

class TrackData(dataset_name, track_id, audio_path, tempo, beat_times, beat_positions, annotator_id=None)[source]

Bases: object

All annotation data for a single track.

Parameters:
  • dataset_name (str)

  • track_id (str)

  • audio_path (str)

  • tempo (float | None)

  • beat_times (ndarray)

  • beat_positions (ndarray | None)

  • annotator_id (str | None)

annotator_id: str | None = None
audio_path: str
beat_positions: ndarray | None
beat_times: ndarray
dataset_name: str
tempo: float | None
track_id: str
class TrackMetadata(location=None, device=None, structure=None, duration_s=None, bpm_mean=None, bpm_median=None, bpm_std=None, annotator_id=None, section_aligned=None, warning=False, needs_review=False, corrected=False, schema_version=1)[source]

Bases: object

Free-form descriptive info about a track, separate from its beats.

All fields optional — captured incrementally from either the desktop annotator or the mobile companion, never required to save a recording.

Parameters:
  • location (str | None)

  • device (str | None)

  • structure (str | None)

  • duration_s (float | None)

  • bpm_mean (float | None)

  • bpm_median (float | None)

  • bpm_std (float | None)

  • annotator_id (str | None)

  • section_aligned (bool | None)

  • warning (bool)

  • needs_review (bool)

  • corrected (bool)

  • schema_version (int)

annotator_id: str | None = None
bpm_mean: float | None = None
bpm_median: float | None = None
bpm_std: float | None = None
corrected: bool = False
device: str | None = None
duration_s: float | None = None
location: str | None = None
needs_review: bool = False
schema_version: int = 1
section_aligned: bool | None = None
structure: str | None = None
warning: bool = False
class TrackRef(dataset_name, track_id, data_home)[source]

Bases: object

One track’s identity plus where to resolve its audio/annotations from.

Returned by list_track_refs(), and the unit a TempoDataset/BeatDataset can be built from directly via its refs= constructor argument — e.g. a list of refs spanning several source datasets, such as one produced by tools/merge_datasets.py.

Parameters:
  • dataset_name (str)

  • track_id (str)

  • data_home (Path)

data_home: Path
dataset_name: str
track_id: str
annotation_path(track)[source]

Return the canonical save path for a track’s annotations (.beats file).

Nested under track.annotator_id’s slot; None is the default slot.

Parameters:

track (TrackData)

Return type:

Path

bpm_stats(beat_times)[source]

Mean/median/std BPM from inter-beat intervals.

Instantaneous tempo per interval, then averaged — the persisted-metadata convention used by the migration tools. Distinct from tools.annotator.data.tempo_from_beats’ single median-interval estimate, which the live tap-tempo UI uses instead.

Parameters:

beat_times (ndarray)

Return type:

tuple[float, float, float] | tuple[None, None, None]

list_migrated_track_ids(dataset_name, data_home=None)[source]

Return every track id with a default-slot .beats file for dataset_name.

Non-recursive, so annotator subdirectories (alternate annotation slots) are excluded. An empty result means dataset_name hasn’t been migrated to this project’s own format yet. See _annotations_slot_dir() for data_home.

Parameters:
  • dataset_name (str)

  • data_home (Path | None)

Return type:

list[str]

list_track_refs(name, data_home=None, contains=None)[source]

Return every migrated track for name, wrapped as TrackRef.

Thin wrapper over list_migrated_track_ids() — kept as the loaders’ entry point since it returns ready-to-resolve refs rather than bare track ids. To build a dataset from tracks spanning several source datasets (e.g. a merge), pass refs= directly to TempoDataset/BeatDataset instead of going through name.

Parameters:
  • contains (str | None) – If given, keep only tracks whose track_id contains this substring, matched case-insensitively. Datasets that encode a category in the track id — e.g. gtzan’s blues_00001, jazz_00042 — are then addressable as a subset without any separate manifest: contains="blues" is gtzan’s blues tracks.

  • name (str)

  • data_home (Path | None)

Return type:

list[TrackRef]

load_metadata(dataset_name, track_id, annotator_id=None, data_home=None)[source]

Load a track’s metadata for annotator_id’s slot, or None if unsaved. See _annotations_slot_dir() for data_home.

Parameters:
  • dataset_name (str)

  • track_id (str)

  • annotator_id (str | None)

  • data_home (Path | None)

Return type:

TrackMetadata | None

metadata_path(dataset_name, track_id, annotator_id=None, data_home=None)[source]

Return the canonical save path for a track’s metadata (.meta.json file).

Nested under annotator_id’s slot; None is the default slot. See _annotations_slot_dir() for data_home.

Parameters:
  • dataset_name (str)

  • track_id (str)

  • annotator_id (str | None)

  • data_home (Path | None)

Return type:

Path

read_beats_file(path)[source]

Read a .beats file into (times, positions).

<time> <position> per line (seconds, 1-indexed bar/phrase position) — see e.g. the ballroom dataset’s raw annotation files, which this format mirrors. Falls back to bare timestamps (one per line, no position) for files saved before position tracking was added; in that case positions is None.

Parameters:

path (Path)

Return type:

tuple[ndarray, ndarray | None]

resolve_track_audio(dataset_name, track_id, data_home=None)[source]

Return the on-disk audio path for track_id in dataset_name, or None if no tracks/<track_id>.wav exists. See _annotations_slot_dir() for data_home.

Parameters:
  • dataset_name (str)

  • track_id (str)

  • data_home (Path | None)

Return type:

Path | None

sanitize_track_name(name)[source]

Turn free-form user input into a filesystem-safe track id.

Falls back to "recording" if name is empty or whitespace-only.

Parameters:

name (str)

Return type:

str

save_annotations(track, path)[source]

Persist beat annotations to a .beats file — see read_beats_file() for the format. Falls back to bare timestamps (no position column) if the track has no positions.

Parameters:
Return type:

None

save_metadata(dataset_name, track_id, metadata)[source]

Persist track metadata as JSON, next to that track’s .beats file.

Saved under metadata.annotator_id’s slot; None is the default slot.

Parameters:
Return type:

None