コード例 #1
0
def edit_second_violin_voice(score, durated_reservoir):
    r'''Edits second violin voice.
    '''

    voice = score['Second Violin Voice']
    descents = durated_reservoir['Second Violin']

    last_descent = select(descents[-1])
    copied_descent = mutate(last_descent).copy()
    copied_descent = list(copied_descent)
    copied_descent[-1].written_duration = durationtools.Duration(1, 1)
    copied_descent.append(scoretools.Note('a2'))
    for leaf in copied_descent:
        articulation = indicatortools.Articulation('accent')
        attach(articulation, leaf)
        articulation = indicatortools.Articulation('tenuto')
        attach(articulation, leaf)
    voice.extend(copied_descent)

    final_sustain = []
    for _ in range(32):
        final_sustain.append(scoretools.Note('a1.'))
    final_sustain.append(scoretools.Note('a2'))
    articulation = indicatortools.Articulation('accent')
    attach(articulation, final_sustain[0])
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, final_sustain[0])

    voice.extend(final_sustain)
    tie = spannertools.Tie()
    attach(tie, final_sustain)
    voice.extend('r4 r2.')
コード例 #2
0
def apply_bowing_marks(score):
    r'''Applies bowing marks to score.
    '''

    # apply alternating upbow and downbow for first two sounding bars
    # of the first violin
    for measure in score['First Violin Voice'][6:8]:
        for i, chord in enumerate(iterate(measure).by_class(scoretools.Chord)):
            if i % 2 == 0:
                articulation = indicatortools.Articulation('downbow')
                attach(articulation, chord)
            else:
                articulation = indicatortools.Articulation('upbow')
                attach(articulation, chord)

    # create and apply rebowing markup
    rebow_markup = markuptools.Markup.concat([
        markuptools.Markup.musicglyph('scripts.downbow'),
        markuptools.Markup.hspace(1),
        markuptools.Markup.musicglyph('scripts.upbow'),
    ])
    markup = copy.copy(rebow_markup)
    attach(markup, score['First Violin Voice'][64][0])
    markup = copy.copy(rebow_markup)
    attach(markup, score['Second Violin Voice'][75][0])
    markup = copy.copy(rebow_markup)
    attach(markup, score['Viola Voice'][86][0])
コード例 #3
0
def edit_cello_voice(score, durated_reservoir):
    r'''Edits cello voice.
    '''

    voice = score['Cello Voice']
    descents = durated_reservoir['Cello']

    logical_tie = inspect_(voice[-1]).get_logical_tie()
    for leaf in logical_tie.leaves:
        parent = leaf._get_parentage().parent
        index = parent.index(leaf)
        parent[index] = scoretools.Chord(['e,', 'a,'], leaf.written_duration)

    selection = voice[-len(descents[-1]):]
    unison_descent = mutate(selection).copy()
    voice.extend(unison_descent)
    for chord in unison_descent:
        index = inspect_(chord).get_parentage().parent.index(chord)
        parent[index] = scoretools.Note(
            chord.written_pitches[1], chord.written_duration)
        articulation = indicatortools.Articulation('accent')
        attach(articulation, parent[index])
        articulation = indicatortools.Articulation('tenuto')
        attach(articulation, parent[index])

    voice.extend('a,1. ~ a,2')
    voice.extend('b,1 ~ b,1. ~ b,1.')
    voice.extend('a,1. ~ a,1. ~ a,1. ~ a,1. ~ a,1. ~ a,2')
    voice.extend('r4 r2.')
