Пример #1
0
    def special_action_1(self):
        """
        Long accented single note on A or B with trailing dim hairpin
        :return: str - image path
        """
        self.refresh_lily()
        # Find pitch
        pitch_set = [-1, 0, 2]
        weighted_pitch_set = []
        i = 0
        while i < len(pitch_set):
            weighted_pitch_set.append((pitch_set[i], 10/(i+1)))
            i += 1
        use_pitch = rand.weighted_rand(weighted_pitch_set, 'discreet')
        # Find length
        use_length = rand.weighted_rand([(5, 2), (13, 8), (25, 1)], do_round=True)
        # Find dynamic
        use_dynamic = rand.weighted_rand([(9, 1), (8, 7), (4, 5), (0, 1)], do_round=True)
        self.note_array.create_note(use_pitch, use_length, dynamic=use_dynamic)
        self.note_array.list[-1].add_articulation(1)
        if self.sustained_playing:
            self.note_array.create_spanner(0, spanner_type='dim', apply_type='start')

        if len(self.clef_list) > 1:
            self.note_array.auto_build_clefs(self.clef_list, self.initial_clef,
                                             self.clef_change_tolerance, self.preferred_clef_extra_weight)
        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name, view_image=False, autocrop=True, delete_ly=False)
        config.FileNameIndex += 1
        return output_png
def draw_big_fermata_without_timecode(size):
    """
    Uses lilypond to draw a big fermata of input size, returns new image path
    :param size: number
    :return: str path to newly built png image
    """
    # Note that this file path only works if both the lilypond file and the eps file are located in the same
    #   directories relative to each other! This could cause a big confusion in refactoring, but as far as I can tell,
    #   lilypond doesn't accept absolute paths in epsfile syntax
    vector_file_path = '../../Graphics/big_fermata_vector.eps'
    fermata_size = size
    score = lilypond_file.LilypondFile()
    score.master_string = ("""\\version "2.18.2"\n
                            \\header { tagline = #" " }
                            \\markup {\n
                            \\center-column {\n
                            \\line {\n
                            \\epsfile #X #""" + str(fermata_size) + ' #"' +
                           vector_file_path + '"\n' + '}}}')
    score._string_built = True
    output_file_name = "fermata_" + str(config.FileNameIndex)
    output_png = score.save_and_render(output_file_name,
                                       view_image=False,
                                       autocrop=True,
                                       delete_ly=False)
    config.FileNameIndex += 1
    return output_png
def draw_big_fermata(length_weights, size_factor=1):
    """
    Builds and renders a lilypond file of a large fermata with an approximate timecode.
    The fermata is scaled according to the timecode. Returns the image path.
    :param length_weights: list of tuples for how many seconds the fermata should last
    :param size_factor: int multiplier for the scale of the fermata
    :return: str of new image path
    """
    assert isinstance(length_weights, list)
    # Note that this file path only works if both the lilypond file and the eps file are located in the same
    #   directories relative to each other! This could cause a big confusion in refactoring, but as far as I can tell,
    #   lilypond doesn't accept absolute paths in epsfile syntax
    vector_file_path = '../../Graphics/big_fermata_vector.eps'

    # Convert an input seconds value into a string representation timecode for use in the fermata
    def seconds_to_timecode(seconds):
        minutes, out_seconds = divmod(seconds, 60)
        if minutes == 0:
            minute_string = ''
        else:
            minute_string = str(minutes) + "\"\\char ##x2019\" "
        second_string = str(out_seconds)
        if len(second_string) == 1:
            second_string = "0" + second_string
        second_string += '\"\\char ##x201D'
        return minute_string + second_string

    length = rand.weighted_rand(length_weights, do_round=True)
    fermata_size = length * 0.222 * size_factor
    # Round length to the nearest 10 seconds
    length = int(round(length, -1))
    length_string = seconds_to_timecode(length)
    score = lilypond_file.LilypondFile()
    score.master_string = (
        """\\version "2.18.2"\n
                            \\header { tagline = #" " }
                            \\markup {\n
                            \\center-column {\n
                            \\line {\n
                            \\epsfile #X #""" + str(fermata_size) + ' #"' +
        vector_file_path + '"\n' +
        "}\n\\line {\\abs-fontsize #11\n\\bold {\\italic{ \\concat {" +
        "\n\\override #' (font-name . \"Book Antiqua Bold\")\n" +
        "\\char ##x2248\n\\override #' (font-name . \"CrimsonText bold italic\")\n \""
        + length_string + ' }}}}}}')
    score._string_built = True

    output_file_name = "fermata_" + str(config.FileNameIndex)
    output_png = score.save_and_render(output_file_name,
                                       view_image=False,
                                       autocrop=True,
                                       delete_ly=False)
    config.FileNameIndex += 1
    return output_png
