accompy.converters
Core types for the chord-to-audio pipeline.
Defines the data types that flow through the pipeline, plus a converter registry that maps (source_type, target_type) pairs to converter functions.
The key types form a DAG:
ChordSheet --> ChordSequence --> NoteSequence --> MidiData --> AudioData
(Plus shortcut converters that skip intermediate steps.)
Usage:
>>> from accompy.wips.types import converter, ChordSequence, MidiData
>>> # Get a specific converter
>>> to_midi = converter[ChordSequence, MidiData]
>>> # Or convert in one call
>>> midi = convert(chord_seq, MidiData)
- class accompy.converters.AudioData(waveform: ndarray, sr: int = 44100)[source]
Container for audio data — numpy array + sample rate.
>>> import numpy as np >>> ad = AudioData(waveform=np.zeros(44100), sr=44100) >>> ad.duration_seconds 1.0
- class accompy.converters.ChordSequence(chords: list[tuple[str, float]], title: str = '', key: str = 'C', tempo: int = 120, time_signature: tuple[int, int] = (4, 4))[source]
Ordered sequence of (chord_symbol, duration_beats) pairs with metadata.
This is the canonical internal representation of a chord progression.
>>> cs = ChordSequence([("Dm7", 4.0), ("G7", 4.0), ("Cmaj7", 8.0)]) >>> len(cs) 3 >>> cs[0] ('Dm7', 4.0) >>> cs.total_beats 16.0
- property durations: list[float]
Just the durations, without symbols.
- property symbols: list[str]
Just the chord symbols, without durations.
- class accompy.converters.ConverterRegistry[source]
Registry mapping (source_type, target_type) to named converter functions.
Supports multiple converters for the same type pair, distinguished by name. The first registered converter becomes the default.
>>> reg = ConverterRegistry() >>> reg.register(str, int, int, name='builtin') >>> reg[str, int]('42') 42 >>> reg.list_converters(str, int) ['builtin']
- get(source_type: type, target_type: type, name: str | None = None) Callable[source]
Get a specific named converter, or the default if name is None.
- list_converters(source_type: type, target_type: type) list[str][source]
List available converter names for a type pair.
- register(source_type: type, target_type: type, func: Callable, *, name: str = '', is_default: bool = False) None[source]
Register a converter function.
- Parameters:
source_type – The input type
target_type – The output type
func – The converter function (source -> target)
name – Name for this converter (defaults to func.__name__)
is_default – If True, make this the default converter for this pair
- class accompy.converters.MidiData(bytes_: bytes | None = None, pretty_midi_obj: Any = None, tempo: int = 120, time_signature: tuple[int, int] = (4, 4))[source]
Container for MIDI data — either as bytes or as a pretty_midi object.
Wraps MIDI content so converters have a uniform interface regardless of which MIDI library produced the data.
>>> import io >>> md = MidiData(bytes_=b'MThd...', tempo=120) >>> md.has_bytes True
- class accompy.converters.NoteSequence(notes: list[tuple[list[int], float]], tempo: int = 120, time_signature: tuple[int, int] = (4, 4))[source]
Ordered sequence of (midi_notes, duration_beats) with metadata.
Represents resolved chords — chord symbols have been converted to concrete MIDI note numbers.
>>> ns = NoteSequence([([60, 64, 67], 4.0), ([62, 65, 69], 4.0)]) >>> ns[0] ([60, 64, 67], 4.0)
- accompy.converters.convert(source: Any, target_type: type, *, via: str | None = None) Any[source]
Convert source to target_type using the registered converter.
- Parameters:
source – The source data
target_type – The desired output type
via – Optional converter name (uses default if None)
- Returns:
Converted data of target_type
Example:
>>> # After converters are registered: >>> # audio = convert(chord_seq, AudioData)