コード例 #4
0
 def _make_bow_direction_change_contributions(
     self,
     bow_contact_point=None,
     leaf=None,
     lilypond_format_bundle=None,
     ):
     direction_change = None
     next_leaf = inspect_(leaf).get_leaf(1)
     this_contact_point = bow_contact_point
     next_contact_point = inspect_(next_leaf).get_indicator(
         indicatortools.BowContactPoint)
     if self._is_my_first_leaf(leaf):
         if this_contact_point < next_contact_point:
             direction_change = Up
         elif next_contact_point < this_contact_point:
             direction_change = Down
     else:
         previous_leaf = inspect_(leaf).get_leaf(-1)
         previous_contact_point = inspect_(previous_leaf
             ).get_indicator(indicatortools.BowContactPoint)
         if (previous_contact_point < this_contact_point and
             next_contact_point < this_contact_point):
             direction_change = Down
         elif (this_contact_point < previous_contact_point and
             this_contact_point < next_contact_point):
             direction_change = Up
     if direction_change is None:
         return
     if direction_change == Up:
         articulation = indicatortools.Articulation('upbow', Up)
     elif direction_change == Down:
         articulation = indicatortools.Articulation('downbow', Up)
     string = str(articulation)
     lilypond_format_bundle.right.articulations.append(string)
コード例 #5
0
    def __call__(
        self,
        expr,
        timespan=None,
        offset=0,
        skip_first=0,
        skip_last=0,
    ):
        r'''Calls handler on `expr` with keywords.

        Returns none.
        '''
        articulation_lists = datastructuretools.CyclicTuple(
            self.articulation_lists)
        prototype = (scoretools.Note, scoretools.Chord)
        notes_and_chords = list(iterate(expr).by_class(prototype))
        notes_and_chords = notes_and_chords[skip_first:]
        if skip_last:
            notes_and_chords = notes_and_chords[:-skip_last]
        i = 0
        for note_or_chord in notes_and_chords:
            logical_tie = inspect_(note_or_chord).get_logical_tie()
            duration = logical_tie.get_duration()
            articulation_list = articulation_lists[offset + i]
            if articulation_list is None:
                i += 1
                continue
            articulation_list = [
                indicatortools.Articulation(_) for _ in articulation_list
            ]
            if self.minimum_duration is not None:
                if duration <= self.minimum_duration:
                    continue
            if self.maximum_duration is not None:
                if self.maximum_duration < duration:
                    continue
            if self.minimum_written_pitch is not None:
                if isinstance(note_or_chord, scoretools.Note):
                    minimum_written_pitch = note_or_chord.written_pitch
                else:
                    minimum_written_pitch = note_or_chord.writen_pitches[0]
                if minimum_written_pitch < self.minimum_written_pitch:
                    continue
            if self.maximum_written_pitch is not None:
                if isinstance(note_or_chord, scoretools.Note):
                    maximum_written_pitch = note_or_chord.written_pitch
                else:
                    maximum_written_pitch = note_or_chord.written_pitches[-1]
                if self.maximum_written_pitch < maximum_written_pitch:
                    continue
            logical_tie = inspect_(note_or_chord).get_logical_tie()
            if note_or_chord is logical_tie.head:
                for articulation in articulation_list:
                    # TODO: make new(articulation) work
                    articulation = copy.copy(articulation)
                    attach(articulation, note_or_chord)
                i += 1
        return expr
コード例 #6
0
    def set_articulation(self, source_expression):
        r'''Set articulation to `source_expression`.

        Returns articulation set expression.
        '''
        from experimental.tools import musicexpressiontools
        if isinstance(source_expression, indicatortools.Articulation):
            articulation_list = [source_expression]
        elif isinstance(source_expression, str):
            articulation = indicatortools.Articulation(source_expression)
            articulation_list = [articulation]
        elif isinstance(source_expression, list):
            articulation_list = [
                indicatortools.Articulation(x) for x in source_expression
            ]
        source_expression = \
            musicexpressiontools.PayloadExpression(payload=articulation_list)
        attribute = 'articulation'
        return self._store_leaf_set_expression(attribute, source_expression)
コード例 #7
0
 def execute_against_score(self, score):
     r'''Execute articulation set expression against `score`.
     '''
     articulation_list = self.source_expression.payload
     leaves = self._iterate_selected_leaves_in_score(score)
     articulation_list = [
         indicatortools.Articulation(x) for x in articulation_list
     ]
     for leaf in leaves:
         for articulation in articulation_list:
             new_articulation = copy.copy(articulation)
             attach(new_articulation, leaf)
