Пример #1
0
    def _load_attributes(self, tonic, scale_name):
        if not isinstance(tonic, Note):
            tonic = Note(tonic)

        self.tonic = tonic

        if not (data := self._DIRECTORY.get(scale_name)):
            raise ValueError("Scale name does not exists")
Пример #2
0
def test_note_check_display_note_name_change(anglosaxon, solfege):
    note = Note(anglosaxon)

    assert str(note) == f"<Note {anglosaxon}>"
    NoteNameContainer.set(1)

    assert str(note) == f"<Note {solfege}>"
    NoteNameContainer.set(0)
Пример #3
0
    def __call__(cls, root_note=None, chord_name=None, inversion=None, base_note=None, extensions=None):
        if root_note is None and chord_name is None:
            raise ValueError("Chord name and root note must be set")

        elif base_note and isinstance(base_note, str):
            base_note = Note(base_note)

        extensions = frozenset([
            extension if isinstance(extension, Interval) else Interval(extension)
            for extension in extensions or []
        ])

        args = frozenset([root_note, chord_name, inversion, base_note, extensions])
        if args not in cls._INSTANCES:
            instance = super().__call__(root_note, chord_name, inversion, base_note, extensions)
            cls._INSTANCES[args] = instance

        return cls._INSTANCES[args]
Пример #4
0
from pytest import mark

from beethoven.common.tuning import Tuning
from beethoven.theory.note import Note


@mark.parametrize("tuning_args,expected_repr", [
    ((Note("A"), ), "<Tuning 1 strings>"),
    (Note.to_list("A,B,C"), "<Tuning 3 strings>"),
    (Note.to_list("E,A,D,G,B,E"), "<Tuning 6 strings>"),
])
def test_tuning_instanciation(tuning_args, expected_repr):
    tuning = Tuning(*tuning_args)

    assert repr(tuning) == expected_repr
Пример #5
0
def test_chord_instanciation_with_inversion():
    normal = Chord("A", "power", inversion=0)
    inverted = Chord("A", "power", inversion=1)

    assert normal.notes == Note.to_list("A,E")
    assert inverted.notes == Note.to_list("E,A")
Пример #6
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)
Пример #7
0
def test_note_add_interval_with_non_interval_string():
    with raises(ValueError, match="Interval name does not exists"):
        Note("A").add_interval("test")
Пример #8
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}>"
Пример #9
0
from beethoven.theory.note import Note


class Tuning:
    def __init__(self, *strings):
        self.strings = list(strings)

    def __str__(self):
        return f"<Tuning {len(self.strings)} strings>"

    def __repr__(self):
        return str(self)

    @classmethod
    def from_notes_str(cls, string):
        return cls(*Note.to_list(string))


E_STANDARD = Tuning(*Note.to_list("E,A,D,G,B,E"))
E_STANDARD_BASS = Tuning(*Note.to_list("E,A,D,G"))
B_STANDARD_7 = Tuning(*Note.to_list("B,E,A,D,G,B,E"))
Пример #10
0
def test_note_instanciation_through_to_dict():
    note = Note("A")

    assert note == Note(**note.to_dict())
Пример #11
0
def test_note_semitones_property(note_name, expected_semitones):
    assert Note(note_name).semitones == expected_semitones
Пример #12
0
def test_note_comparison():
    assert Note("A") == Note("A")

    assert Note("A") < Note("B")

    assert Note("B") > Note("C")
Пример #13
0
def test_note_is_the_same_between_notation_systems_with_sharps(
        anglosaxon, solfege):
    note_a, note_s = Note(anglosaxon), Note(solfege)

    assert note_a == note_s
    assert note_a is not None
Пример #14
0
def test_note_with_sharps_and_flats_raise_exception(note_name):
    with raises(ValueError,
                match="Note name shouldn't contain sharps AND flats"):
        Note(note_name)
Пример #15
0
def test_note_with_wrong_note_name(note_name):
    with raises(ValueError, match="Note name does not exists"):
        Note(note_name)
Пример #16
0
def test_note_with_empty_note_name():
    with raises(ValueError, match="Note name does not exists"):
        Note("")
Пример #17
0
def test_note_instanciation_without_attributes():
    with raises(ValueError, match="Note name must be set"):
        Note()
Пример #18
0
from pytest import mark

from beethoven.common.tuning import (B_STANDARD_7, E_STANDARD, E_STANDARD_BASS,
                                     Tuning)
from beethoven.display.fretboard import Fretboard
from beethoven.theory.chord import Chord
from beethoven.theory.note import Note
from beethoven.theory.scale import Scale


