automuse package

Subpackages

Submodules

automuse.guesser module

Utilities that match notes with scales. Matching scales contain the given notes, possibly in the exact order.

This is effectively a brute-force implementation of chord-scale theory.

class automuse.guesser.MatchResult[source]

Bases: NamedTuple

MatchResult(key, mode, matched, unmatched, unused, check, against)

key: str

Base note of the matched scale / chord

mode: str

Mode of the matched scale / chord

matched: list[str]

Matching notes

unmatched: list[str]

Notes that are in the subject, but not in the matched scale / chord

unused: list[str]

Notes that are in the matched scale / chord, but not in the subject

check: list[str]

Notes to be matched

against: list[str]

Notes to be matched against

automuse.guesser.guess_scale(notes: Sequence[str], mode_specs: Sequence[ModeSpec], roots: Sequence[str] = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'), sort_key: Literal['matched'] | Literal['unused'] | Literal['unmatched'] | Literal['matched_percent'] = 'matched', match_order: Literal['substring'] | Literal['order'] | Literal['any'] = 'any') list[MatchResult][source]

Check which scale or chord contain subject.

Parameters:
  • subject – A set of note classes, for example {"A", "A#"}.

  • test_scales – Interval patterns to compare subject against, for example TEST_SCALES_STANDARD.

  • roots – Note classes to construct test_scales on. The default NOTE_NAMES contains all note classes.

  • sort_key – How the returned list is sorted. See attributes of MatchResult for what the available values mean. Also, matched_percent uses the ratio of matched notes against unused notes.

  • match_order

    How notes is checked against test_modes:

    • "substring": Match the longest substring

      of notes.

    • "order": Match notes in notes in order,

      moving on to the next once a note is matched.

    • "any": Match any note that occur in

      notes.

automuse.guesser.guess_chord(notes: Iterable[str], mode_specs: Iterable[ModeSpec] = (([2, 2, 1, 2, 2, 2], 'M'), ([2, 1, 2, 2, 1, 2], 'm'), ([2, 1, 2, 2, 1, 2], 'm (Natural)'), ([2, 1, 2, 2, 1, 3], 'm (Harmonic)'), ([2, 1, 2, 2, 2, 2], 'm (Melodic)'), ([3, 1, 3, 1, 3], 'A'), ([2, 1, 2, 1, 2, 1, 2], 'Dim W-H'), ([1, 2, 1, 2, 1, 2, 1], 'Dim H-W'), ([2, 2, 3, 2], 'M (Pentatonic)'), ([3, 2, 2, 3], 'm (Pentatonic)'), ([2, 1, 1, 3, 2], 'M (Blues)'), ([3, 2, 1, 1, 3], 'm (Blues)'), ([2, 2, 2, 2, 2], 'WholeTone'), ([2, 2, 1, 2, 2, 2], 'Ionian'), ([2, 1, 2, 2, 2, 1], 'Dorian'), ([1, 2, 2, 2, 1, 2], 'Phrygian'), ([2, 2, 2, 1, 2, 2], 'Lydian'), ([2, 2, 1, 2, 2, 1], 'Mixolydian'), ([2, 1, 2, 2, 1, 2], 'Aeolian'), ([1, 2, 2, 1, 2, 2], 'Locrian')), tonics: Iterable[str] = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'), chords: Iterable[Literal['triad'] | Literal['seventh']] = ('triad', 'seventh'), orders: Iterable[int] = (0, 1, 2, 3, 4, 5, 6, 7), inversions: Sequence[int] = (0, 1, 2, 3), sort_key: Literal['matched'] | Literal['unused'] | Literal['unmatched'] | Literal['matched_percent'] = 'matched', match_order: Literal['substring'] | Literal['order'] | Literal['any'] = 'any') list[MatchResult][source]

Convenience function that guess which chords contain notes.

This function can guess against:

  • Triads

  • Seventh chords of all qualities (major, minor, augmented, diminished)

  • Modes (e.g. M, m, Dorian)

  • Inversions

  • Orders (e.g. \(\textrm{I}\))

It cannot guess against:

  • Add, sus, sharp, and flat chords

  • Extra notes by intervals (e.g. b6)

  • Extended chords above seventh

For a more powerful guesser, consider guess_scale() with TEST_CHORDS.

Parameters:
  • tonics – See chord().

  • mode_specs – See guess_scale().

  • chords – Can be "triad", "seventh", or both.

  • orders – See chord().

  • inversions – See chord().

  • sort_key – See guess_scale().

  • match_order – See guess_scale().

automuse.guesser.guess(check: Iterable[str], test_scales: list[ScaleSpec], sort_key: Literal['matched'] | Literal['unused'] | Literal['unmatched'] | Literal['matched_percent'], match_order: Literal['substring'] | Literal['order'] | Literal['any']) list[MatchResult][source]

Helper function. Check :arg”check against scales or chords in against.

This function is a big dispatcher: it has several options (sort_key) and (match_order). Beware of that.

See guess_scale() for arguments.

automuse.guesser.tabulate_guess(result: list[MatchResult], tablefmt: str = 'simple') None[source]

automuse.guitar module

Utilities that visualise notes on a fretboard.

automuse.guitar.notes_on_string(start: int, capo: int, length: int) list[int][source]

Return a list of length notes on a string that begins with the start th note at capo capo.

automuse.guitar.notes_on_fretboard(capo: int, length: int, tuning: list[int]) list[list[int]][source]

Return a matrix of notes for all strings on a guitar for the given tuning.

The item at [i][j] is the jth note on the ith string … I think.

automuse.guitar.notes_of_interest(notes: list[str], octave_matrix: list[list[int]], strict: bool = False) list[list[int | None]][source]

Given a matrix of notes, replace items that are not in the given scale with None, then return the result.

Use to visualise chords.

automuse.guitar.disseminate_neural_lattices(height: int, length: int)[source]

Render the local neighbourhood structure of a Riemannian topological manifold.

automuse.guitar.draw_key_at_location(reverse_string_loc: int, fret_loc: int, key_name: str)[source]
automuse.guitar.draw_dot_at_location(reverse_string_loc: float, fret_loc: float, **kwargs)[source]
automuse.guitar.draw_capo(capo: int) None[source]
automuse.guitar.draw_scale(scale: list[str], capo: int, width: int, strict: bool = False) None[source]

automuse.midi module

Utilities that play MIDI notes.

automuse.midi.show_ports() list[str][source]

Show a list of available MIDI ports.

These names can be given to set_default_port() and Player.

automuse.midi.set_default_port(port_name: str) None[source]

Set the default output port DEFAULT_PORT. Player uses this port when one is not given in its initialiser.

class automuse.midi.Player[source]

Bases: object

__init__(port: str = 'Microsoft GS Wavetable Synth 0', pool_size: int = 6)[source]
automuse.midi.play(player: Player, notes: str | list[str], duration: float = 2, channel: Channel = 0, velocity: int = 64, *, arpeggio: Literal['ascending'] | Literal['descending'] | None = None, spacing: float | tuple[float, float] = 0, touch: int | tuple[int, int] = 0) None[source]

Play notes with player.

Parameters:
  • player – A context manager that controls a MIDI channel.

  • notes – Note or chord to play.

  • duration – Duration of the note or chord.

  • channel – Channel to play the note or chord in.

  • velocity – Velocity of the note or chord.

  • arpeggio – Order of the note or chord. If None, then the order in notes is used.

  • spacing – Melodic intervals between notes in the chord. If 0, then all notes are played at the same time.

  • touch – Variation in note velocity (touch pressure). Simulates the beautiful human imperfection.

class automuse.midi.Instrument[source]

Bases: IntEnum

Instrument codes implemented with reference to the General MIDI Level 1 specification (source).

AcousticGrandPiano = 1
BrightAcousticPiano = 2
ElectricGrandPiano = 3
HonkyTonkPiano = 4
ElectricPiano1 = 5
ElectricPiano2 = 6
Harpsichord = 7
Clavi = 8
Celesta = 9
Glockenspiel = 10
MusicBox = 11
Vibraphone = 12
Marimba = 13
Xylophone = 14
TubularBells = 15
Dulcimer = 16
DrawbarOrgan = 17
PercussiveOrgan = 18
RockOrgan = 19
ChurchOrgan = 20
ReedOrgan = 21
Accordion = 22
Harmonica = 23
TangoAccordion = 24
AcousticGuitarNylon = 25
AcousticGuitarSteel = 26
ElectricGuitarJazz = 27
ElectricGuitarClean = 28
ElectricGuitarMuted = 29
OverdrivenGuitar = 30
DistortionGuitar = 31
Guitarharmonics = 32
AcousticBass = 33
ElectricBassFinger = 34
ElectricBassPick = 35
FretlessBass = 36
SlapBass1 = 37
SlapBass2 = 38
SynthBass1 = 39
SynthBass2 = 40
Violin = 41
Viola = 42
Cello = 43
Contrabass = 44
TremoloStrings = 45
PizzicatoStrings = 46
OrchestralHarp = 47
Timpani = 48
StringEnsemble1 = 49
StringEnsemble2 = 50
SynthStrings1 = 51
SynthStrings2 = 52
ChoirAahs = 53
VoiceOohs = 54
SynthVoice = 55
OrchestraHit = 56
Trumpet = 57
Trombone = 58
Tuba = 59
MutedTrumpet = 60
FrenchHorn = 61
BrassSection = 62
SynthBrass1 = 63
SynthBrass2 = 64
SopranoSax = 65
AltoSax = 66
TenorSax = 67
BaritoneSax = 68
Oboe = 69
EnglishHorn = 70
Bassoon = 71
Clarinet = 72
Piccolo = 73
Flute = 74
Recorder = 75
PanFlute = 76
BlownBottle = 77
Shakuhachi = 78
Whistle = 79
Ocarina = 80
Lead1Square = 81
Lead2Sawtooth = 82
Lead3Calliope = 83
Lead4Chiff = 84
Lead5Charang = 85
Lead6Voice = 86
Lead7Fifths = 87
Lead8BassPlusLead = 88
Pad1Newage = 89
Pad2Warm = 90
Pad3Polysynth = 91
Pad4Choir = 92
Pad5Bowed = 93
Pad6Metallic = 94
Pad7Halo = 95
Pad8Sweep = 96
FX1Rain = 97
FX2Soundtrack = 98
FX3Crystal = 99
FX4Atmosphere = 100
FX5Brightness = 101
FX6Goblins = 102
FX7Echoes = 103
FX8SciFi = 104
Sitar = 105
Banjo = 106
Shamisen = 107
Koto = 108
Kalimba = 109
Bagpipe = 110
Fiddle = 111
Shanai = 112
TinkleBell = 113
Agogo = 114
SteelDrums = 115
Woodblock = 116
TaikoDrum = 117
MelodicTom = 118
SynthDrum = 119
ReverseCymbal = 120
GuitarFretNoise = 121
BreathNoise = 122
Seashore = 123
BirdTweet = 124
TelephoneRing = 125
Helicopter = 126
Applause = 127
Gunshot = 128
class automuse.midi.Percussion[source]

Bases: object

Percussion instrument codes implemented with reference to the General MIDI Level 1 specification (source).

Use these values as notes and not as instruments. On channel 10 (or 9 because channels in MIDI messages are zero-indexed), notes are interpreted as percussion sounds.

AcousticBassDrum = 35
BassDrum = 36
SideStick = 37
AcousticSnare = 38
HandClap = 39
ElectricSnare = 40
LowFloorTom = 41
ClosedHiHat = 42
HighFloorTom = 43
PedalHiHat = 44
LowTom = 45
OpenHiHat = 46
LowMidTom = 47
HiMidTom = 48
HighTom = 50
ChineseCymbal = 52
RideBell = 53
Tambourine = 54
SplashCymbal = 55
Cowbell = 56
CrashCymbal = 57
Vibraslap = 58
RideCymbal = 59
HiBongo = 60
LowBongo = 61
MuteHiConga = 62
OpenHiConga = 63
LowConga = 64
HighTimbale = 65
LowTimbale = 66
HighAgogo = 67
LowAgogo = 68
Cabasa = 69
Maracas = 70
ShortWhistle = 71
LongWhistle = 72
ShortGuiro = 73
LongGuiro = 74
Claves = 75
HiWoodBlock = 76
LowWoodBlock = 77
MuteCuica = 78
OpenCuica = 79
MuteTriangle = 80
OpenTriangle = 81
__init__() None
automuse.midi.change_instrument(player: Player, channel: Channel, instrument: Instrument) None[source]

automuse.modes module

Patterns that are useful for constructing scales and chords.

A scale is constructed with a note and one such pattern (for example, C major consists of the note C as well as the 2nd, 4th, 5th … and so on, notes from C.) This pattern is the mode (or key) of the scale.

Whereas scales (see scale) are constructed by picking notes in a music space, chords are (see chord) constructed by picking notes from a scale. Both (scale) and (chord) can use constants defined in this module.

automuse.modes.reduce_mode(mode: list[int], indices: list[int]) list[int][source]

Reduce mode to only include notes at indices.

For example, scale("C", MAJOR) returns ["C", "D", ..., "B"]; scale("C", reduce_mode(MAJOR, [0, 2, 4]) returns only ["C", "E", "G"].

automuse.modes.pentatonic_major(hep: list[int]) list[int][source]
automuse.modes.pentatonic_minor(hep: list[int]) list[int][source]
automuse.modes.blues_major(hep: list[int]) list[int][source]
automuse.modes.blues_minor(hep: list[int]) list[int][source]
automuse.modes.harmonic_minor(minor_scale: list[int]) list[int][source]
automuse.modes.melodic_minor(minor_scale: list[int]) list[int][source]
automuse.modes.intervals_to_offsets(intervals: Sequence[int]) list[int][source]
automuse.modes.offsets_to_intervals(offsets: Sequence[int]) list[int][source]

automuse.scale module

Utilities that construct scales.

automuse.scale.scale(tonic: str, mode: list[int], include_tonic: bool = True, use_offsets: bool = False) list[str][source]

Construct a scale in mode from tonic.

Parameters:
  • tonic – A note like C# and C#4.

  • mode – A sequence of intervals, like [2, 2, 1, 2, 2, 2] for the major scale. See modes for pre-made options.

  • include_tonic – If True, then prepend tonic to the result.

  • use_offsets – If True, the interpret mode as a sequence of Offsets (instead of Intervals). Note that

automuse.transforms module

Transforms, or transformations. From inversion and transposition to the neo-Riemannian school of transforms.

Neo-Riemannian transforms are implemented referencing //Hollywood Harmony// by Lehman.

automuse.transforms.invert(arg: str) str[source]
automuse.transforms.invert(arg: Interval | Note) Interval | Note

Invert an interval. Or a note.

Works with both because taking the modular complement happens to have the same effect on both.

automuse.transforms.invert_chord(notes: list[str]) list[str][source]

Invert notes by 1.

automuse.transforms.invert_chord_by(notes: list[str], invert_by: int) list[str][source]

Invert notes by invert_by.

automuse.transforms.invert_chord_to(notes: list[str], note: str) list[str][source]

Invert notes to note. In other words, slash chord.

Degree of inversion is computed with the note class of note; its octave does not matter.

automuse.transforms.transpose(note: str, by: int) str[source]
automuse.transforms.transpose(note: list[str], by: int) list[str]

Transpose a note or notes by semitones.

automuse.transforms.nrt_parallel(triad: list[str]) list[str][source]

The parallel transform (P) maps a major triad to its minor.

automuse.transforms.nrt_relative(triad: list[str]) list[str][source]

The relative transform (R) maps a major triad to its relative minor, and a minor triad to its relative major.

automuse.transforms.nrt_slide(triad: list[str]) list[str][source]

The slide transform (S) maps a major triad to the minor triad one semitone higher.

automuse.transforms.nrt_leading_tone_exchange(triad: list[str]) list[str][source]

The leading tone exchange (L, Leittonwechselklänge) transform maps a major triad to the minor triad a major third higher.

automuse.transforms.nrt_near_fifth(triad: list[str]) list[str][source]

The near fifth (N) transform maps a major triad to its fifth minor, and a minor triad to its fifth major.

automuse.transforms.nrt_far_fifth(triad: list[str]) list[str][source]

The far fifth (F) transform maps a major triad to its fourth minor, and a minor triad to its fourth major.

automuse.transforms.nrt_dominant(triad: list[str], inverse: bool = False) list[str][source]

The dominant transform (N) maps a triad to its fifth with the same quality.

Note that this will only raise, and never lower, the root. Set inverse to True to map back.

automuse.transforms.nrt_hexatonic_pole(triad: list[str]) list[str][source]

The hexatonic pole (H) maps a major triad to the triad that is a major 3 before it.

Source: Audacious Euphony.

automuse.transforms.nrt_t6(triad: list[str], up: bool = True) list[str][source]

The T6 transform transposes all notes in a chord by 6 semitones. That’s half an octave.

Source: Neo-Riemannian examples in music

Module contents

Definition of the pitch space, notes, intervals, and basic operations on them.

automuse.Interval

Interval. Difference between notes in semitones.

automuse.Offset

Offset from tonic / root to a note.

automuse.Note

Pitch. Index in NOTES.

automuse.Degree

Scale degree

automuse.note_m2s(note: int) str[source]

Map an index to its value in NOTES_MIDI.

Unlike note_i2s(), this function always uses NOTES_MIDI.

automuse.note_s2m(note: str) int[source]

Map a name to its index in NOTES_MIDI.

Unlike note_s2i(), this function always uses NOTES_MIDI.

automuse.note_i2s(note: Note | None) str[source]
automuse.note_i2s(note: Sequence[Note | None]) list[str]

Map an index or sequence of indices to names in NOTES.

automuse.note_s2i(name: str, solfege: bool = False) Note[source]
automuse.note_s2i(name: list[str], solfege: bool = False) list[Note]

Map a name or sequence of names to indices of NOTES.

automuse.NOTE_NAMES: tuple[str, ...] = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')

Names of note classes.

automuse.interval_s2i(name: str) int[source]

Map a interval name (e.g. major 2) to a semitone difference.

automuse.interval_i2s(key_num: int) list[str][source]

Map a semitone difference to a list of possible nams. Does not consider the generic interval.

automuse.get_interval(note_from: str, note_to: str) int[source]

Take two notes and return the interval between them, in semitones.

automuse.name_interval(note_from: str, note_to: str) str[source]

Take two notes and return the name of their interval.

automuse.reach(root: str, interval: str | int, reverse: bool = False) str[source]

“Reach up” from tonic by interval. interval can be either a number (e.g. 1) or a string (e.g. "augmented 8").

In the latter case, interval should be a key in INTERVALS.

automuse.reach_many(root: str, interval_list: Sequence[str]) list[str][source]

Obtain nodes by repeatedly reaching up from root by intervals in interval_list.

Useful for building triads and scales from intervals.

automuse.extract_pitch_class(expr: str) str[source]

Map a note in IPN to its pitch class.

For example, "C#4" maps to "C#".

automuse.same_class(a: list[str], b: list[str]) bool[source]
automuse.same_class(a: str, b: str) bool

Return if a and b belong to the same pitch class.