braidio.sources#

Segment sources: resolve a reference to a cuttable [start, end] window.

A production weaves in extracted segments of source media. How a reference (a lyric quote, an audiobook passage, a news phrase, an SFX cue) maps to a concrete [start, end] span of a source asset is pluggable via the SegmentSource protocol — the weave engine never needs to know it is lyrics.

This module ships two generic implementations. TimedLineSegmentSource, a token-F1 matcher over time-aligned lines (TimedLine). It answers a reference by the best contiguous run of lines — handling exact, sub-line, and multi-line references. Consumers bind it to their own timed lines + asset (e.g. Hamilton binds LRCLIB line timings + owned song audio). And NamespacedSegmentSource routes a prefixed reference to one of several sub-sources, which is how a production that cuts between two recordings of the same work says which recording a given quote should come from.

Also provides the lower-level resolver (find_segment(), load_timing()) and the resolve-and-cut convenience (cut_quote()) used directly by the Hamilton pilot; new code should prefer the SegmentSource protocol + braidio.weave.extract_padded().

Functions

cut_quote(audio_path, lines, quote, out_path, *)

Resolve quote → segment and cut it from audio_path (pad + fades).

find_segment(lines, quote, *[, max_span, ...])

Best contiguous run of timed lines matching quote, or None.

load_timing(path)

Load a {lines: [{index,start_s,end_s,text}]} JSON into `TimedLine`s.

Classes

NamespacedSegmentSource(sources, *[, sep, ...])

A SegmentSource that routes prefixed references to sub-sources.

ResolvedSegment(asset_path, start_s, end_s)

A cuttable span of a source asset — what a SegmentSource returns.

Segment(start_s, end_s, score, line_start, ...)

A resolved window for a reference, with the matched line span.

SegmentSource(*args, **kwargs)

Resolve an opaque reference to a ResolvedSegment (or None).

TimedLine(index, start_s, end_s, text)

A source line with a [start_s, end_s) window (end may be None = tail).

TimedLineSegmentSource(*, lines, asset_path)

A SegmentSource over time-aligned lines + one source asset.

class braidio.sources.NamespacedSegmentSource(sources, *, sep=':', default=None)[source]#

Bases: object

A SegmentSource that routes prefixed references to sub-sources.

A production that cuts between several recordings of the same work — two takes of one song, a studio master and a live version, an audiobook read in two languages — hits a wall: render_production(..., source=...) takes one SegmentSource, and a reference like a lyric line matches equally well in every recording. Which asset a quote should come from is a production decision, not something a token matcher can infer.

This routes on an explicit prefix, so the script says which recording it means:

source = NamespacedSegmentSource(
    {
        "1966": TimedLineSegmentSource(lines=studio, asset_path="studio.mp3"),
        "1981": TimedLineSegmentSource(lines=live, asset_path="live.mp3"),
    }
)
SegmentBeat("1981: and in the naked light I saw")  # → the live master
Parameters:
  • sources (dict[str, SegmentSource]) – Namespace → sub-source. Namespaces are matched case-insensitively and with surrounding whitespace stripped.

  • sep (str) – Separator between the namespace and the reference body.

  • default (str | None) – Namespace used for an unprefixed reference. None (the default) makes an unprefixed reference an error.

Raises:

KeyError – on an unknown namespace, or an unprefixed reference with no default. This is deliberate: silently falling through to the wrong recording would ship one performance under commentary that describes another — the failure a listener cannot detect and the author cannot see in a diff.

property namespaces: list[str]#

The namespaces this source routes, in insertion order.

split(reference)[source]#

Split reference into (namespace, body), applying the default.

Return type:

tuple[str, str]

class braidio.sources.ResolvedSegment(asset_path, start_s, end_s, score=1.0, matched_text='')[source]#

Bases: object

A cuttable span of a source asset — what a SegmentSource returns.

class braidio.sources.Segment(start_s, end_s, score, line_start, line_end, matched_text)[source]#

Bases: object

A resolved window for a reference, with the matched line span.

class braidio.sources.SegmentSource(*args, **kwargs)[source]#

Bases: Protocol

Resolve an opaque reference to a ResolvedSegment (or None).

class braidio.sources.TimedLine(index, start_s, end_s, text)[source]#

Bases: object

A source line with a [start_s, end_s) window (end may be None = tail).

class braidio.sources.TimedLineSegmentSource(*, lines, asset_path, song_end_s=None, min_score=0.5)[source]#

Bases: object

A SegmentSource over time-aligned lines + one source asset.

Binds the generic find_segment() matcher to a concrete asset so the weave engine can resolve(reference) -> ResolvedSegment.

braidio.sources.cut_quote(audio_path, lines, quote, out_path, *, pad_pre_s=0.15, pad_post_s=0.35, fade_s=0.04, min_score=0.5, song_end_s=None)[source]#

Resolve quote → segment and cut it from audio_path (pad + fades).

Convenience combining find_segment() + an ffmpeg cut. Returns the resolved Segment (raises LookupError if unmatched). New code should prefer a SegmentSource + braidio.weave.extract_padded().

Return type:

Segment

braidio.sources.find_segment(lines, quote, *, max_span=12, min_score=0.5, song_end_s=None)[source]#

Best contiguous run of timed lines matching quote, or None.

Scores every run lines[i..j] (up to max_span lines) by token F1 against the reference’s tokens and returns the highest-scoring run clearing min_score. Handles single-line, sub-line, and multi-line references.

Return type:

Segment | None

braidio.sources.load_timing(path)[source]#

Load a {lines: [{index,start_s,end_s,text}]} JSON into `TimedLine`s.

Return type:

list[TimedLine]