コード例 #8
0
    def __call__(self, expr, offset=0, skip_first=0, skip_last=0):
        r'''Calls handler on `expr` with keywords.

        Returns none.
        '''
        prototype = (scoretools.Note, scoretools.Chord)
        notes_and_chords = list(iterate(expr).by_class(prototype))
        notes_and_chords = notes_and_chords[skip_first:]
        if skip_last:
            notes_and_chords = notes_and_chords[:-skip_last]
        total_length = len(notes_and_chords)
        for i, note_or_chord in enumerate(notes_and_chords):
            if self.pattern is not None:
                if not self.pattern.matches_index(i, total_length):
                    continue
            logical_tie = inspect_(note_or_chord).get_logical_tie()
            if self.skip_ties and not logical_tie.is_trivial:
                continue
            if not note_or_chord is logical_tie.head:
                continue
            duration = logical_tie.get_duration()
            if self.minimum_duration is not None:
                if duration < self.minimum_duration:
                    continue
            if self.maximum_duration is not None:
                if self.maximum_duration <= duration:
                    continue
            if self.minimum_written_pitch is not None:
                if isinstance(note_or_chord, scoretools.Note):
                    minimum_written_pitch = note_or_chord.pitch
                else:
                    minimum_written_pitch = note_or_chord.written_pitches[0]
                if minimum_written_pitch < self.minimum_written_pitch:
                    continue
            if self.maximum_written_pitch is not None:
                if isinstance(note_or_chord, scoretools.Note):
                    maximum_written_pitch = note_or_chord.written_pitch
                else:
                    maximum_written_pitch = note_or_chord.written_pitches[-1]
                if self.maximum_written_pitch < maximum_written_pitch:
                    continue
            articulations = [
                indicatortools.Articulation(_) for _ in self.articulation_list
            ]
            for articulation in articulations:
                articulation = copy.deepcopy(articulation)
                attach(articulation, note_or_chord)
        return expr
コード例 #9
0
 def _resolve_event_identifier(self, identifier):
     from abjad.tools import lilypondparsertools
     # without any leading slash
     lookup = self._current_module[identifier]
     name = lookup['name']
     if name == 'ArticulationEvent':
         return indicatortools.Articulation(lookup['articulation-type'])
     elif name == 'AbsoluteDynamicEvent':
         return indicatortools.Dynamic(lookup['text'])
     elif name == 'LaissezVibrerEvent':
         return indicatortools.LilyPondCommand('laissezVibrer', 'after')
     event = lilypondparsertools.LilyPondEvent(name)
     if 'span-direction' in lookup:
         if lookup['span-direction'] == -1:
             event.span_direction = 'start'
         else:
             event.span_direction = 'stop'
     return event
コード例 #10
0
def make_desordre_cell(pitches):
    '''The function constructs and returns a *Désordre cell*.
    `pitches` is a list of numbers or, more generally, pitch tokens.
    '''

    notes = [scoretools.Note(pitch, (1, 8)) for pitch in pitches]
    beam = spannertools.Beam()
    attach(beam, notes)
    slur = spannertools.Slur()
    attach(slur, notes)
    clef = indicatortools.Dynamic('f')
    attach(clef, notes[0])
    dynamic = indicatortools.Dynamic('p')
    attach(dynamic, notes[1])

    # make the lower voice
    lower_voice = scoretools.Voice(notes)
    lower_voice.name = 'RH Lower Voice'
    command = indicatortools.LilyPondCommand('voiceTwo')
    attach(command, lower_voice)
    n = int(math.ceil(len(pitches) / 2.))
    chord = scoretools.Chord([pitches[0], pitches[0] + 12], (n, 8))
    articulation = indicatortools.Articulation('>')
    attach(articulation, chord)

    # make the upper voice
    upper_voice = scoretools.Voice([chord])
    upper_voice.name = 'RH Upper Voice'
    command = indicatortools.LilyPondCommand('voiceOne')
    attach(command, upper_voice)

    # combine them together
    container = scoretools.Container([lower_voice, upper_voice])
    container.is_simultaneous = True

    # make all 1/8 beats breakable
    leaves = select(lower_voice).by_leaf()
    for leaf in leaves[:-1]:
        bar_line = indicatortools.BarLine('')
        attach(bar_line, leaf)

    return container
