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’}