def draw_boxed_text(text_string, line_width=45):
    """
    Creates and renders a lilypond file containing a boxed text markup with the text of text_string
    :param text_string: str
    :param line_width: int
    :return: str of png path
    """
    score = lilypond_file.LilypondFile()
    score.master_string = (
        "\\version \"2.18.2\"\n" + "\\header { tagline = #\" \" }\n" +
        "\\markup {\n\n" +
        "\\override #' (font-name . \"CrimsonText bold italic\")\n" +
        "\\abs-fontsize #11 \\box{ \\bold{ \\italic{ \\pad-around #1 {\n" +
        "\\override #'(line-width . " + str(line_width) + ")\n" +
        "\\wordwrap-string #\"" + text_string + "\" }}}}}")
    score._string_built = True

    output_file_name = "text_string_" + str(config.FileNameIndex)
    output_png = score.save_and_render(output_file_name,
                                       view_image=False,
                                       autocrop=True,
                                       delete_ly=False)
    config.FileNameIndex += 1
    return output_png
Пример #5
0
    def play(self):

        self.refresh_lily()

        # Roll for special actions
        special_action_roll = rand.weighted_rand(self.special_action_weights,
                                                 'discreet')
        if special_action_roll != 0:
            if special_action_roll == 1:
                self.previous_action = 'Special Action 1'
                return self.special_action_1()
            elif special_action_roll == 2:
                self.previous_action = 'Special Action 2'
                return self.special_action_2()
            elif special_action_roll == 3 and self.previous_action != 'Special Action 3':
                self.previous_action = 'Special Action 3'
                return self.special_action_3()
        else:
            self.previous_action = 'Normal Play'

        note_count = rand.weighted_rand(self.note_count_weights, do_round=True)
        current_node = self.pitch_network.pick()
        while (not isinstance(current_node, nodes.NoteBehavior)) or (
                current_node.name[:4] == 'rest'):
            current_node = self.pitch_network.pick()
        # Get first pitch
        current_pitch = self._find_first_pitch(current_node.pitch_set,
                                               self.starting_pitch_weights)

        current_time_in_upper_tessitura = 0

        for i in range(0, note_count):
            current_dur = self.length_network.pick().get_value()
            while isinstance(current_node, nodes.Action):
                current_node = self.pitch_network.pick()
            if current_node.name[:4] == 'rest':
                self.note_array.create_note(current_pitch,
                                            current_dur,
                                            is_rest=True)
                current_time_in_upper_tessitura = 0
            else:
                current_pitch = current_node.move_pitch(current_pitch)
                self.note_array.create_note(current_pitch, current_dur)
                current_time_in_upper_tessitura += current_dur

                # If it's the first note, do first-note rolls
                if i == 0:
                    # Roll for mute changes
                    if (random.uniform(0, 1) < self.mute_change_frequency) or (
                            self.current_mute is None):
                        new_mute = self.current_mute
                        while new_mute == self.current_mute:
                            new_mute = random.choice(self.mute_list)
                        self.current_mute = new_mute
                        reverse_mute_dict = {
                            'senza sord': 203,
                            'straight mute': 204,
                            'practice mute': 205
                        }
                        self.note_array.list[-1].add_articulation(
                            reverse_mute_dict[self.current_mute], 'over')

            current_node = self.pitch_network.pick()
            # If the current time in the upper range exceeds the limit, change current_node to a downward pointing one
            if current_time_in_upper_tessitura > self.max_time_at_high:
                if random.randint(0, 1) == 0:
                    current_node = self.pitch_network.node_list[5]
                else:
                    current_node = self.pitch_network.node_list[7]
                current_time_in_upper_tessitura = 0

            if random.uniform(0, 1) < self.mode_change_frequency:
                self.change_mode()

        self.auto_add_dynamics()
        if len(self.clef_list) > 1:
            self.note_array.auto_build_clefs(self.clef_list, self.initial_clef,
                                             self.clef_change_tolerance,
                                             self.preferred_clef_extra_weight)
        self.auto_add_slurs()

        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(
            config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name,
                                                    view_image=False,
                                                    autocrop=True,
                                                    delete_ly=False)
        config.FileNameIndex += 1
        return output_png
