Bar

class paeonia.Bar(notes=None, tonality=None)[source]

Bases: object

Parameters:

tonality (Tonality | None)

property notes: tuple[Note, ...]

Return the immutable event sequence.

property tonality: Tonality | None

Return the bar’s immutable tonal context.

interleave(other, counts)[source]

Interleave chunks from this bar and a cycling second bar.

The first count selects consecutive events from this bar and the second count selects consecutive events from other. Chunk pairs repeat until this bar is exhausted. Its final chunk may contain fewer events than requested; the corresponding chunk from other remains full. The second bar cycles from its beginning whenever it runs out.

For example, counts [1, 2] take one event from this bar, then two from other, and repeat that pattern. Both source bars remain unchanged, and emitted events retain all of their metadata. Tonality is inherited from the defined bar when only one has a tonality, and conflicting explicit tonalities are rejected.

Parameters:
  • other (Bar) – Non-empty bar whose events cycle as the second source.

  • counts (Iterable[int]) – Exactly two positive integers: the chunk sizes for this bar and other, respectively.

Returns:

A new bar containing the interleaved event sequence.

Return type:

Bar

Raises:
  • TypeError – If other is not a bar or a count is not an integer.

  • ValueError – If there are not exactly two positive counts, the second bar is empty while this bar has events, or explicit tonalities conflict.

with_events(indices, replacements)[source]

Return a copy with selected events replaced.

This is the non-mutating counterpart to multi-index assignment. The number of replacements must equal the number of indices. Tonality and every event outside the selected positions are preserved.

Parameters:
  • indices (Iterable[int]) – Event positions to replace, including negative indices.

  • replacements (Iterable[Note] | Bar) – Replacement events in corresponding order.

Returns:

A new bar containing the requested replacements.

Return type:

Bar

merge_adjacent()[source]

Merge every consecutive run of structurally equal pitches.

Pitch comparison is order-independent for chords but preserves written spelling, so reordered equal chords merge while enharmonic spellings such as E-flat and D-sharp remain separate. Consecutive rests merge as well because both have an empty pitch collection.

Each merged event keeps the first event’s pitch order and velocity, uses the first event’s tie_in and the final event’s tie_out, and receives the sum of all durations in the run. Unlike neighbors are retained unchanged. The operation returns a new bar, preserves its tonality, and does not quantize resulting durations.

Returns:

A new bar with every qualifying run replaced by one longer event.

Return type:

Bar

sounding_indices()[source]

Return the indices of all non-rest events.

Single notes and chords are both sounding events. The returned list follows event order and is empty when the bar contains no sounding events.

Return type:

list[int]

rest_indices()[source]

Return the indices of all rest events in event order.

Return type:

list[int]

to_rest()[source]

Return a single-rest replacement with the same total duration.

The returned bar contains one untied rest spanning the complete source bar and retains the source bar’s tonality. The source bar and its events are unchanged. Because a zero-duration Note is invalid, an empty source bar produces a new empty bar instead.

Returns:

A new bar containing one full-span rest, or no events when this bar is empty.

Return type:

Bar

map_notes(function)[source]

Apply a function to every note in the bar.

Parameters:

function (Callable[[Note], Note]) – Function that maps each note to its replacement.

Returns:

A new bar containing the mapped notes and the same tonality.

Return type:

Bar

stretch(factor, *, quantize=True)[source]

Stretch event durations and return a new bar.

A single factor is applied to every event. When an iterable is given, events and factors advance together: factors cycle when shorter than the bar, and bar events cycle when the factor pattern is longer. Pairing stops after the longer input has been consumed once.

Each result is transformed through Note.stretch(), so rests, chords, pitches, velocity, and tie metadata retain their existing behavior. The source bar is unchanged and its tonality is preserved.

Parameters:
  • factor (int | float | Fraction | Iterable[int | float | Fraction]) – A finite, strictly positive duration multiplier, or a finite, non-empty pattern of such multipliers.

  • quantize (bool, default=True) – Snap each result to the nearest duration directly supported by the LilyPond renderer. Set this to false to retain exact multiplied durations.

Returns:

A new bar containing the stretched events.

Return type:

Bar

Raises:
  • TypeError – If a factor or quantize has an unsupported type.

  • ValueError – If a factor is non-finite or not strictly positive, the factor pattern is empty, or a non-empty pattern is applied to an empty bar.

rotate(steps)[source]

Rotate the event sequence and return a new bar.