コード例 #11
0
def edit_viola_voice(score, durated_reservoir):
    r'''Edits viola voice.
    '''

    voice = score['Viola Voice']
    descents = durated_reservoir['Viola']

    for leaf in descents[-1]:
        articulation = indicatortools.Articulation('accent')
        attach(articulation, leaf)
        articulation = indicatortools.Articulation('tenuto')
        attach(articulation, leaf)
    last_descent = select(descents[-1])
    copied_descent = mutate(last_descent).copy()
    for leaf in copied_descent:
        if leaf.written_duration == durationtools.Duration(4, 4):
            leaf.written_duration = durationtools.Duration(8, 4)
        else:
            leaf.written_duration = durationtools.Duration(4, 4)
    voice.extend(copied_descent)

    bridge = scoretools.Note('e1')
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, bridge)
    articulation = indicatortools.Articulation('accent')
    attach(articulation, bridge)
    voice.append(bridge)

    final_sustain_rhythm = [(6, 4)] * 21 + [(1, 2)]
    final_sustain_notes = scoretools.make_notes(['e'], final_sustain_rhythm)
    articulation = indicatortools.Articulation('accent')
    attach(articulation, final_sustain_notes[0])
    articulation = indicatortools.Articulation('tenuto')
    attach(articulation, final_sustain_notes[0])
    voice.extend(final_sustain_notes)
    tie = spannertools.Tie()
    attach(tie, final_sustain_notes)
    voice.extend('r4 r2.')
コード例 #12
0
# -*- encoding: utf-8 -*-
import consort
from abjad.tools import indicatortools
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from abjad.tools import spannertools
from ersilia.materials import abbreviations

guitar_tremolo_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        accents=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('accent'),
            selector=selectortools.select_pitched_runs().by_counts(
                [3], cyclic=True)[1],
        ),
        dynamic_expressions=consort.DynamicExpression(
            division_period=2,
            dynamic_tokens='pp mf p p mf mf pp',
            start_dynamic_tokens='fp niente',
            stop_dynamic_tokens='niente f',
        ),
        stem_tremolo_spanner=consort.AttachmentExpression(
            attachments=spannertools.StemTremoloSpanner(),
            selector=selectortools.select_pitched_runs(),
        ),
    ),
    color='red',
    pitch_handler=consort.AbsolutePitchHandler(
        logical_tie_expressions=[
            consort.ChordExpression(chord_expr=_, )
            for _ in abbreviations.guitar_chords
コード例 #13
0
# -*- encoding: utf-8 -*-
import consort
from abjad.tools import indicatortools
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from ersilia.materials import abbreviations


string_pointillist_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        mordents=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('mordent'),
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                [0]
            ),
        dynamic_expressions=consort.DynamicExpression(
            start_dynamic_tokens='ppp',
            only_first=True,
            ),
        text_spanner=consort.AttachmentExpression(
            attachments=consort.AttachmentExpression(
                attachments=abbreviations.make_text_spanner('pizz.'),
                selector=selectortools.Selector().by_leaf(),
                ),
            selector=selectortools.Selector().by_leaf(),
            ),
        ),
    color='darkyellow',
    labels=[],
    pitch_handler=consort.PitchClassPitchHandler(
コード例 #14
0
# -*- encoding: utf-8 -*-
from abjad.tools import indicatortools
from abjad.tools import patterntools
from abjad.tools import rhythmmakertools
from abjad.tools import scoretools
from abjad.tools import selectortools
from abjad.tools import spannertools
from ersilia.materials import abbreviations
import consort


piano_agitato_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        accents=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('accent'),
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                .by_duration('==', (1, 8), preprolated=True)
                [0],
            ),
        dynamic_expressions=consort.DynamicExpression(
            division_period=2,
            dynamic_tokens='mf mp fff',
            start_dynamic_tokens='f',
            stop_dynamic_tokens='mf',
            ),
        mordent=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('mordent'),
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                .by_duration('>=', (1, 8), preprolated=True)
コード例 #15
0
 def _make_bow_direction_change_contributions(
     self,
     bow_contact_point=None,
     leaf=None,
     lilypond_format_bundle=None,
 ):
     cautionary_change = False
     direction_change = None
     next_leaf = inspect_(leaf).get_leaf(1)
     this_contact_point = bow_contact_point
     if this_contact_point is None:
         return
     next_contact_point = inspect_(next_leaf).get_indicator(
         indicatortools.BowContactPoint)
     if next_contact_point is None:
         return
     previous_leaf = inspect_(leaf).get_leaf(-1)
     previous_contact_point = None
     if previous_leaf is not None:
         previous_contact_points = inspect_(previous_leaf).get_indicators(
             indicatortools.BowContactPoint)
         if previous_contact_points:
             previous_contact_point = previous_contact_points[0]
     if self._is_my_first_leaf(leaf) or \
         previous_contact_point is None or \
         previous_contact_point.contact_point is None:
         if this_contact_point < next_contact_point:
             direction_change = Down
         elif next_contact_point < this_contact_point:
             direction_change = Up
     else:
         previous_leaf = inspect_(leaf).get_leaf(-1)
         previous_contact_point = inspect_(previous_leaf).get_indicator(
             indicatortools.BowContactPoint)
         if (previous_contact_point < this_contact_point
                 and next_contact_point < this_contact_point):
             direction_change = Up
         elif (this_contact_point < previous_contact_point
               and this_contact_point < next_contact_point):
             direction_change = Down
         elif (this_contact_point == previous_contact_point):
             if this_contact_point < next_contact_point:
                 cautionary_change = True
                 direction_change = Down
             elif next_contact_point < this_contact_point:
                 cautionary_change = True
                 direction_change = Up
     if direction_change is None:
         return
     if cautionary_change:
         if direction_change == Up:
             string = r'^ \parenthesize \upbow'
         elif direction_change == Down:
             string = r'^ \parenthesize \downbow'
     else:
         if direction_change == Up:
             articulation = indicatortools.Articulation('upbow', Up)
         elif direction_change == Down:
             articulation = indicatortools.Articulation('downbow', Up)
         string = str(articulation)
     lilypond_format_bundle.right.articulations.append(string)