Пример #6
0
    def play(self):

        self.refresh_lily()

        # Roll for special actions
        special_action_roll = rand.weighted_rand(self.special_action_weights, 'discreet')
        if special_action_roll != 0:
            if special_action_roll == 1:
                self.previous_action = 'Special Action 1'
                return self.special_action_1()
            elif special_action_roll == 2:
                self.previous_action = 'Special Action 2'
                return self.special_action_2()
            elif special_action_roll == 3 and self.previous_action != 'Special Action 3':
                self.previous_action = 'Special Action 3'
                return self.special_action_3()
        else:
            self.previous_action = 'Normal Play'

        note_count = rand.weighted_rand(self.note_count_weights, do_round=True)
        current_node = self.pitch_network.pick()
        while (not isinstance(current_node, nodes.NoteBehavior)) or (current_node.name == 'rest'):
            current_node = self.pitch_network.pick(current_node)

        # Pick first note randomly
        current_pitch = self._find_first_pitch(current_node.pitch_set, self.starting_pitch_weights)

        for i in range(0, note_count):
            current_dur = self.length_network.pick().get_value()

            while isinstance(current_node, nodes.Action):
                current_node = self.pitch_network.pick()
            if current_node.name == 'rest':
                if current_dur < self.minimum_rest_length:
                    current_dur = self.minimum_rest_length
                self.note_array.create_note(current_pitch, current_dur, is_rest=True)
            else:
                current_pitch = current_node.move_pitch(current_pitch)

                # Special handling for spacing of square noteheads, make a little wider
                if current_pitch in [4, 5, 7]:
                    current_dur += 1

                self.note_array.create_note(current_pitch, current_dur)
                if current_pitch == -3:
                    self.note_array.list[-1].notehead_style_code = 1
                elif current_pitch in [-5, -7]:
                    self.note_array.list[-1].notehead_style_code = 3
                elif current_pitch in [4, 5, 7]:
                    self.note_array.list[-1].notehead_style_code = 4

                # If it's the first note, do first-note rolls
                if i == 0:
                    # Roll for beater changes
                    if (random.uniform(0, 1) < self.beater_change_frequency) or self.current_beater is None:
                        new_beater = self.current_beater
                        while new_beater == self.current_beater:
                            new_beater = random.choice(self.beater_list)
                        self.current_beater = new_beater
                        reverse_mute_dict = {'hard yarn': 230, 'soft yarn': 231, 'soft rubber': 232}
                        self.note_array.list[-1].add_articulation(reverse_mute_dict[self.current_beater], 'over')

            current_node = self.pitch_network.pick(current_node)

            if random.uniform(0, 1) < self.mode_change_frequency:
                self.perc_change_mode()

        self.auto_add_dynamics()
        self.auto_add_slurs()

        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name, view_image=False, autocrop=True, delete_ly=False)
        config.FileNameIndex += 1
        return output_png
