Skip to content

Algorithmic composition tools

David Anderson edited this page Jul 5, 2025 · 6 revisions

Numula can be used for compositions that are partly or entirely algorithmic: that is, generated by programs, possibly including randomness.

It includes a few basic tools for this purpose. This is a work in progress. You can build on top of this or write your own tools.

Pitch sets

A 'pitch set' is a set of pitches (i.e. MIDI pitch numbers) that's invariant under shifting by an octave. Examples include scales and chords.

Class PitchSet represents a pitch set. Its constructor is:

PitchSet(
    pitch_offsets: list[int],
    root: int,
    probs: list[float] = None
)

pitch_offsets is a list of pitch offsets (0..11). For example, the offsets for a major scale are [0,2,4,5,7,9,11].

root is a pitch corresponding to offset 0.

probs is a list of relative probabilities of choosing each of the pitch offsets in the random note selection functions described below. If not specified, weights are identical.

PitchSet.rnd_uniform(
    lo: int,
    hi: int
) -> int

returns a pitch in the set between lo and hi inclusive, or -1 if there are none. The pitch is chosen randomly, with probabilities proportional to the probs values.

PitchSet.rnd_normal(
    mean: float,
    stddev: float,
    maxsigma: float
) -> int

return a random pitch in the set from a distribution with the given mean and stddev, truncated to the given max stddev, with probabilities proportional to the probs values.

PitchSet.gt(
    p: int,
    index: int = -1
) -> int

returns the lowest pitch in the set that is greater than p and has the given offset index (if specified). Returns -1 if there is none.

PitchSet.ge(
    p: int,
    index: int = -1
) -> int

Same, but greater than or equal.

PitchSet.lt(
    p: int,
    index: int = -1
) -> int

Same, but less than.

PitchSet.le(
    p: int,
    index: int = -1
) -> int

Same, but less than or equal.

Clone this wiki locally