コード例 #16
0
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from abjad.tools import spannertools
from ersilia.materials import abbreviations


string_ostinato_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        dynamic_expressions=consort.DynamicExpression(
            dynamic_tokens='p',
            ),
        pizzicati=consort.AttachmentExpression(
            attachments=[
                [
                    abbreviations.make_text_markup('pizz.'),
                    indicatortools.Articulation('snappizzicato'),
                    ],
                ],
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                .by_contiguity()
                .by_length('==', 1)
                .by_duration('==', (1, 16), preprolated=True)
                .by_leaf()
                [0]
            ),
        tenuti=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('tenuto'),
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                .by_contiguity()
コード例 #17
0
# -*- encoding: utf-8 -*-
import consort
from abjad.tools import indicatortools
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from abjad.tools import spannertools
from ersilia.materials import abbreviations

percussion_marimba_ostinato_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        clef_spanner=consort.ClefSpannerExpression(),
        deadstroke=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('stopped'),
            selector=selectortools.Selector().by_logical_tie(
                pitched=True).by_duration(
                    '==', (1, 16), preprolated=True).by_contiguity().by_length(
                        '==', 1).by_leaf()[0]),
        dynamic_expressions=consort.DynamicExpression(dynamic_tokens='p', ),
        slur=consort.AttachmentExpression(
            attachments=spannertools.Slur(),
            selector=selectortools.Selector().by_logical_tie(
                pitched=True).by_duration(
                    '==', (1, 16),
                    preprolated=True).by_contiguity().by_length('>',
                                                                1).by_leaf()),
        staccati=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('staccato'),
            selector=selectortools.Selector().by_logical_tie(
                pitched=True).by_duration(
                    '==', (1, 16), preprolated=True).by_contiguity().by_length(
                        '>', 1).by_leaf()[-1]),
コード例 #18
0
# -*- encoding: utf-8 -*-
import consort
from abjad.tools import durationtools
from abjad.tools import indicatortools
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from ersilia.materials import abbreviations