Пример #7
0
    def play(self):

        self.refresh_lily()

        # Roll for special actions
        special_action_roll = rand.weighted_rand(self.special_action_weights,
                                                 'discreet')
        if special_action_roll != 0:
            if special_action_roll == 1:
                self.previous_action = 'Special Action 1'
                return self.special_action_1()
            elif special_action_roll == 2:
                self.previous_action = 'Special Action 2'
                return self.special_action_2()
            elif special_action_roll == 3 and self.previous_action != 'Special Action 3':
                self.previous_action = 'Special Action 3'
                return self.special_action_3()
        else:
            self.previous_action = 'Normal Play'

        note_count = rand.weighted_rand(self.note_count_weights, do_round=True)
        current_node = self.pitch_network.pick()
        while (not isinstance(current_node, nodes.NoteBehavior)) or (
                current_node.name[:4] == 'rest'):
            current_node = self.pitch_network.pick()
        # Get first pitch
        current_pitch = self._find_first_pitch(current_node.pitch_set,
                                               self.starting_pitch_weights)

        for i in range(0, note_count):
            current_dur = self.length_network.pick().get_value()

            # pick through action (sub-network link) nodes
            while isinstance(current_node, nodes.Action):
                current_node = self.pitch_network.pick()
            if current_node.name[:4] == 'rest':
                self.note_array.create_note(current_pitch,
                                            current_dur,
                                            is_rest=True)
            else:
                current_pitch = current_node.move_pitch(current_pitch)
                self.note_array.create_note(current_pitch, current_dur)

                # With self.natural_harmonic_frequency, if current_pitch can be a natural harmonic, add it.
                if random.uniform(0, 1) < self.natural_harmonic_frequency:
                    harmonic_string_test = self.natural_harmonic_string(
                        current_pitch)
                    if harmonic_string_test is not None:
                        string_code_dict = {
                            'I': 220,
                            'II': 221,
                            'III': 222,
                            'IV': 223,
                            'V': 224,
                            'VI': 225
                        }
                        self.note_array.list[-1].add_articulation(
                            string_code_dict[harmonic_string_test], 'over')
                        self.note_array.list[-1].is_artificial_harmonic = True
                # With self.artifical_harmonic_frequency add an artificial harmonic at the 8ve
                elif (random.uniform(0, 1) < self.artificial_harmonic_frequency
                      and self.allow_artificial_harmonics
                      and (current_pitch < self.upper_tessitura)):
                    self.note_array.list[-1].is_artificial_harmonic = True
                    if isinstance(self.note_array.list[-1].pitch_num, int):
                        self.note_array.list[-1].pitch_num = [
                            self.note_array.list[-1].pitch_num
                        ]
                    assert isinstance(self.note_array.list[-1].pitch_num, list)
                    self.note_array.list[-1].pitch_num.append(
                        self.note_array.list[-1].pitch_num[0] + 12)
                # TODO: elaborate on guitar chords (not just open strings, over 2 strings, etc.)
                # Within self.chord_frequency, add an open-string double-stop
                elif (random.uniform(0, 1) < self.chord_frequency) and (
                        current_pitch < self.upper_tessitura):
                    if isinstance(self.note_array.list[-1].pitch_num, int):
                        self.note_array.list[-1].pitch_num = [
                            self.note_array.list[-1].pitch_num
                        ]
                    assert isinstance(self.note_array.list[-1].pitch_num, list)
                    open_string_pitch = self.get_best_open_string(
                        self.note_array.list[-1].pitch_num[0])
                    self.note_array.list[-1].pitch_num.append(
                        open_string_pitch)

            current_node = self.pitch_network.pick()

            if random.uniform(0, 1) < self.mode_change_frequency:
                self.change_mode()

        self.note_array.auto_build_octave_spanners()
        self.auto_add_dynamics()
        self.auto_add_slurs()
        if len(self.clef_list) > 1:
            self.note_array.auto_build_clefs(self.clef_list, self.initial_clef,
                                             self.clef_change_tolerance,
                                             self.preferred_clef_extra_weight)

        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(
            config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name,
                                                    view_image=False,
                                                    autocrop=True,
                                                    delete_ly=False)
        config.FileNameIndex += 1
        return output_png
