# musy


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

`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`](https://CarloLepelaars.github.io/musy/note.html#note): The
basic atomic unit of music. -
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord) and
[`PolyChord`](https://CarloLepelaars.github.io/musy/chord.html#polychord):
A stack of notes played together. -
[`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale): Stack
of intervals from which harmony, (diatonic) chords, melody, etc. can be
derived.

For visualization these objects can be placed on instrument surfaces: -
[`Piano`](https://CarloLepelaars.github.io/musy/viz.html#piano): Basic
key layout -
[`Guitar`](https://CarloLepelaars.github.io/musy/viz.html#guitar):
Guitar fretboard

# Installation

``` sh
pip install musy
```

# Note

## Initialization

The [`Note`](https://CarloLepelaars.github.io/musy/note.html#note) is
the basic building block from which you can create chords, scales,
intervals and songs.

``` python
from musy import Note

c_sharp = Note("C#")
c_sharp
```

    C#4

You can get compact representations of
[`Note`](https://CarloLepelaars.github.io/musy/note.html#note) objects.
For example, their MIDI numbers and binary representations.

``` python
c_sharp.midi, bin(c_sharp), hex(c_sharp)
```

    (49, '0b110001', '0x31')

## Addition and subtraction

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

``` python
c_sharp + 1
```

    D4

``` python
c_sharp - 1
```

    C4

``` python
c_sharp + 14
```

    D#5

## Comparison

Notes can be compared using familiar Python operators.

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

c < g
```

    True

Octaves can make a difference in comparisons.

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

    True

## Relative Major/Minor

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

``` python
Note("C").minor()
```

    A4

``` python
Note("C#").major()
```

    E4

# Interval

## Initialization

[`Interval`](https://CarloLepelaars.github.io/musy/note.html#interval)
objects can be obtained by calling `interval` on two notes or using the
`&` operator.

``` python
f_sharp = Note("F#")

P4 = c_sharp & f_sharp
P4
```

    perfect fourth (4)

``` python
P4.semitones, P4.long, P4.short, P4.type(), P4.is_contextual(), P4.is_consonant()
```

    (5, 'perfect fourth', '4', 'Contextual', True, False)

## Comparison

Intervals can also be compared.

``` python
P5 = c & g
P5
```

    perfect fifth (5)

``` python
P5.semitones, P5.long, P5.short, P5.type(), P5.is_consonant(), P5.is_perfect()
```

    (7, 'perfect fifth', '5', 'Perfect Consonant', True, True)

``` python
P4 != P5
```

    True

``` python
P4 < P5
```

    True

# Chord

## Initialization

The [`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord) is
a stack of
[`Note`](https://CarloLepelaars.github.io/musy/note.html#note) objects
played together.

``` python
from musy import Chord

c_major = Chord(["C", "E", "G"])
c_major
```

    Chord: 'C major triad'. Notes: ['C4', 'E4', 'G4']

[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord)
objects can be initialized from shorthand notation.

``` python
cmaj7 = Chord.from_short("Cmaj7")
cmaj7
```

    Chord: 'C major seventh'. Notes: ['C4', 'E4', 'G4', 'B4']

## Inversion

Chords can also be inverted with `invert`.

``` python
# Get 1st inversion chord of C major 7th
cmaj7.invert(1)
```

    Chord: 'C major seventh, first inversion'. Notes: ['E4', 'G4', 'B4', 'C5']

## Transposition

Like [`Note`](https://CarloLepelaars.github.io/musy/note.html#note)
objects,
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord)
objects can be added and subtracted to transpose them.

``` python
cmaj7 + 2
```

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

Notes can be multiplied to create chords.

``` python
Note("C") * Note("E") * Note("G")
```

    Chord: 'C major triad'. Notes: ['C4', 'E4', 'G4']

## Table

Each chord can be displayed in a Pandas DataFrame table, which gives a
quick overview of the notes and intervals in the chord.

``` python
cmaj7.to_frame()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

|     | 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               |

</div>

This get more interesting when we want to analyze more complicated
chords and progressions. Take for example this chord:

``` python
Cdim6maj7 = Chord([Note("C"), Note("D#"), Note("F#"), Note("A"), Note("B")])
Cdim6maj7.to_frame()
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

|     | 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               |

</div>

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.

# PolyChord

## Initialization

For polyphonic use cases you can create
[`PolyChord`](https://CarloLepelaars.github.io/musy/chord.html#polychord)
objects. This objects inherits the same functionality as
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord)
objects.

``` python
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`](https://CarloLepelaars.github.io/musy/chord.html#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`](https://CarloLepelaars.github.io/musy/chord.html#polychord)
object.

``` python
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

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

|     | 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              |

</div>

    Chord 2: Bb major seventh, third inversion

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

|     | Notes | Relative Degree | Relative Interval | Absolute Interval | Absolute Degree |
|-----|-------|-----------------|-------------------|-------------------|-----------------|
| 0   | A     | 1               | unison            | unison            | 1               |
| 1   | Bb    | b2              | minor second      | minor second      | b2              |
| 2   | D     | 4               | perfect fourth    | major third       | 3               |
| 3   | F     | b6              | minor sixth       | minor third       | b3              |

</div>

# Scale

## Initialization

[`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale)
objects are collections of intervals from which we can generate notes
and chords around a root note.

``` python
from musy import Scale

dorian = Scale("dorian")
dorian
```

    Scale: Dorian. Intervals: ['1', '2', 'b3', '4', '5', '6', 'b7']

## Note Generation

When given a root note,
[`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale)
generates the notes of the scale.

``` python
dorian.get_notes("C")
```

    [C4, D4, D#4, F4, G4, A4, A#4]

## Mode Generation

All the modes of any
[`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale) can be
generated.

``` python
dorian.get_modes()
```

    [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']]

## Triad Generation

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

``` python
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']]

## Seventh Chord Generation

``` python
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`.

## Table

``` python
dorian.to_frame(root="E")
```

<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }
&#10;    .dataframe tbody tr th {
        vertical-align: top;
    }
&#10;    .dataframe thead th {
        text-align: right;
    }
</style>

|  | 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 |

</div>

## Custom Scales

Consult
[`Scale.available_scales`](https://CarloLepelaars.github.io/musy/scale.html#scale.available_scales)
for a list of available scales. If a scale is not available, you can
create your own scale from intervals.

``` python
persian = Scale.from_intervals(["1", "b2", "3", "4", "b5", "b6", "7"], "persian")
persian
```

    Scale: Persian. Intervals: ['1', 'b2', '3', '4', 'b5', 'b6', '7']

``` python
persian.get_notes("C")
```

    [C4, C#4, E4, F4, F#4, G#4, B4]

``` python
persian.get_triads("C")
```

    [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']]

## Listening

[`Note`](https://CarloLepelaars.github.io/musy/note.html#note),
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord),
[`PolyChord`](https://CarloLepelaars.github.io/musy/chord.html#polychord)
and [`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale)
objects can all be heard by calling the `play` method on them. Check out
the [musy documentation](https://carlolepelaars.github.io/musy) on
[`Note`](https://CarloLepelaars.github.io/musy/note.html#note),
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord),
[`PolyChord`](https://CarloLepelaars.github.io/musy/chord.html#polychord)
and [`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale)
for example code and audio playbacks.

# Visualization

`musy` objects can be visualized on a piano or guitar by providing a
list of [`Note`](https://CarloLepelaars.github.io/musy/note.html#note)
objects to the rendering method. Notes can easily be retrieved from
[`Chord`](https://CarloLepelaars.github.io/musy/chord.html#chord) and
[`Scale`](https://CarloLepelaars.github.io/musy/scale.html#scale)
objects.

## Piano

``` python
from musy import Piano

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>

``` python
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>

``` python
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>

``` python
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>

``` python
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>

## Guitar

``` python
from musy import Guitar
```

------------------------------------------------------------------------
