Skip to main content

Toolbox for analyzing, creating and visualizing music

Project description

musy

Installation

pip install musy

How to use

Note

from musy import Note, Chord, Scale

The Note is the basic building block from which you can create chords and songs.

c_sharp = Note("C#")
c_sharp
musy.core.Note(note='C#', oct=4)

Notes can be added and subtracted to form new notes. Each added integer represents a semitone.

c_sharp + 1
musy.core.Note(note='D', oct=4)
c_sharp - 1
musy.core.Note(note='C', oct=4)
c_sharp + 14
musy.core.Note(note='D#', oct=5)

Notes can be compared using familiar Python operators.

c = Note("C")
g = Note("G")

c < g
True

Octaves can make a difference in comparisons.

Note("C", oct=4) >= Note("G", oct=3)
True

Interval objects can be obtained by calling interval on two notes or using the & operator.

f_sharp = Note("F#")

P4 = c_sharp & f_sharp
P4
perfect fourth (4)
P4.semitones, P4.long, P4.short, P4.type()
(5, 'perfect fourth', '4', 'Contextual')

Intervals can also be compared.

P5 = c & g
P5
perfect fifth (5)
P5.semitones, P5.long, P5.short, P5.type()
(7, 'perfect fifth', '5', 'Perfect Consonant')
P4 != P5
True
P4 < P5
True

Notes can be converted to its relative major or minor. As can be found on the circle of fifths.

Note("C").minor()
musy.core.Note(note='A', oct=4)
Note("C#").major()
musy.core.Note(note='E', oct=4)

Chord

The Chord is a collection of Note objects played together.

c_major = Chord(["C", "E", "G"])
c_major
Chord: 'C major triad'. Notes: ['C4', 'E4', 'G4']

Chord objects can be initialized from shorthand notation.

cmaj7 = Chord.from_short("Cmaj7")
cmaj7
Chord: 'C major seventh'. Notes: ['C4', 'E4', 'G4', 'B4']

Chords can also be inverted with invert.

# Get 1st inversion chord of C major 7th
cmaj7.invert(1)
Chord: 'C major seventh, first inversion'. Notes: ['E4', 'G4', 'B4', 'C5']

Like Note objects, Chord objects can be added and subtracted to transpose them.

cmaj7 + 2
Chord: 'D major seventh'. Notes: ['D4', 'F#4', 'A4', 'C#5']

Notes can be multiplied to create chords.

Note("C") * Note("E") * Note("G")
Chord: 'C major triad'. Notes: ['C4', 'E4', 'G4']

For advanced usage there is even a way to create PolyChord objects. These are most naturally created by multiplying Chord objects.

Chord.from_short("C") * Chord.from_short("Bbmaj7").invert(3)
PolyChord: 'C major triad|Bb major seventh, third inversion'. Notes: ['C4', 'E4', 'G4', 'A4', 'Bb5', 'D5', 'F5']

Scale

Scale objects are collections of intervals from which we can generate notes and chords around a root note.

dorian = Scale("dorian")
dorian
Scale: Dorian. Intervals: ['1', '2', 'b3', '4', '5', '6', 'b7']

When given a root note, Scale generates the notes of the scale.

dorian.get_notes("C")
[musy.core.Note(note='C', oct=4),
 musy.core.Note(note='D', oct=4),
 musy.core.Note(note='D#', oct=4),
 musy.core.Note(note='F', oct=4),
 musy.core.Note(note='G', oct=4),
 musy.core.Note(note='A', oct=4),
 musy.core.Note(note='A#', oct=4)]

Intervals can be obtained.

dorian.get_interval_names()
['major second',
 'minor third',
 'perfect fourth',
 'perfect fifth',
 'major sixth',
 'minor seventh']

Triads and seventh chords in the scale can be generated around a root note.