Positive values rotate to the right and negative values rotate to the left. Values larger than the number of events wrap around. Tonality and the original Note objects, including all their metadata, are preserved; the source bar is unchanged.

Parameters:

steps (int) – Number of event positions to rotate. Positive values rotate right.

Returns:

A new bar containing the rotated event sequence.

Return type:

Bar

Raises:

TypeError – If steps is not an integer.

gate_notes(pattern, *, extend_previous=False)[source]

Apply one gate switch to each event and return a new bar.

This is the finite, bar-sized counterpart of paeonia.tools.gate_notes(). An open gate retains its event and a closed gate replaces it with an untied rest. String patterns use "x" for an open gate and "." for a closed gate. With extend_previous=True, closed events are absorbed into the duration of the preceding open event; leading closed events remain rests.

The pattern must contain exactly one switch per source event. Tonality and active-event metadata are preserved, and the source bar is not modified.

Parameters:
  • pattern (Iterable[bool | int] | str) – Gate switches matching the number of events in the bar.

  • extend_previous (bool, default=False) – Extend an earlier active event across following closed events.

Returns:

A new bar containing one gated pass over the source events.

Return type:

Bar

Raises:
  • ValueError – If the pattern length differs from the number of events or a string contains unsupported characters.

  • TypeError – If switches or extend_previous have unsupported types.

map_pitches(function)[source]

Apply a function to every pitch in the bar.

Rests are retained unchanged.

Parameters:

function (Callable[[Pitch], Pitch]) – Function that maps each pitch to its replacement.

Returns:

A new bar containing the mapped pitches and the same tonality.

Return type:

Bar

note_repeat(repeats)[source]

Repeat events according to a cycling count pattern.

This is the finite counterpart of paeonia.tools.note_repeat(). Events and counts advance together. If the count pattern is shorter than the bar, the counts cycle; if it is longer, the bar’s events cycle. Pairing stops after the longer input has been consumed once. The source bar is unchanged and its tonality and event metadata are preserved.

Parameters:

repeats (Iterable[int]) – Finite, non-empty sequence of positive repeat counts.

Returns:

A new bar containing the repeated event sequence.

Return type:

Bar

Raises:
  • ValueError – If the bar or repeat pattern is empty, or a count is not positive.

  • TypeError – If a repeat count is not an integer.

repeat(times)[source]

Repeat the bar while preserving its tonality.

Parameters:

times (int) – How many times to repeat the bar

Returns:

A new bar containing the repeated event sequence.

Return type:

Bar

span()[source]

“Return the span of the bar (sum of duration of all notes).

Returns:

Sum of the durations of the notes in the bar

Return type:

Fraction

split(time_signature=(4, 4))[source]

Split the event sequence into measures of a given time signature.

Sounding notes and chords that cross a measure boundary are divided into tied segments. Rests are split without ties, and consecutive rests in a resulting measure are combined. When the source does not fill its final measure, an untied rest pads the remaining duration. Every resulting bar has the source tonality, which is also installed as the returned voice’s default tonal context. The source bar and its events are not modified. An empty source produces an empty voice.

Parameters:

time_signature (tuple[int, int], default=(4, 4)) – Positive numerator and denominator. Their ratio gives each measure’s duration in whole-note units.

Returns:

A new voice containing complete, equally sized measures.

Return type:

Voice

Raises:
  • TypeError – If time_signature is not a pair of integers.

  • ValueError – If either time-signature value is not positive.

add_note(note)[source]

Return a new bar with one event appended.

Parameters:

note (Note) – Event to append.

Returns:

A new bar containing the existing events followed by note.

Return type:

Bar

pitches()[source]

Returns all pitches in this bar as a single flat list.

Returns:

A list of numbers signifying pitches.

Return type:

list

pitch_variant(function)[source]

Transform the bar’s flattened pitch sequence.

The transformed pitches are redistributed across the original notes and chords. Rests and the number of pitches in each event are preserved.

Parameters:

function (Callable[[list[Pitch]], Sequence[Pitch]]) – Function that receives all pitches as a flat list and returns a replacement sequence containing the same number of pitches.

Returns:

A new bar containing the transformed pitches and the same tonality.

Return type:

Bar

Raises:

ValueError – If the transformed sequence contains a different number of pitches.

with_tonality(tonality)[source]

Return a copy of the bar with the specified tonality.

This changes only the bar’s tonal context; it does not remap the pitches of its notes.

Parameters:

tonality (Tonality | None) – Tonality to associate with the new bar, or None to remove the current tonal context.

Returns:

A new bar containing the same notes and the specified tonality.

Return type:

Bar

apply_tonality(target, source=None, *, chromatic='preserve_alteration', degree_policy='error')[source]

Reinterpret the bar’s scale positions in another tonality.

Each pitch is analyzed relative to the source tonality and realized at the same scale degree, tonal octave, and chromatic alteration in the target tonality. Durations, rests, chords, and other note properties are preserved.

Parameters:
  • target (Tonality) – Tonality in which to realize the mapped pitches.

  • source (Tonality | None) – Tonality used to analyze the existing pitches. If omitted, the tonality assigned to the bar is used.

  • chromatic (str) – Policy passed to Tonality.analyze_pitch for pitches outside the source tonality.

  • degree_policy (str) – How to handle different source and target degree counts. Use "error" to reject them or "wrap" to wrap source degrees modulo the target’s degree count.

Returns:

A new bar mapped to and associated with the target tonality.

Return type:

Bar

Raises:

ValueError – If no source tonality is available, a policy is unknown, or the degree counts differ when degree_policy is "error".

quantize_to_tonality(target, *, direction='nearest', tie_break='lower')[source]

Move every pitch to a nearby pitch in a target tonality.

Quantization is based on MIDI distance rather than scale degree. Rests, durations, chord structure, and other note properties are preserved.

Parameters:
  • target (Tonality) – Tonality whose pitches are used as quantization candidates.

  • direction (str) – Direction in which to search: "nearest", "up", or "down".

  • tie_break (str) – For equally near candidates, choose "lower" or "upper".

Returns:

A new quantized bar associated with the target tonality.

Return type:

Bar

Raises:

ValueError – If a policy is unknown or no target pitch can be found in the requested direction.

transpose_degrees(degrees, tonality=None, *, chromatic='preserve_alteration')[source]

Transpose every pitch by scale degrees within a tonality.

Positive values move pitches upward and negative values move them downward. Rests, durations, chord structure, and other note properties are preserved.

Parameters:
  • degrees (int) – Number of scale degrees by which to transpose each pitch.

  • tonality (Tonality | None) – Tonality that defines the scale degrees. If omitted, the tonality assigned to the bar is used.

  • chromatic (str) – Policy passed to Tonality.transpose_pitch for pitches outside the tonality: "preserve_alteration", "error", or "nearest".

Returns:

A new transposed bar associated with the tonality used.

Return type:

Bar

Raises:

ValueError – If no tonality is available, the chromatic policy is unknown, or a resulting pitch falls outside the MIDI range.

intervals()[source]

Return successive signed MIDI-semitone intervals.

Returns:

Semitone difference between each pair of flattened pitches.

Return type:

list[int]

tonal_intervals(tonality=None, *, chromatic='preserve_alteration')[source]

Return signed scale-degree steps between successive pitches.

Pitches are read as one flat sequence, so rests contribute no pitches and pitches within chords participate in their stored order. The interval values count scale-degree steps rather than semitones; chromatic alterations do not change a degree when they are preserved.

Parameters:
  • tonality (Tonality | None) – Tonality used to analyze the pitches. If omitted, the tonality assigned to the bar is used.

  • chromatic (str) – Policy passed to Tonality.analyze_pitch for pitches outside the tonality: "preserve_alteration", "error", or "nearest".

Returns:

Signed differences between consecutive absolute scale-degree positions. Bars with fewer than two pitches return an empty list.

Return type:

list[int]

Raises:

ValueError – If no tonality is available or the chromatic policy is unknown.

scale_intervals(factor, *, operation='multiply', chromatic=False, tonality=None, alteration_policy='preserve_alteration')[source]

Contract or expand successive intervals around the first pitch.

By default, values multiply successive signed intervals while the first sounding pitch remains fixed. Values between zero and one contract intervals, values greater than one expand them, zero collapses them, and negative values additionally invert their direction. With operation="add", values are instead added to the signed intervals: for example, adding one changes -3 to -2.

By default, intervals are measured in scale degrees using tonality or the bar’s assigned tonality. Set chromatic=True to measure them in MIDI semitones instead. Tonal scaling preserves each corresponding source pitch’s chromatic alteration according to alteration_policy.

A single factor applies to every interval without changing the event layout. For an iterable, factors and successive flattened pitches advance together. A short pattern cycles across the bar’s intervals. If the pattern is longer, the source event layout cycles until every supplied factor has been used at least once. Chord boundaries, rests, durations, velocities, and ties are retained; a repeated partial cycle always includes complete events.