shaker_decelerando_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        staccati=indicatortools.Articulation('staccato'),
        dynamic_expression=consort.DynamicExpression(
            start_dynamic_tokens='f mf mp',
            stop_dynamic_tokens='p',
            ),
        percussion_staff=abbreviations.percussion_staff,
        text_spanner=consort.AttachmentExpression(
            attachments=abbreviations.make_text_spanner('shaker'),
            selector=selectortools.Selector().by_leaf(),
            ),
        ),
    color='blue',
    labels=['shakers'],
    pitch_handler=consort.AbsolutePitchHandler(
        pitches_are_nonsemantic=True,
        ),
    rhythm_maker=rhythmmakertools.AccelerandoRhythmMaker(
        beam_specifier=rhythmmakertools.BeamSpecifier(
            use_feather_beams=True,
            ),
コード例 #19
0
        rotation_indices=(1, 0, 1, 0, -1),
        secondary_music_specifier=lh_diads,
    ),
)

segment_maker.add_setting(
    timespan_maker=armilla.materials.dense_timespan_maker,
    timespan_identifier=consort.RatioPartsExpression(
        parts=(2, ),
        ratio=(2, 2, 1),
    ),
    viola_1=consort.CompositeMusicSpecifier(
        primary_music_specifier=new(
            rh_overpressure,
            attachment_handler__articulations=consort.AttachmentExpression(
                attachments=indicatortools.Articulation('>', 'down'),
                selector=selectortools.Selector().by_leaf()[:-1].flatten(),
            ),
            attachment_handler__stem_tremolo_spanner=intermittent_tremoli,
            attachment_handler__bow_motion_technique_x=intermittent_circular,
            rhythm_maker__default__denominators=(4, 16, 4, 4, 4),
            seed=1,
        ),
        rotation_indices=(1, 0, 1, 0, -1),
        secondary_music_specifier=new(
            lh_diads,
            attachment_handler__glissando=intermittent_glissandi,
        ),
    ),
    viola_2=consort.CompositeMusicSpecifier(
        primary_music_specifier=new(
コード例 #20
0

guitar_strummed_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        damped=consort.AttachmentExpression(
            attachments=consort.LeafExpression(
                leaf=scoretools.Note("f'4"),
                attachments=[
                    lilypondnametools.LilyPondGrobOverride(
                        grob_name='NoteHead',
                        is_once=True,
                        property_path='transparent',
                        value=True,
                        ),
                    markuptools.Markup.musicglyph('scripts.coda'),
                    indicatortools.Articulation('accent'),
                    indicatortools.Dynamic('sfz'),
                    ],
                ),
            is_destructive=True,
            selector=selectortools.Selector()
                .by_logical_tie(pitched=True)
                .by_contiguity()
                .by_length('>', 1)
                .by_leaf()
                [-1]
            ),
        dynamic_expressions=consort.DynamicExpression(
            dynamic_tokens='p ppp p ppp mf p',
            only_first=True,
            ),
コード例 #21
0
# -*- encoding: utf-8 -*-
import consort
from abjad.tools import indicatortools
from abjad.tools import patterntools
from abjad.tools import rhythmmakertools
from abjad.tools import selectortools
from abjad.tools import spannertools
from ersilia.materials import abbreviations

wind_agitato_music_specifier = consort.MusicSpecifier(
    attachment_handler=consort.AttachmentHandler(
        accents_short=consort.AttachmentExpression(
            attachments=[
                [
                    indicatortools.Articulation('accent'),
                    indicatortools.Articulation('staccatissimo'),
                ],
            ],
            selector=selectortools.Selector().by_logical_tie(
                pitched=True).by_duration(
                    '==', (1, 16), preprolated=True).by_contiguity().by_length(
                        '==', 1).by_leaf()[0]),
        accents_long=consort.AttachmentExpression(
            attachments=indicatortools.Articulation('accent'),
            selector=selectortools.Selector().by_logical_tie(
                pitched=True).by_duration(
                    '>', (1, 16), preprolated=True).by_contiguity().by_length(
                        '==', 1).by_leaf()[0]),
        dynamic_expressions=consort.DynamicExpression(
            division_period=2,
            dynamic_tokens='mf mp fff',