dorian.get_triads("D")
[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']]
dorian.get_sevenths("E")
[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.

dorian.to_frame(root="E")
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
Intervals Relative Semitones Absolute Semitones Notes Triads Seventh Chords
0 1 0 2 E E minor triad E minor seventh
1 2 2 1 F# F# minor triad F# minor seventh
2 b3 3 2 G G major triad G major seventh
3 4 5 2 A A major triad A dominant seventh
4 5 7 2 B B minor triad B minor seventh
5 6 9 1 C# C# diminished triad C# half diminished seventh
6 b7 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.

persian = Scale.from_intervals("persian", ["1", "b2", "3", "4", "b5", "b6", "7"])
persian
Scale: Persian. Intervals: ['1', 'b2', '3', '4', 'b5', 'b6', '7']
persian.get_notes("C")
[musy.core.Note(note='C', oct=4),
 musy.core.Note(note='C#', oct=4),
 musy.core.Note(note='E', oct=4),
 musy.core.Note(note='F', oct=4),
 musy.core.Note(note='F#', oct=4),
 musy.core.Note(note='G#', oct=4),
 musy.core.Note(note='B', oct=4)]

Note, Chord, PolyChord and Scale objects can all be heard by calling the play method on them.

Visualization

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.

from musy import Piano, Guitar

Piano()(Note("C#"))
<style>
.piano { background: #222; padding: 20px 0; position: relative; width: 480px; }
.white-keys { display: flex; }
.white-key {
    width: 40px; height: 125px; background: #fff;
    border: 1px solid #000;
    color: #111; font-size: 18px; text-align: center; line-height: 200px; font-family: Arial;
    position: relative; z-index: 1;
}
.black-key {
    width: 20px; height: 80px; background: #000; color: #fff;
    border: 1px solid #333; position: absolute; z-index: 2;
    text-align: center; line-height: 100px; font-family: Arial; font-size: 14px;
    left: 0; top: 20px; pointer-events: none;
}
.highlight { background: #ff0 !important; color: #000 !important; }
.highlight-black { background: #ff0 !important; color: #000 !important; }
</style>
<div class="piano" style="width:440px"><div class="white-keys"><div class="white-key">C</div><div class="white-key">D</div><div class="white-key">E</div><div class="white-key">F</div><div class="white-key">G</div><div class="white-key">A</div><div class="white-key">B</div><div class="white-key">C</div><div class="white-key">D</div><div class="white-key">E</div><div class="white-key">F</div><div class="black-key highlight-black" style="left:26px">C#</div><div class="black-key" style="left:66px">D#</div><div class="black-key" style="left:146px">F#</div><div class="black-key" style="left:186px">G#</div><div class="black-key" style="left:226px">A#</div><div class="black-key highlight-black" style="left:306px">C#</div><div class="black-key" style="left:346px">D#</div><div class="black-key" style="left:426px">F#</div></div>
Piano()(list(Chord.from_short("Cmaj7")))
<style>
.piano { background: #222; padding: 20px 0; position: relative; width: 480px; }
.white-keys { display: flex; }
.white-key {
    width: 40px; height: 125px; background: #fff;
    border: 1px solid #000;
    color: #111; font-size: 18px; text-align: center; line-height: 200px; font-family: Arial;
    position: relative; z-index: 1;
}
.black-key {
    width: 20px; height: 80px; background: #000; color: #fff;
    border: 1px solid #333; position: absolute; z-index: 2;
    text-align: center; line-height: 100px; font-family: Arial; font-size: 14px;
    left: 0; top: 20px; pointer-events: none;
}
.highlight { background: #ff0 !important; color: #000 !important; }
.highlight-black { background: #ff0 !important; color: #000 !important; }
</style>
<div class="piano" style="width:440px"><div class="white-keys"><div class="white-key highlight">C</div><div class="white-key">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="white-key highlight">G</div><div class="white-key">A</div><div class="white-key highlight">B</div><div class="white-key highlight">C</div><div class="white-key">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="black-key" style="left:26px">C#</div><div class="black-key" style="left:66px">D#</div><div class="black-key" style="left:146px">F#</div><div class="black-key" style="left:186px">G#</div><div class="black-key" style="left:226px">A#</div><div class="black-key" style="left:306px">C#</div><div class="black-key" style="left:346px">D#</div><div class="black-key" style="left:426px">F#</div></div>
Piano()(Scale("major").get_notes("D"))
<style>
.piano { background: #222; padding: 20px 0; position: relative; width: 480px; }
.white-keys { display: flex; }
.white-key {
    width: 40px; height: 125px; background: #fff;
    border: 1px solid #000;
    color: #111; font-size: 18px; text-align: center; line-height: 200px; font-family: Arial;
    position: relative; z-index: 1;
}
.black-key {
    width: 20px; height: 80px; background: #000; color: #fff;
    border: 1px solid #333; position: absolute; z-index: 2;
    text-align: center; line-height: 100px; font-family: Arial; font-size: 14px;
    left: 0; top: 20px; pointer-events: none;
}
.highlight { background: #ff0 !important; color: #000 !important; }
.highlight-black { background: #ff0 !important; color: #000 !important; }
</style>
<div class="piano" style="width:440px"><div class="white-keys"><div class="white-key">C</div><div class="white-key highlight">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="white-key highlight">G</div><div class="white-key highlight">A</div><div class="white-key highlight">B</div><div class="white-key">C</div><div class="white-key highlight">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="black-key highlight-black" style="left:26px">C#</div><div class="black-key" style="left:66px">D#</div><div class="black-key highlight-black" style="left:146px">F#</div><div class="black-key" style="left:186px">G#</div><div class="black-key" style="left:226px">A#</div><div class="black-key highlight-black" style="left:306px">C#</div><div class="black-key" style="left:346px">D#</div><div class="black-key highlight-black" style="left:426px">F#</div></div>
Piano()(Scale("phrygian dominant").get_notes("D"))
<style>
.piano { background: #222; padding: 20px 0; position: relative; width: 480px; }
.white-keys { display: flex; }
.white-key {
    width: 40px; height: 125px; background: #fff;
    border: 1px solid #000;
    color: #111; font-size: 18px; text-align: center; line-height: 200px; font-family: Arial;
    position: relative; z-index: 1;
}
.black-key {
    width: 20px; height: 80px; background: #000; color: #fff;
    border: 1px solid #333; position: absolute; z-index: 2;
    text-align: center; line-height: 100px; font-family: Arial; font-size: 14px;
    left: 0; top: 20px; pointer-events: none;
}
.highlight { background: #ff0 !important; color: #000 !important; }
.highlight-black { background: #ff0 !important; color: #000 !important; }
</style>
<div class="piano" style="width:440px"><div class="white-keys"><div class="white-key highlight">C</div><div class="white-key highlight">D</div><div class="white-key">E</div><div class="white-key">F</div><div class="white-key highlight">G</div><div class="white-key highlight">A</div><div class="white-key">B</div><div class="white-key highlight">C</div><div class="white-key highlight">D</div><div class="white-key">E</div><div class="white-key">F</div><div class="black-key" style="left:26px">C#</div><div class="black-key highlight-black" style="left:66px">D#</div><div class="black-key highlight-black" style="left:146px">F#</div><div class="black-key" style="left:186px">G#</div><div class="black-key highlight-black" style="left:226px">A#</div><div class="black-key" style="left:306px">C#</div><div class="black-key highlight-black" style="left:346px">D#</div><div class="black-key highlight-black" style="left:426px">F#</div></div>
Piano()(PolyChord([Chord.from_short("E"), Chord.from_short("Am")]))
<style>
.piano { background: #222; padding: 20px 0; position: relative; width: 480px; }
.white-keys { display: flex; }
.white-key {
    width: 40px; height: 125px; background: #fff;
    border: 1px solid #000;
    color: #111; font-size: 18px; text-align: center; line-height: 200px; font-family: Arial;
    position: relative; z-index: 1;
}
.black-key {
    width: 20px; height: 80px; background: #000; color: #fff;
    border: 1px solid #333; position: absolute; z-index: 2;
    text-align: center; line-height: 100px; font-family: Arial; font-size: 14px;
    left: 0; top: 20px; pointer-events: none;
}
.highlight { background: #ff0 !important; color: #000 !important; }
.highlight-black { background: #ff0 !important; color: #000 !important; }
</style>
<div class="piano" style="width:440px"><div class="white-keys"><div class="white-key highlight">C</div><div class="white-key">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="white-key">G</div><div class="white-key highlight">A</div><div class="white-key highlight">B</div><div class="white-key highlight">C</div><div class="white-key">D</div><div class="white-key highlight">E</div><div class="white-key">F</div><div class="black-key" style="left:26px">C#</div><div class="black-key" style="left:66px">D#</div><div class="black-key" style="left:146px">F#</div><div class="black-key highlight-black" style="left:186px">G#</div><div class="black-key" style="left:226px">A#</div><div class="black-key" style="left:306px">C#</div><div class="black-key" style="left:346px">D#</div><div class="black-key" style="left:426px">F#</div></div>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

musy-0.0.4.tar.gz (21.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

musy-0.0.4-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file musy-0.0.4.tar.gz.

File metadata

  • Download URL: musy-0.0.4.tar.gz
  • Upload date:
  • Size: 21.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for musy-0.0.4.tar.gz
Algorithm Hash digest
SHA256 65c3d3e53b6f9ddf0bc9c436b1bf62342dca8665c1d1d69c9c98b5d5c428a119
MD5 af713c2c50c92be8dd92af19f61366e2
BLAKE2b-256 d9614f2671348db7d9d5a3e2e2d86fdedf10d3e52511b92a993d1d6a88a90ef7

See more details on using hashes here.

File details

Details for the file musy-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: musy-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.0

File hashes

Hashes for musy-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d6f63e8c12a67a53ce7a1595867729c760dbcf7443cfdf663e6670992ac495e9
MD5 0feee4fec0a08618c61f4a0b42eb98bb
BLAKE2b-256 432240842aa7563494ee2a67a44b538765e8c96871fc25aa705069c458609705

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page