from musy import Note
= Note("C#")
c_sharp c_sharp
C#4
musy
is a comprehensive toolbox for analyzing and visualizing music. It lays the foundation for the Musy web apps.
At its core it has basic building blocks from which all theory can be derived:
Note
: The basic atomic unit of music.
Scale
: Stack of intervals from which harmony, (diatonic) chords, melody, etc. can be derived.
For visualization these objects can be placed on instrument surfaces:
The Note
is the basic building block from which you can create chords, scales, intervals and songs.
You can get compact representations of Note
objects. For example, their MIDI numbers and binary representations.
Notes can be added and subtracted to form new notes. Each added integer represents a semitone.
Notes can be compared using familiar Python operators.
Octaves can make a difference in comparisons.
Notes can be converted to its relative major or minor. As can be found on the circle of fifths.
Interval
objects can be obtained by calling interval
on two notes or using the &
operator.
Intervals can also be compared.
(7, 'perfect fifth', '5', 'Perfect Consonant', True, True)
The Chord
is a stack of Note
objects played together.
Chord: 'C major triad'. Notes: ['C4', 'E4', 'G4']
Chord
objects can be initialized from shorthand notation.
You can easily retrieve intervals, related chords and extensions from a Chord
object.
Chord: 'G dominant seventh'. Notes: ['G4', 'B4', 'D5', 'F5']
[C#5, D5, D#5, F5, F#5, G#5, A5]
Extension can be added and removed.
Chord: 'BM6|CM'. Notes: ['C4', 'E4', 'G4', 'B4', 'D#5', 'G#5']
Chords can also be inverted with invert
.
Like Note
objects, Chord
objects can be added and subtracted to transpose them.
Notes can be multiplied to create chords.
Each chord can be displayed in a Pandas DataFrame table, which gives a quick overview of the notes and intervals in the chord.
Notes | Relative Degree | Relative Interval | Absolute Interval | Absolute Degree | |
---|---|---|---|---|---|
0 | C | 1 | unison | unison | 1 |
1 | E | 3 | major third | major third | 3 |
2 | G | 5 | perfect fifth | minor third | b3 |
3 | B | 7 | major seventh | major third | 3 |
This get more interesting when we want to analyze more complicated chords and progressions. Take for example this chord:
Notes | Relative Degree | Relative Interval | Absolute Interval | Absolute Degree | |
---|---|---|---|---|---|
0 | C | 1 | unison | unison | 1 |
1 | D# | b3 | minor third | minor third | b3 |
2 | F# | b5 | tritone | minor third | b3 |
3 | A | 6 | major sixth | minor third | b3 |
4 | B | 7 | major seventh | major second | 2 |
We can immediately see that there are 2 minor 3rds (i.e. b3
and b5
) so the base is a diminished chord (Cdim
or C°
). It is extended with a major 6th (6
) and a major 7th (maj7
). So we can describe this as a C°6maj7
chord.
For polyphonic use cases you can create PolyChord
objects. This objects inherits the same functionality as Chord
objects.
from musy import PolyChord
c = Chord.from_short("C")
bbmaj7_3_inv = Chord.from_short("Bbmaj7").invert(3)
poly_chord = PolyChord([c, bbmaj7_3_inv])
poly_chord
PolyChord: 'C major triad|Bb major seventh, third inversion'. Notes: ['C4', 'E4', 'G4', 'A4', 'Bb5', 'D5', 'F5']
Within PolyChord
objects we can treat it as a single chord or analyze the underlying chords separately. For example, here we display 2 tables to analyze the underlying chords of the PolyChord
object.
poly_chord_tables = poly_chord.to_frame()
print(f"Chord 1: {poly_chord.chords[0].name}")
display(poly_chord_tables[0])
print(f"Chord 2: {poly_chord.chords[1].name}")
display(poly_chord_tables[1])
Chord 1: C major triad
Notes | Relative Degree | Relative Interval | Absolute Interval | Absolute Degree | |
---|---|---|---|---|---|
0 | C | 1 | unison | unison | 1 |
1 | E | 3 | major third | major third | 3 |
2 | G | 5 | perfect fifth | minor third | b3 |
Chord 2: Bb major seventh, third inversion
Notes | Relative Degree | Relative Interval | Absolute Interval | Absolute Degree | |
---|---|---|---|---|---|
0 | A | 1 | unison | unison | 1 |
1 | Bb | b9 | minor ninth | minor ninth | b9 |
2 | D | 4 | perfect fourth | minor sixth | b6 |
3 | F | b6 | minor sixth | minor third | b3 |
Scale
objects are collections of intervals from which we can generate notes and chords around a root note.
When given a root note, Scale
generates the notes of the scale.
All the modes of any Scale
can be generated.
[Scale: Dorian. Intervals: ['1', '2', 'b3', '4', '5', '6', 'b7'],
Scale: Phrygian. Intervals: ['1', 'b2', 'b3', '4', '5', 'b6', 'b7'],
Scale: Lydian. Intervals: ['1', '2', '3', '#4', '5', '6', '7'],
Scale: Mixolydian. Intervals: ['1', '2', '3', '4', '5', '6', 'b7'],
Scale: Minor. Intervals: ['1', '2', 'b3', '4', '5', 'b6', 'b7'],
Scale: Locrian. Intervals: ['1', 'b2', 'b3', '4', 'b5', 'b6', 'b7'],
Scale: Ionian. Intervals: ['1', '2', '3', '4', '5', '6', '7']]
Triads and seventh chords in the scale can be generated around a root note.
[Chord: 'D minor triad'. Notes: ['D4', 'F4', 'A4'],
Chord: 'E minor triad'. Notes: ['E4', 'G4', 'B4'],
Chord: 'F major triad'. Notes: ['F4', 'A4', 'C4'],
Chord: 'G major triad'. Notes: ['G4', 'B4', 'D5'],
Chord: 'A minor triad'. Notes: ['A4', 'C4', 'E5'],
Chord: 'B diminished triad'. Notes: ['B4', 'D5', 'F5'],
Chord: 'C major triad'. Notes: ['C5', 'E6', 'G6']]
You can get all the secondary dominants (i.e. V7
chords) of a given Scale
.
[Chord: 'G dominant seventh'. Notes: ['G4', 'B4', 'D5', 'F5'],
Chord: 'A dominant seventh'. Notes: ['A4', 'C#5', 'E5', 'G5'],
Chord: 'B dominant seventh'. Notes: ['B4', 'D#5', 'F#5', 'A5'],
Chord: 'No chord found.'. Notes: ['C5', 'E5', 'G5', 'A#5'],
Chord: 'D dominant seventh'. Notes: ['D5', 'F#5', 'A5', 'C6'],
Chord: 'E dominant seventh'. Notes: ['E5', 'G#5', 'B5', 'D6'],
Chord: 'F# dominant seventh'. Notes: ['F#5', 'A#5', 'C#6', 'E6']]
[Chord: 'E minor seventh'. Notes: ['E4', 'G4', 'B4', 'D4'],
Chord: 'F# minor seventh'. Notes: ['F#4', 'A4', 'C#4', 'E5'],
Chord: 'G major seventh'. Notes: ['G4', 'B4', 'D4', 'F#5'],
Chord: 'A dominant seventh'. Notes: ['A4', 'C#4', 'E5', 'G5'],
Chord: 'B minor seventh'. Notes: ['B4', 'D4', 'F#5', 'A5'],
Chord: 'C# half diminished seventh'. Notes: ['C#5', 'E6', 'G6', 'B6'],
Chord: 'D major seventh'. Notes: ['D5', 'F#6', 'A6', 'C#6']]
All information can be conveniently retrieved and displayed as a Pandas DataFrame with to_frame
.
Degree | Relative Interval | Mode | Relative Semitones | Absolute Semitones | Notes | Triad | Seventh Chord | |
---|---|---|---|---|---|---|---|---|
0 | 1 | unison | dorian | 0 | 2 | E | E minor triad | E minor seventh |
1 | 2 | major second | phrygian | 2 | 1 | F# | F# minor triad | F# minor seventh |
2 | b3 | minor third | lydian | 3 | 2 | G | G major triad | G major seventh |
3 | 4 | perfect fourth | mixolydian | 5 | 2 | A | A major triad | A dominant seventh |
4 | 5 | perfect fifth | minor | 7 | 2 | B | B minor triad | B minor seventh |
5 | 6 | major sixth | locrian | 9 | 1 | C# | C# diminished triad | C# half diminished seventh |
6 | b7 | minor seventh | ionian | 10 | 2 | D | D major triad | D major seventh |
Consult Scale.available_scales
for a list of available scales. If a scale is not available, you can create your own scale from intervals.
Scale: Persian. Intervals: ['1', 'b2', '3', '4', 'b5', 'b6', '7']
[Chord: 'No chord found.'. Notes: ['C4', 'E4', 'F#4'],
Chord: 'No chord found.'. Notes: ['C#4', 'F4', 'G#4'],
Chord: 'E suspended second triad'. Notes: ['E4', 'F#4', 'B4'],
Chord: 'No chord found.'. Notes: ['F4', 'G#4', 'C5'],
Chord: 'F# suspended fourth triad'. Notes: ['F#4', 'B4', 'C#5'],
Chord: 'C augmented triad, second inversion'. Notes: ['G#4', 'C5', 'E5'],
Chord: 'No chord found.'. Notes: ['B4', 'C#5', 'F5']]
Note
, Chord
, PolyChord
and Scale
objects can all be heard by calling the play
method on them. Check out the musy documentation on Note
, Chord
, PolyChord
and Scale
for example code and audio playbacks.
musy
objects can be visualized on a piano or guitar by providing a list of Note
objects to the rendering method. Notes can easily be retrieved from Chord
and Scale
objects.
musy
will show the minimum octaves on the piano needed to show the object. Here for example a single C#
on one octave.
Here is an example of visualizing a Cadd9/F
chord where we need multiple octaves.
cadd9_over_f = Chord([Note("F", 2), Note("C", 3), Note("E", 3), Note("G", 3), Note("D", 4)])
Piano().visualize_chord(cadd9_over_f)
For scale visualization on Piano
we show 2 octaves by default. The number of octaves can be controlled with the octs
parameter.
visualize_note
shows options for a given note in a certain octave. For example a C4
is shown below.
visualize_chord
shows you all the notes across octaves to spot different voicings.
visualize_scale
shows all notes in the scale from a given root note.