Exemple #1
0
    def _get_interval_between_notes(cls, note1, note2):
        c_index = cls._SYSTEM_DIRECTORY["C"][1]
        self_index = cls._SYSTEM_DIRECTORY[note1.note_name.system][1]
        other_index = cls._SYSTEM_DIRECTORY[note2.note_name.system][1]

        l1 = (self_index - c_index) % 12
        l2 = (other_index - c_index) % 12

        d1 = Interval.get_interval_degree(l1)
        d2 = Interval.get_interval_degree(l2)

        degree = (d2 - d1) % 7
        interval_st = Interval.get_interval_semitones(degree)
        ll = interval_st

        alt_count = ((l2 - l1) +
                     (note2.alteration - note1.alteration) % 12) - ll
        if alt_count >= 6:
            alt_count -= 12
        if alt_count <= -6:
            alt_count += 12

        symbol = cls._INTERVAL._get_alteration_symbols(degree + 1, alt_count)

        return cls._INTERVAL(f"{degree + 1}{symbol}")
Exemple #2
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):
            try:
                base_note = Note(base_note)
            except Exception:
                base_note = TheoryNote(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]
Exemple #3
0
    def load(cls, mappings):
        for mapping in mappings:
            interval_names, *names = mapping
            names_instance = ChordNameContainer(names)

            intervals = []
            for interval_name in interval_names.split(","):
                intervals.append(Interval(interval_name))

            for name in names:
                cls._DIRECTORY[name] = (names_instance, intervals)

            cls._REVERSE_DIRECTORY[interval_names] = names_instance
Exemple #4
0
    def load(cls, mappings):
        for mapping in mappings:
            interval_names, mode_name, *names = mapping
            names_instance = ScaleNameContainer(names)

            intervals = [
                Interval(interval_name)
                for interval_name in interval_names.split(",")
            ]

            for name in names:
                cls._DIRECTORY[name] = (names_instance, mode_name, intervals)

            if mode_name:
                cls._MODES_DIRECTORY[mode_name].append(names[0])
Exemple #5
0
def test_interval_initialization_with_a_major_and_minor_perfect_intervals(
        interval_name, error_msg):
    with raises(ValueError, match=error_msg):
        Interval(interval_name)
Exemple #6
0
def test_interval_check_display(interval_name):
    assert str(Interval(
        interval_name)) == f"<Interval {interval_name.replace('M', '')}>"
Exemple #7
0
def test_interval_initialization_with_a_non_existing_interval_name(
        interval_name):
    with raises(ValueError, match="Interval name does not exists"):
        Interval(interval_name)
Exemple #8
0
def test_interval_with_multiple_alterations(interval_name):
    msg = "Interval alteration should be of a single type M, m, a or d"
    with raises(ValueError, match=msg):
        Interval(interval_name)
Exemple #9
0
def test_interval_with_wrong_interval_name(interval_name):
    with raises(ValueError, match="Interval name does not exists"):
        Interval(interval_name)
Exemple #10
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)
Exemple #11
0
def test_interval_instanciation_through_to_dict():
    interval = Interval("5")

    assert interval == Interval(**interval.to_dict())
Exemple #12
0
def test_note_instanciation_without_attributes():
    with raises(ValueError, match="Interval name must be set"):
        Interval()
Exemple #13
0
def test_interval_check_fullname_display(interval_name, interval_display):
    IntervalNameContainer.set(1)
    assert str(Interval(interval_name)) == f"<Interval {interval_display}>"
    IntervalNameContainer.set(0)
Exemple #14
0
    if inversion := parsed_config.get("inversion"):
        pass

    # GET BASE NOTE OR INVERSION
    base_note = None
    base_degree = None
    if base := parsed_config.get("base"):
        try:
            base_note = Note(base)
        except (ValueError, AttributeError):
            # base_degree_interval = harmony.get_base_degree_interval(raw_data)
            base_degree = base

    if extensions := parsed_config.get("extensions"):
        extensions = {Interval(e) for e in extensions}

    if not (chord := Harmony(current_scale).get(
            parsed_config.get("chord"),
            inversion=inversion,
            base_note=base_note,
            base_degree=base_degree,
            extensions=extensions,
            strict=state.prompt_config.get("strict")
    )):
        chord = Chord.get_from_fullname(
            parsed_config.get("chord"),
            inversion=inversion,
            base_note=base_note,
            extensions=extensions
        )
Exemple #15
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)
Exemple #16
0
def test_interval_is_hashable():
    {
        Interval("1"): "unisson",
        Interval("8"): "octave",
    }
Exemple #17
0
def test_interval_comparison():
    assert Interval("1") <= Interval("1")

    assert Interval("1") < Interval("3")
Exemple #18
0
def test_interval_with_minor_alteration_on_perfect_interval(interval_name):
    with raises(ValueError,
                match="Minor alteration on perfect interval is not possible"):
        Interval(interval_name)
Exemple #19
0
def test_interval_with_implicit_major(interval_name):
    assert Interval(interval_name) == Interval(interval_name + "M")
Exemple #20
0
def test_note_add_interval_alteration_normalization():
    assert Note("A") + Interval("1aaaaaaaaaaa") == Note("Ab")
    assert Note("A") + Interval("1ddddddddddd") == Note("A#")