ContinuousPhysicalTimeline

ContinuousPhysicalTimeline(
    length=0,
    unit=None,
    number_type=None,
    id_prefix='tl',
    uid=None,
    name=None,
    locked=False,
    meta=None,
)

A physical timeline with continuous coordinates.

Used for acoustic time measurements where arbitrary precision is needed (e.g., note onsets at 1.234 seconds).

Default unit: seconds. Default number type: float. Allowed units: seconds, milliseconds, minutes (NOT samples/frames).

Provides convenience methods for creating metrical timelines connected via TimelineGroups (per TTA specification, children must share the parent’s unit; cross-domain relationships use groups).

Methods

Name Description
create_metrical_grid Create a metrical grid timeline with automatic beat/measure computation.
create_metrical_region Create a metrical grid for an existing region.

create_metrical_grid

ContinuousPhysicalTimeline.create_metrical_grid(
    first_beat_at,
    tempo_bpm,
    beats_per_measure=4,
    beat_unit=Fraction(1, 4),
    end_at=None,
    start_mc=1,
    start_mn='1',
    anacrusis_quarters=None,
    measure_type='none',
    beat_type='none',
    name=None,
)

Create a metrical grid timeline with automatic beat/measure computation.

This is the primary convenience method for users who have an audio file and know: (1) tempo, (2) meter, and (3) where the first beat is. They do NOT need to know the total length in quarters - the library computes that automatically.

Per TTA specification (Section 3.4 - Nested Timelines): “A timeline can accommodate other timelines as Children, as long as they use the same measuring unit.” Therefore, a logical timeline (quarters) cannot be a child of a physical timeline (seconds). Instead, this method creates a standalone ContinuousLogicalTimeline and connects it to this physical timeline via a TimelineGroup with bidirectional linear interpolation.

The returned MetricalResult provides convenient access to: - The created grid (ContinuousLogicalTimeline in quarters) - The TimelineGroup connecting physical and logical coordinates - Methods for timestamp queries with metrical information

Args: first_beat_at: Coordinate (in seconds) of the first beat. tempo_bpm: Tempo in beats per minute. beats_per_measure: Number of beats per measure. Default 4. beat_unit: Note value of one beat. Default 1/4 (quarter note). Use Fraction(1, 8) for eighth-note beats (e.g., 6/8 time). end_at: Coordinate (in seconds) where the grid ends. If None, extends to the end of the physical timeline. start_mc: MC (measure count) of the first measure. Default 1. start_mn: MN (measure number label) of the first measure. Default “1”. Use “0” for anacrusis (pickup measure). anacrusis_quarters: If set, the first measure is shorter (pickup). Specified in quarter notes. measure_type: How to represent measures in the grid: - “none”: No measure entities (default) - “events”: Create Measure as IntervalEvents - “children”: Create each measure as a Child timeline beat_type: How to represent beats in the grid: - “none”: No beat entities (default) - “instants”: Create Beat as InstantEvents - “intervals”: Create Beat as IntervalEvents (with duration) - “segments”: Create a SegmentLine with beat Segments name: Human-readable name for the grid timeline.

Returns: MetricalResult containing the grid, group, and accessor methods.

Raises: ValueError: If first_beat_at is negative or after end_at.

Examples: >>> # Audio file at 120 BPM, 4/4, first beat at 0.5 seconds >>> audio = ContinuousPhysicalTimeline(length=180.0) >>> result = audio.create_metrical_grid( … first_beat_at=0.5, … tempo_bpm=120.0, … beats_per_measure=4, … ) >>> # Query metrical info at 60 seconds >>> result.timestamp_at_seconds(60.0) {‘seconds’: 60.0, ‘quarters’: 119.0, ‘mc’: 30, ‘beat’: Fraction(4, 1), ‘mn’: ‘30’}

>>> # Find where measure 10, beat 1 is
>>> result.seconds_at(mc=10, beat=Fraction(1, 1))
18.5

>>> # Access the group for general coordinate conversion
>>> result.group.convert(100.0, result.grid.id, audio.id)  # quarters -> seconds
50.5

>>> # With anacrusis (pickup beat)
>>> result = audio.create_metrical_grid(
...     first_beat_at=0.25,
...     tempo_bpm=100.0,
...     beats_per_measure=3,
...     start_mn="0",
...     anacrusis_quarters=Fraction(1, 1),  # 1 beat pickup
... )

create_metrical_region

ContinuousPhysicalTimeline.create_metrical_region(
    region_name,
    tempo_bpm,
    beats_per_measure=4,
    beat_unit=Fraction(1, 4),
    start_mc=1,
    start_mn='1',
    anacrusis_quarters=None,
    measure_type='none',
    beat_type='none',
)

Create a metrical grid for an existing region.

This method creates a metrical grid that corresponds to a named region on this physical timeline. Per TTA Table 2, regions are named parts of a timeline defined by a TimeInterval. This method creates the metrical structure for that region.

Args: region_name: Name of an existing region on this timeline. tempo_bpm: Tempo in beats per minute. beats_per_measure: Number of beats per measure. Default 4. beat_unit: Note value of one beat. Default 1/4 (quarter note). start_mc: MC (measure count) of the first measure. Default 1. start_mn: MN (measure number label) of the first measure. anacrusis_quarters: If set, the first measure is shorter (pickup). measure_type: How to represent measures: - “none”: No measure entities (default) - “events”: Create Measure as IntervalEvents - “children”: Create each measure as a Child timeline beat_type: How to represent beats: - “none”: No beat entities (default) - “instants”: Create Beat as InstantEvents - “intervals”: Create Beat as IntervalEvents - “segments”: Create a SegmentLine with beat Segments

Returns: MetricalResult containing the grid, group, and accessor methods.

Raises: KeyError: If the region does not exist.

Examples: >>> audio = ContinuousPhysicalTimeline(length=300.0) >>> audio.add_region(“verse”, start=10.0, end=50.0) >>> result = audio.create_metrical_region( … region_name=“verse”, … tempo_bpm=100.0, … beats_per_measure=4, … ) >>> result.timestamp_at_seconds(25.0) {‘seconds’: 25.0, ‘quarters’: 25.0, ‘mc’: 7, ‘beat’: Fraction(2, 1), ‘mn’: ‘7’}