Пример #8
0
    def play(self):
        self.refresh_lily()

        # Roll for special actions
        special_action_roll = rand.weighted_rand(self.special_action_weights,
                                                 'discreet')
        if special_action_roll != 0:
            if special_action_roll == 1:
                self.previous_action = 'Special Action 1'
                return self.special_action_1()
            elif special_action_roll == 2:
                self.previous_action = 'Special Action 2'
                return self.special_action_2()
            elif special_action_roll == 3 and self.previous_action != 'Special Action 3':
                self.previous_action = 'Special Action 3'
                return self.special_action_3()
        else:
            self.previous_action = 'Normal Play'

        note_count = rand.weighted_rand(self.note_count_weights, do_round=True)
        current_node = self.pitch_network.pick()
        while (not isinstance(current_node, nodes.NoteBehavior)) or (
                current_node.name[:4] == 'rest'):
            current_node = self.pitch_network.pick()
        # Get first pitch with a fairly strong bias toward the lower pitches in the register
        current_pitch = current_node.pitch_set[rand.weighted_rand(
            [(0, 100), (len(current_node.pitch_set) - 1, 1)], do_round=True)]

        current_time_in_upper_tessitura = 0

        for i in range(0, note_count):
            current_dur = self.length_network.pick().get_value()
            while isinstance(current_node, nodes.Action):
                current_node = self.pitch_network.pick()
            if current_node.name[:4] == 'rest':
                self.note_array.create_note(current_pitch,
                                            current_dur,
                                            is_rest=True)
                current_time_in_upper_tessitura = 0
            else:
                current_pitch = current_node.move_pitch(current_pitch)
                self.note_array.create_note(current_pitch, current_dur)
                current_time_in_upper_tessitura += current_dur

            current_node = self.pitch_network.pick()
            # If the current time in the upper range exceeds the limit, change current_node to a downward pointing one
            if current_time_in_upper_tessitura > self.max_time_at_high:
                if random.randint(0, 1) == 0:
                    current_node = self.pitch_network.node_list[5]
                else:
                    current_node = self.pitch_network.node_list[7]
                current_time_in_upper_tessitura = 0

            if random.uniform(0, 1) < self.mode_change_frequency:
                self.change_mode()

        self.auto_add_slurs()
        self.auto_add_dynamics()
        if len(self.clef_list) > 1:
            self.note_array.auto_build_clefs(self.clef_list, self.clef_list[0],
                                             self.clef_change_tolerance,
                                             self.preferred_clef_extra_weight)
        if self.instrument_name == 'Flute' or self.instrument_name == 'Alto Flute':
            self.note_array.auto_build_octave_spanners()

        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(
            config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name,
                                                    view_image=False,
                                                    autocrop=True,
                                                    delete_ly=False)
        config.FileNameIndex += 1
        return output_png
