Exemple #1
0
    def get_chord(self,
                  start_degree,
                  degrees,
                  alteration=0,
                  inversion=None,
                  base_note=None,
                  extensions=None):
        degrees = degrees.split(",")
        notes = []

        for degree in degrees:
            note = self.notes[(start_degree + int(degree) - 1) % 7]
            for _ in range(abs(alteration)):
                if alteration < 0:
                    note += DIMINISHED
                elif alteration > 0:
                    note += AUGMENTED
            notes.append(note)

        first_note = notes[0]
        intervals = []
        for note in notes:
            intervals.append(first_note // note)

        chord_name = Chord.get_chord_name_from_intervals(intervals)

        return Chord(first_note,
                     chord_name.short,
                     inversion=inversion,
                     base_note=base_note,
                     extensions=extensions)
Exemple #2
0
def test_chord_notation_on_initialization(short, extended, symbol):
    root_note = "A4"

    notation1 = Chord(root_note, short)
    notation2 = Chord(root_note, extended)
    notation3 = Chord(root_note, symbol)

    assert notation1 == notation2
    assert notation2 == notation3

    assert str(notation1) == str(notation2)
Exemple #3
0
def adapt_chord_to_sequencer(chord, range):
    low_range, high_range = range

    chord_data = chord.to_dict()
    root_note = chord_data.pop("root_note")

    if isinstance(chord, TheoryChord):
        root_note = Note.cast_from_theory(root_note)

    if root_note < low_range:
        while root_note < low_range:
            root_note += OCTAVE

    chord = Chord(root_note=root_note, **chord_data)

    return [note for note in chord.notes if note <= high_range]
Exemple #4
0
def test_harmony_parse_degree_non_strictly(degree_name, expected_chord):
    harmony = Harmony(Scale("A4", "major"))

    assert harmony.get(degree_name,
                       strict=False) == Chord.get_from_fullname(expected_chord)
Exemple #5
0
from pytest import mark

from beethoven.sequencer.chord import Chord
from beethoven.sequencer.note import Note
from beethoven.sequencer.utils import adapt_chord_to_sequencer, get_all_notes
from beethoven.theory.scale import Scale


@mark.parametrize("chord,note_range,expected", [
    (Chord("C1", "maj"), "C3,C6", "C3,E3,G3"),
    (Chord("C2", "maj"), "C3,C6", "C3,E3,G3"),
    (Chord("C3", "maj"), "C4,C6", "C4,E4,G4"),
    (Chord("C4", "maj"), "C4,C6", "C4,E4,G4"),
    (Chord("C5", "maj"), "C4,C6", "C5,E5,G5"),
    (Chord("C6", "maj"), "C5,F6", "C6,E6"),
    (Chord("A4", "maj7"), "C4,C6", "A4,C#5,E5,G#5"),
    (Chord("A4", "maj7"), "C4,E5", "A4,C#5,E5"),
])
def test_adapt_chord_to_sequencer(chord, note_range, expected):
    assert (adapt_chord_to_sequencer(
        chord, Note.to_list(note_range)) == Note.to_list(expected))


@mark.parametrize("scale,note_range,expected", [
    (Scale("C3", "major"), "C3,C4", "C3,D3,E3,F3,G3,A3,B3,C4"),
    (Scale("C3", "major"), "E3,E4", "E3,F3,G3,A3,B3,C4,D4,E4"),
    (Scale("C3",
           "major"), "C3,C5", "C3,D3,E3,F3,G3,A3,B3,C4,D4,E4,F4,G4,A4,B4,C5"),
])
def test_get_all_notes(scale, note_range, expected):
    assert (get_all_notes(scale,
Exemple #6
0
def test_chord_instanciation_with_inversion_out_of_range(inversion):
    with raises(ValueError, match="Chord inversion out of range"):
        Chord("A4", "power", inversion=inversion)
Exemple #7
0
def test_chord_instanciation_with_inversion():
    normal = Chord("A4", "power", inversion=0)
    inverted = Chord("A4", "power", inversion=1)

    assert normal.notes == Note.to_list("A4,E5")
    assert inverted.notes == Note.to_list("E5,A5")
Exemple #8
0
def test_chord_instanciation_with_extensions(root_note, chord_name, extensions, expected_str, expected_notes):
    chord = Chord(root_note, chord_name, extensions=extensions)

    assert repr(chord) == f"<Chord {expected_str}>"

    assert chord.notes == expected_notes
Exemple #9
0
def test_chord_instanciation_without_attrubutes():
    with raises(ValueError, match="Chord name and root note must be set"):
        Chord()
Exemple #10
0
def test_chord_instanciation_with_base_note(root_note, chord_name, base_note, expected_str):
    chord = Chord(root_note, chord_name, base_note=base_note)

    assert chord.base_note == Note(base_note)
    assert repr(chord) == f"<Chord {expected_str}>"
Exemple #11
0
def test_chord_instanciation(root_note, chord_name, result_notes):
    chord = Chord(root_note, chord_name)

    assert chord.notes == Note.to_list(result_notes)
Exemple #12
0
def test_chord_get_from_fullname_classmethod_no_match(chord_name):
    assert Chord.get_from_fullname(chord_name) is None
Exemple #13
0
def test_chord_get_from_fullname_classmethod(chord_name):
    Chord.get_from_fullname(chord_name)
Exemple #14
0
def test_chord_with_wrong_chord_name(chord_name):
    with raises(ValueError, match="Chord name does not exists"):
        Chord("A4", chord_name)
Exemple #15
0
    ('ionian', 'major'),
    ('aeolian', 'minor'),
    ('melodic minor', 'ascending melodic minor'),
])
def test_scale_notation_on_initialization(name, alt_name):
    root_note = "A4"

    notation1 = Scale(root_note, name)
    notation2 = Scale(root_note, alt_name)

    assert notation1 == notation2
    assert str(notation1) == str(notation2)


@mark.parametrize("start_degree_name,chord_basic,chord_seventh", [
    (1, Chord("B4", "min"), Chord("B4", "min7")),
    (2, Chord("C#5", "min"), Chord("C#5", "min7")),
    (3, Chord("D5", "maj"), Chord("D5", "maj7")),
    (4, Chord("E5", "maj"), Chord("E5", "7")),
    (6, Chord("G#5", "dim"), Chord("G#5", "min7b5")),
])
def test_scale_get_chords(start_degree_name, chord_basic, chord_seventh):
    scale = Scale("A4", "major")

    assert scale.get_chord(start_degree_name, "1,3,5") == chord_basic
    assert scale.get_chord(start_degree_name, "1,3,5,7") == chord_seventh


@mark.parametrize("start_degree_name,alteration,chord_basic,chord_seventh", [
    (1, 0, Chord("B4", "min"), Chord("B4", "min7")),
    (1, 1, Chord("B#4", "min"), Chord("B#4", "min7")),