Beispiel #1
0
def perform_cell(input_string,
                 repeats,
                 max_duration,
                 parts,
                 instrument_name,
                 key,
                 check_range=False):
    total_duration = 0
    n = NanoNotation()
    note_pattern = Pseq(n.midinumbers(input_string), repeats)
    dur_pattern = Pseq(n.dur(input_string), repeats)
    for n, d in zip(note_pattern, dur_pattern):
        if total_duration < max_duration:
            prop = {}
            if random.randint(0, 10) > 7:
                accent = 1.0
                prop["articulations"] = "accent"
            else:
                accent = 0.6

            duration = dur_to_beat(d)
            if total_duration + duration > max_duration:
                duration = max_duration - total_duration  #  cut off the rhythm to remain inside measure

            if key:
                prop["key"] = key

            if check_range and not check_range(instrument_name, n):
                print(
                    f"Warning: instrument {instrument_name} goes out of range with note {n}"
                )

            if n == REST:
                scamp.wait(duration)
            else:
                parts[instrument_name].play_note(
                    n,
                    0.7 * accent,
                    duration,
                    properties=prop if prop else None)
            total_duration += duration

        else:
            return
 def __init__(self):
     self.note2midi = Note2Midi()
     self.nano = NanoNotation()
class PhraseFactory:
    def __init__(self):
        self.note2midi = Note2Midi()
        self.nano = NanoNotation()

    def __call__(self,
                 kind=None,
                 nanonotation=None,
                 volumes=None,
                 last_note_is_final=False):
        notes = self.nano.notes(nanonotation)
        durations = self.nano.dur(nanonotation)
        return Phrase({
            PP.NOTE: self.note(notes),
            PP.VOL: self.volume(notes, volumes, None, None),
            PP.PLAYEDDUR: self.playeddur(notes, kind),
            PP.DUR: self.dur(durations),
            PP.LAG: self.lag(notes, last_note_is_final)
        })

    @classmethod
    def playeddur(cls, notes, kind="l2s"):
        """
        :param notes: list of notes that make up the phrase
        :param kind: one of "l2s" (legato-to-staccato) or "s2l" (staccato-to-legato)
        :return: pattern that generates the desired playeddur values
        """
        if kind == "l2s":
            anim = Pseq([
                Pconst(PDur.legato,
                       len(notes) - 1),
                Pconst(PDur.staccato, 1)
            ], 1)
        elif kind == "s2l":
            anim = Pseq([
                Pconst(PDur.staccato,
                       len(notes) - 1),
                Pconst(PDur.legato, 1)
            ], 1)
        elif kind == "s2s":
            anim = Pconst(PDur.staccato, len(notes))
        elif kind == "l2l":
            anim = Pconst(PDur.legato, len(notes))
        else:
            anim = None
            assert False
        return anim

    @classmethod
    def volume(cls,
               notes,
               volumes=None,
               individual_tween=None,
               overall_tween=None):
        """
        :param notes: list of notes that make up the phrase
        :param volumes: a list of volumes to evolve to over the course of the phrase, e.g. [Dyn.mp, Dyn.mf, Dyn.ppp]
        :param individual_tween: per segment tween
        :param overall_tween: tween over all segments
        :return: pattern that tweens between the successive volumes
        """
        if volumes is None:
            volumes = [Dyn.mf, Dyn.mf]
        if overall_tween is None:
            overall_tween = ['linear']
        if individual_tween is None:
            individual_tween = ['linear']
        if len(volumes) == 1:
            volumes = [volumes[0], volumes[0]]
        anims = []
        for v in pairwise(volumes):
            anims.append(
                NumberAnimation(frm=v[0], to=v[1], tween=individual_tween))
        s = SequentialAnimation(anims, tween=overall_tween)
        return Ptween(s, 0, 0, len(notes), len(notes))

    def note(self, notes):
        """
        :param notes: list of notes that make up the phrase
        :return: pattern that generates the notes one by one
        """
        return Pseq(self.note2midi.convert2(notes))

    @classmethod
    def lag(cls, notes, last_note_is_endnote=False):
        """
        :param last_note_is_endnote:
        :param notes: list of notes that make up the phrase
        :return: pattern that generates the desired lag
        """
        if last_note_is_endnote:
            return Pseq([Pconst(0, len(notes) - 1), Pconst(0.5, 1)], repeats=1)
        else:
            return Pconst(0, len(notes))

    @classmethod
    def dur(cls, durations):
        return Pseq(durations, repeats=1)
Beispiel #4
0
 def test_notes(self):
     nn = NanoNotation()
     the_notes = nn.notes("r_8 c4 e4_16 f4_8.")
     self.assertEqual(the_notes, "r c4 e4 f4".split(" "))
Beispiel #5
0
 def test_octaves(self):
     nn = NanoNotation()
     the_notes = nn.notes("r_8 c3 e g4 a_2 e")
     self.assertEqual(the_notes, "r c3 e3 g4 a4 e4".split(" "))
Beispiel #6
0
 def test_durs(self):
     nn = NanoNotation()
     the_durs = nn.dur("r_8 c4 e4_16 f4_8.")
     self.assertEqual(the_durs, [1 / 8, 1 / 8, 1 / 16, 1 / 8 + 1 / 16])
Beispiel #7
0
def perform_cell_spicy(input_string,
                       repeats,
                       max_duration,
                       parts,
                       instrument_name,
                       key,
                       check_range=False):
    total_duration = 0
    n = NanoNotation()
    note_pattern = Pseq(n.midinumbers(input_string), repeats)
    dur_pattern = Pseq(n.dur(input_string), repeats)
    if len(n.midinumbers(input_string)) == 1 and repeats <= 1:
        perform_cell(input_string, repeats, max_duration, parts,
                     instrument_name, key, check_range)
    else:
        last_encountered_nd2 = None
        for nd1, nd2 in pairwise(zip(note_pattern, dur_pattern)):
            last_encountered_nd2 = nd2
            if total_duration < max_duration:
                prop = {}
                if random.randint(0, 10) > 7:
                    accent = 1.0
                    prop["articulations"] = "accent"
                else:
                    accent = 0.6

                n1 = nd1[0]
                n2 = nd2[0]
                d = nd1[1]
                duration = dur_to_beat(d)

                if total_duration + duration > max_duration:
                    duration = max_duration - total_duration  #  cut off the rhythm to remain inside measure

                if key:
                    prop["key"] = key

                if check_range and not check_range(instrument_name, n):
                    print(
                        f"Warning: instrument {instrument_name} goes out of range with note {n}"
                    )

                all_notes, all_durs = transform_note_duration(duration, n1, n2)

                for n, d in zip(all_notes, all_durs):
                    if n == REST:
                        scamp.wait(d)
                    else:
                        parts[instrument_name].play_note(
                            n,
                            0.7 * accent,
                            d,
                            properties=prop if prop else None)
                    total_duration += d
            else:
                return

        if last_encountered_nd2 is not None:
            n = last_encountered_nd2[0]
            d = last_encountered_nd2[1]
            if n == REST:
                scamp.wait(d)
            else:
                parts[instrument_name].play_note(
                    n,
                    0.7 * accent,
                    duration,
                    properties=prop if prop else None)
            total_duration += d