Subsystem

subsequence.intervals

The API reference for register_scale and scale_notes.

register_scale

register_scale(
    name: str,
    intervals: typing.List[int],
    qualities: typing.Optional[typing.List[str]] = None,
) -> None

Register a custom scale for use with p.snap_to_scale() and scale_pitch_classes().

Built-in scale names (e.g. "minor", "hirajoshi") cannot be overwritten. Custom names may be re-registered freely — live reload re-runs registration on every save, so this must not raise.

Parameters

Raises

Example:

import subsequence

subsequence.register_scale("raga_bhairav", [0, 1, 4, 5, 7, 8, 11])

@comp.pattern(channel=0, length=4)
def melody (p):
        p.note(60, beat=0)
        p.snap_to_scale("C", "raga_bhairav")

scale_notes

scale_notes(
    key: str,
    mode: str = 'ionian',
    low: int = 60,
    high: int = 72,
    count: typing.Optional[int] = None,
) -> typing.List[int]

Return MIDI note numbers for a scale within a pitch range.

Parameters

Returns

Examples

import subsequence
import subsequence.constants.midi_notes as notes

# C major: all tones from middle C to C5
subsequence.scale_notes("C", "ionian", low=notes.C4, high=notes.C5)
# → [60, 62, 64, 65, 67, 69, 71, 72]

# E natural minor (aeolian) across one octave
subsequence.scale_notes("E", "aeolian", low=notes.E2, high=notes.E3)
# → [40, 42, 43, 45, 47, 48, 50, 52]

# 15 notes of A minor pentatonic ascending from A3
subsequence.scale_notes("A", "minor_pentatonic", low=notes.A3, count=15)
# → [57, 60, 62, 64, 67, 69, 72, 74, 76, 79, 81, 84, 86, 88, 91]

# Misalignment: key="E" but low=C4 — first note is C, not E
subsequence.scale_notes("E", "minor", low=60, count=4)
# → [60, 62, 64, 66]  (C D E F# — all in E natural minor, but starts on C)

# Fix: derive key name from root_pitch so low is always in the scale
root_pitch = 64  # E4
key = subsequence.chords.PC_TO_NOTE_NAME[root_pitch % 12]  # → "E"
subsequence.scale_notes(key, "minor", low=root_pitch, count=4)
# → [64, 66, 67, 69]  (E F# G A — starts on the root)