Exemplo n.º 1
0
class FakePlayer1(BasePlayer):
    NOTE_DURATION = Whole
    NOTE_RANGE = [Note("C3"), Note("C5")]

    def play_measure(self, **kwargs):
        for self.part in self.time_signature.gen(self.NOTE_DURATION):
            yield self.play(*self.chord_voicer.get()[0:2],
                            duration=Whole,
                            velocity=127)
Exemplo n.º 2
0
class FakePlayer2(BasePlayer):
    NOTE_DURATION = Half
    NOTE_RANGE = [Note("D3"), Note("C5")]

    def play_measure(self, **kwargs):
        for self.part in self.time_signature.gen(self.NOTE_DURATION):
            yield self.play(self.arpeggiator.get()[0],
                            duration=Half,
                            velocity=63)
Exemplo n.º 3
0
class Piano(BasePlayer):
    NOTE_DURATION = Sixteenths
    NOTE_RANGE = [Note("C2"), Note("C5")]
    NORMALIZE_TS = True

    def play_measure(self, **kwargs):
        for self.part in self.time_signature.gen(self.NOTE_DURATION,
                                                 self.duration):
            if self.check(bar=1, measure=1, submeasure=1):
                yield self.play(*self.chord_voicer.get(),
                                duration=Whole,
                                velocity=76)
Exemplo n.º 4
0
def test_base_player_capabilities():
    player = FakePlayer()

    assert repr(player) == "<Player FakePlayer>"

    player.part = TimeContainer(1, 1, 1)
    assert player.play("F4", "F5", velocity=63) == {
        "part": TimeContainer(1, 1, 1),
        "notes": [Note("F4"), Note("F5")],
        "duration": Whole,
        "velocity": 63
    }
Exemplo n.º 5
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]
Exemplo n.º 6
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")
Exemplo n.º 7
0
class Chord(BaseChord, metaclass=SequencerChordSingletonMeta):
    def __init__(self, root, name, inversion, base_note, extensions):
        self._load_attributes(root, name, inversion, base_note, extensions)

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

        self.root = root_note
        self.inversion = inversion or 0
        self.base_note = None

        if base_note and base_note != root_note:
            self.base_note = Note.cast_from_theory(
                base_note,
                octave=(self.root.octave if
                        (base_note < self.root
                         or self.root.octave == 0) else self.root.octave - 1))

        self.name, intervals = data
        self.intervals = copy(intervals)

        if inversion and (inversion < 0 or inversion >= len(self.intervals)):
            raise ValueError("Chord inversion out of range")

        notes = []
        if self.base_note:
            notes.append(self.base_note)

        base_chord_notes = [self.root] + [
            self.root + interval for interval in self.intervals[1:]
        ]
        notes += base_chord_notes[
            self.inversion:] + base_chord_notes[:self.inversion]

        self.notes = [notes[0]]
        last_note = notes[0]
        for note in notes[1:]:
            # AU CAS OU IL Y AURAIT DES INTERVALES ETENDUS
            while note < last_note:
                note += OCTAVE
            self.notes.append(note)
            last_note = note

        self.extensions = []
        for extension in sorted(extensions):
            if extension in self.intervals:
                continue

            self.notes.append(self.root + extension)
            self.intervals.append(extension)
            self.extensions.append(extension)

        self.notes = list(sorted(self.notes))
        self.intervals = list(sorted(self.intervals))
Exemplo n.º 8
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")
Exemplo n.º 9
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)
Exemplo n.º 10
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]
Exemplo n.º 11
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}>"
Exemplo n.º 12
0
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))
Exemplo n.º 13
0
def test_get_all_notes(scale, note_range, expected):
    assert (get_all_notes(scale,
                          Note.to_list(note_range)) == Note.to_list(expected))
Exemplo n.º 14
0
def test_note_add_interval_with_non_interval_string():
    with raises(ValueError, match="Interval name does not exists"):
        Note("A4").add_interval("test")
Exemplo n.º 15
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")
Exemplo n.º 16
0
def test_interval_check_display(start_note, interval_name, expected_note):
    assert Note(start_note) + Interval(interval_name) == Note(expected_note)
Exemplo n.º 17
0
def test_note_with_empty_note_name():
    with raises(ValueError, match="Note could not be parsed"):
        Note("")
Exemplo n.º 18
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)
Exemplo n.º 19
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)
Exemplo n.º 20
0
def test_note_add_interval_alteration_normalization():
    assert Note("A4") + Interval("1aaaaaaaaaaa") == Note("Ab4")
    assert Note("A4") + Interval("1ddddddddddd") == Note("A#4")
Exemplo n.º 21
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)
Exemplo n.º 22
0
def test_note_with_wrong_note_name(note_name):
    with raises(ValueError, match="Note could not be parsed"):
        Note(note_name)
Exemplo n.º 23
0
def test_note_semitones_property(note_name, expected_semitones):
    assert Note(note_name).semitones == expected_semitones
Exemplo n.º 24
0
def test_note_instanciation_without_attributes():
    with raises(ValueError, match="Note name must be set"):
        Note()
Exemplo n.º 25
0
def test_note_instanciation(note_name):
    assert Note(note_name)
Exemplo n.º 26
0
def test_note_add_interval_with_non_interval_instance():
    assert Note("A3").add_interval("3") == Note("C#4")
    assert Note("G3").add_interval("5", reverse=True) == Note("C3")
Exemplo n.º 27
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)
Exemplo n.º 28
0
def test_note_comparison():
    assert Note("A4") == Note("A4")

    assert Note("A2") < Note("B2")

    assert Note("B3") > Note("C2")
Exemplo n.º 29
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
Exemplo n.º 30
0
def test_note_casting_to_theory_self():
    return BaseNote("B") == Note("B4").get_theory_self()