@mark.parametrize(
    "tuning,fretboard_kwargs,call_kwargs,expected_ascii",
    [
        # Test without any scale/chord
        (Tuning(Note("A")), {}, {},
         ("     ║     |     |     |     |     |     |     |     |     |     |     |     |\n"
          "\n"
          "  0  ║     |     |  3  |     |  5  |     |  7  |     |  9  |     |     | 12  |"
          )),
        # Test with a scale
        (Tuning(Note("A")), {}, {
            "scale": Scale("A", "major")
        },
         ("  A  ║     |  B  |     | C#  |  D  |     |  E  |     | F#  |     | G#  |  A  |\n"
          "\n"
          "  0  ║     |     |  3  |     |  5  |     |  7  |     |  9  |     |     | 12  |"
          )),
        # Test with a chord
        (Tuning(Note("A")), {}, {
            "chord": Chord("A", "maj7")
        },
Пример #19
0
def validate_note_or_degree(string, loc, expr):
    try:
        Note(expr[0])
    except Exception:
        Harmony(Scale("A", "major")).get(expr[0])
Пример #20
0
def process_config(parsed_config, current_scale=None):
    parsed = {}
    scale_updated = False

    scale_name = None
    tonic_note = None
    if current_scale:
        scale_name = str(current_scale.name)
        tonic_note = current_scale.tonic

    if scale_name_value := parsed_config.get("scale"):
        scale_name = scale_name_value
        scale_updated = True

    if tonic_name := parsed_config.get("note"):
        tonic_note = Note(tonic_name)
        scale_updated = True

    if scale_updated and scale_name and tonic_note:
        parsed["scale"] = Scale(tonic_note, scale_name)
    elif not current_scale:
        return parsed

    if progression := parsed_config.get("progression"):
        parsed["progression"] = progression

    if time_signature := parsed_config.get("time_signature"):
        parsed["time_signature"] = TimeSignature(*time_signature)

    if tempo := parsed_config.get("tempo"):
        parsed["tempo"] = Tempo(tempo)
Пример #21
0
    def _load_attributes(self, root_note, chord_name, inversion, base_note, extensions):
        if not isinstance(root_note, Note):
            root_note = Note(root_note)

        if not (data := self._DIRECTORY.get(chord_name)):
            raise ValueError("Chord name does not exists")
Пример #22
0
 def from_notes_str(cls, string):
     return cls(*Note.to_list(string))
Пример #23
0
def test_note_add_interval_alteration_normalization():
    assert Note("A") + Interval("1aaaaaaaaaaa") == Note("Ab")
    assert Note("A") + Interval("1ddddddddddd") == Note("A#")
Пример #24
0
def validate_note(string, loc, expr):
    Note(expr[0])
Пример #25
0
def test_note_add_interval_method(note_name, interval_name, result_note_name):
    assert Note(note_name) + Interval(interval_name) == Note(result_note_name)
Пример #26
0
def test_scale(root_note, scale_name, result_notes):
    scale = Scale(root_note, scale_name)

    assert scale.notes == Note.to_list(result_notes)
Пример #27
0
def test_note_substract_interval_method(note_name, interval_name,
                                        result_note_name):
    assert Note(note_name) - Interval(interval_name) == Note(result_note_name)
Пример #28
0
    assert chord.base_note == Note(base_note)
    assert repr(chord) == f"<Chord {expected_str}>"


def test_chord_instanciation_with_inversion():
    normal = Chord("A", "power", inversion=0)
    inverted = Chord("A", "power", inversion=1)

    assert normal.notes == Note.to_list("A,E")
    assert inverted.notes == Note.to_list("E,A")


@mark.parametrize(
    "root_note,chord_name,extensions,expected_str,expected_notes",
    [("A", "power", ("5", ), "Apower", Note.to_list("A,E")),
     ("A", "power", ("4", ), "Apower add4", Note.to_list("A,E,D")),
     ("B", "min", ("9a", ), "Bmin add9a", Note.to_list("B,D,F#,C##")),
     ("D", "maj7",
      ("11", "13d"), "Dmaj7 add11add13d", Note.to_list("D,F#,A,C#,G,Bbb")),
     ("F", "min maj7",
      ("14dd", ), "Fmin maj7 add14dd", Note.to_list("F,Ab,C,E,Ebbb"))])
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

Пример #29
0
def test_note_add_interval_with_non_interval_instance():
    assert Note("A").add_interval("3") == Note("C#")
    assert Note("G").add_interval("5", reverse=True) == Note("C")