Пример #9
0
    def play(self):

        self.refresh_lily()

        # Roll for special actions
        special_action_roll = rand.weighted_rand(self.special_action_weights, 'discreet')
        if special_action_roll != 0:
            if special_action_roll == 1:
                self.previous_action = 'Special Action 1'
                return self.special_action_1()
            elif special_action_roll == 2:
                self.previous_action = 'Special Action 2'
                return self.special_action_2()
            elif special_action_roll == 3 and self.previous_action != 'Special Action 3':
                self.previous_action = 'Special Action 3'
                return self.special_action_3()
        else:
            self.previous_action = 'Normal Play'

        note_count = rand.weighted_rand(self.note_count_weights, do_round=True)
        current_node = self.pitch_network.pick()
        while (not isinstance(current_node, nodes.NoteBehavior)) or (current_node.name[:4] == 'rest'):
            current_node = self.pitch_network.pick()
        # Get first pitch
        current_pitch = self._find_first_pitch(current_node.pitch_set, self.starting_pitch_weights)

        for i in range(0, note_count):
            current_dur = self.length_network.pick().get_value()

            # pick through action (sub-network link) nodes
            while isinstance(current_node, nodes.Action):
                current_node = self.pitch_network.pick()
            if current_node.name[:4] == 'rest':
                self.note_array.create_note(current_pitch, current_dur, is_rest=True)
            else:
                current_pitch = current_node.move_pitch(current_pitch)
                self.note_array.create_note(current_pitch, current_dur)

                # If it's the first note, roll for pizz/mute changes
                if i == 0:
                    if self.is_currently_pizz and random.randint(0, 6) == 0:
                        self.note_array.list[0].add_articulation(201, 'over')
                        self.is_currently_pizz = False
                        self.sustained_playing = True
                    elif not self.is_currently_pizz and random.randint(0, 16) == 0:
                        self.note_array.list[0].add_articulation(200, 'over')
                        self.is_currently_pizz = True
                        self.sustained_playing = False

                    if self.is_currently_muted and random.randint(0, 15) == 0:
                        self.note_array.list[0].add_articulation(203, 'over')
                        self.is_currently_muted = False
                    elif not self.is_currently_muted and random.randint(0, 15) == 0:
                        self.note_array.list[0].add_articulation(202, 'over')
                        self.is_currently_muted = True

                # Within self.natural_harmonic_frequency, if current_pitch can be a natural harmonic, add it
                if random.uniform(0, 1) < self.natural_harmonic_frequency and self.can_be_harmonic(current_pitch):
                    self.note_array.list[-1].add_articulation(105, 'over')
                # Within self.artificial_harmonic_frequency, add an artificial harmonic at the 4th
                elif (random.uniform(0, 1) < self.artificial_harmonic_frequency and
                            self.allow_artificial_harmonics and (current_pitch < self.upper_tessitura)):
                    self.note_array.list[-1].is_artificial_harmonic = True
                    if isinstance(self.note_array.list[-1].pitch_num, int):
                        self.note_array.list[-1].pitch_num = [self.note_array.list[-1].pitch_num]
                    assert isinstance(self.note_array.list[-1].pitch_num, list)
                    self.note_array.list[-1].pitch_num.append(self.note_array.list[-1].pitch_num[0]+5)
                # Within self.chord_frequency, add an open-string double-stop
                elif (random.uniform(0, 1) < self.chord_frequency) and (current_pitch < self.upper_tessitura):
                    if isinstance(self.note_array.list[-1].pitch_num, int):
                        self.note_array.list[-1].pitch_num = [self.note_array.list[-1].pitch_num]
                    open_string_pitch = self.get_best_open_string(self.note_array.list[-1].pitch_num[0])
                    self.note_array.list[-1].pitch_num.append(open_string_pitch)

            current_node = self.pitch_network.pick()

            if random.uniform(0, 1) < self.mode_change_frequency:
                self.change_mode()

        self.note_array.auto_build_octave_spanners()
        self.auto_add_dynamics()
        self.auto_add_slurs()
        if len(self.clef_list) > 1:
            self.note_array.auto_build_clefs(self.clef_list, self.initial_clef,
                                             self.clef_change_tolerance, self.preferred_clef_extra_weight)

        self.score.note_array = self.note_array
        output_ly_file = lilypond_file.LilypondFile(self.score)
        output_file_name = self.instrument_name + '_' + str(config.FileNameIndex)
        output_png = output_ly_file.save_and_render(output_file_name, view_image=False, autocrop=True, delete_ly=False)
        config.FileNameIndex += 1
        return output_png