Resulting tonal degrees and semitone intervals must remain integral. For example, contracting a two-degree interval by Fraction(1, 2) is valid, while contracting a one-degree interval by the same factor is not representable and raises an error.

Parameters:
  • factor (int | float | Fraction | Iterable[int | float | Fraction]) – Finite interval value or finite, non-empty value pattern.

  • operation (str, default="multiply") – Combine intervals and values with "multiply" or "add".

  • chromatic (bool, default=False) – Measure intervals in semitones instead of tonal scale degrees.

  • tonality (Tonality | None) – Tonality used for tonal interval analysis. Defaults to the bar’s tonality and is ignored for chromatic scaling.

  • alteration_policy (str, default="preserve_alteration") – Tonal pitch-analysis policy: "preserve_alteration", "error", or "nearest".

Returns:

A new interval-scaled bar with preserved event metadata.

Return type:

Bar

Raises:
  • TypeError – If a factor or option has an unsupported type.

  • ValueError – If a pattern is empty, no tonal context is available, a policy is unknown, a scaled interval is not integral, or a pitch leaves the MIDI range.

retrograde()[source]

Return a bar with a retrograde pitch variant. Durations are unaffected.

Returns:

A fresh new bar with pitches in reverse order

Return type:

Bar

inversion()[source]

Invert successive MIDI intervals around the first pitch.

Returns:

A new bar with pitch boundaries and non-pitch metadata preserved.

Return type:

Bar

tonal_inversion(tonality=None, *, chromatic='preserve_alteration')[source]

Invert scale-degree intervals around the first pitch.

Inversion operates in absolute scale-degree coordinates, not MIDI semitones. The first analyzed scale position is retained. Every later degree interval has its direction negated while keeping its magnitude.

With the default "preserve_alteration" policy, the first pitch keeps its alteration and every later inverted pitch receives the alteration of the corresponding original pitch. Alterations themselves are not inverted. "error" rejects chromatic pitches, while "nearest" analyzes them as their nearest pitches in the tonality.

Parameters:
  • tonality (Tonality | None) – Tonality that defines the scale degrees. If omitted, the tonality assigned to the bar is used.

  • chromatic (str) – Chromatic analysis policy: "preserve_alteration", "error", or "nearest".

Returns:

A new tonally inverted bar with the original event boundaries and the selected tonality.

Return type:

Bar

Raises:

ValueError – If no tonality is available, the chromatic policy is unknown, or an inverted pitch falls outside the MIDI range.

ascending()[source]

Return a bar with pitches in ascending order.

Returns:

A new bar with pitches in ascending order.

Return type:

Bar

descending()[source]

Returns a bar with pitches in descending order.

Returns:

A new bar with pitches in descending order.

Return type:

Bar

random_order(seed=7)[source]

Returns a bar with pitches in random order.

Returns:

A new bar with pitches in random order.

Return type:

Bar

take(source, *, pitches=False, durations=False, velocities=False)[source]

Copy selected note properties from a sequence of donor notes.

This operation is immutable: neither this bar nor the donor notes are modified. Unselected properties, including tie metadata, remain those of the receiving notes, and the returned bar retains this bar’s tonality. A source bar is cycled as needed; any other iterable must contain at least as many notes as this bar.

Parameters:
  • source (Iterable[Note] | Bar) – Notes from which selected properties are copied. A bar repeats cyclically when it is shorter than the receiving bar.

  • pitches (bool) – Copy each donor’s pitches when true.

  • durations (bool) – Copy each donor’s duration when true.

  • velocities (bool) – Copy each donor’s velocity when true.

Returns:

A new bar containing the combined note properties and this bar’s tonality.

Return type:

Bar

Raises:
  • ValueError – If a nonempty bar takes from an empty source bar or a finite source does not contain enough notes.

  • TypeError – If the source yields an object that is not a Note.

merge_pitches(other)[source]

Merge corresponding events from rhythmically compatible bars.

Parameters:

other (Bar) – Bar with the same event count and corresponding durations.

Returns:

A new bar whose events contain the left pitches followed by the right pitches. Note metadata comes from the left bar, and the common tonality is preserved.

Return type:

Bar

Raises:
  • TypeError – If other is not a bar.

  • ValueError – If the bars have different event counts, corresponding durations differ, or their explicit tonalities conflict.

to_paeonia()[source]

Return paeonia notation representation of this bar.

Returns:

Lilypond notation representing all the notes in the bar

Return type:

str