Ejemplo n.º 1
0
    def __or__(self, expr):
        r'''Logical OR of two payload expressions.

        Payload expression must be able to fuse.

        Returns timespan inventory.
        '''
        assert self._can_fuse(expr)
        if isinstance(self.payload, scoretools.Container):
            selection = select(self.payload[0], contiguous=True)
            left = mutate(selection).copy()[0]
            selection = select(expr.payload[0], contiguous=True)
            right = mutate(selection).copy()[0]
            payload = scoretools.Container([left, right])
            for component in payload[:]:
                component._extract()
            payload = scoretools.Container([payload])
        else:
            payload = self.payload + expr.payload
        result = type(self)(
            [],
            start_offset=self.timespan.start_offset,
            voice_name=self.voice_name,
        )
        result._payload = payload
        return timespantools.TimespanInventory([result])
Ejemplo n.º 2
0
    def _construct_simultaneous_music(self, music):
        def is_separator(x):
            if isinstance(x, lilypondparsertools.LilyPondEvent):
                if x.name == 'VoiceSeparator':
                    return True
            return False

        from abjad.tools import lilypondparsertools
        container = scoretools.Container()
        container.is_simultaneous = True
        # check for voice separators
        groups = []
        for value, group in itertools.groupby(music, is_separator):
            if not value:
                groups.append(list(group))
        # without voice separators
        if 1 == len(groups):
            #assert all(isinstance(x, scoretools.Context) for x in groups[0])
            container.extend(groups[0])
        # with voice separators
        else:
            for group in groups:
                container.append(
                    scoretools.Voice(
                        self._construct_sequential_music(group)[:]))
        return container
Ejemplo n.º 3
0
 def _make_container(self, division):
     from abjad.tools import rhythmmakertools
     duration_spelling_specifier = self.duration_spelling_specifier
     if duration_spelling_specifier is None:
         duration_spelling_specifier = \
             rhythmmakertools.DurationSpellingSpecifier()
     forbidden_written_duration = \
         duration_spelling_specifier.forbidden_written_duration
     time_signature = indicatortools.TimeSignature(division)
     implied_prolation = time_signature.implied_prolation
     numerator, denominator = division.pair
     denominator = mathtools.greatest_power_of_two_less_equal(denominator)
     assert mathtools.is_positive_integer_power_of_two(denominator)
     exponent = self.exponent or 0
     denominator_multiplier = 2**exponent
     denominator *= denominator_multiplier
     unit_duration = durationtools.Duration(1, denominator)
     if forbidden_written_duration is not None:
         multiplier = 1
         while forbidden_written_duration <= unit_duration:
             unit_duration /= 2
             multiplier *= 2
         numerator *= multiplier
     numerator *= denominator_multiplier
     notes = scoretools.make_notes(numerator * [0], [unit_duration])
     if implied_prolation == 1:
         result = scoretools.Container(notes)
     else:
         multiplier = implied_prolation
         result = scoretools.Tuplet(multiplier, notes)
     return result
Ejemplo n.º 4
0
 def _fuse_tuplets(self):
     from abjad.tools import scoretools
     assert self._all_are_contiguous_components_in_same_parent(
         self, prototype=(scoretools.Tuplet, ))
     if len(self) == 0:
         return None
     first = self[0]
     first_multiplier = first.multiplier
     first_type = type(first)
     for tuplet in self[1:]:
         if tuplet.multiplier != first_multiplier:
             message = 'tuplets must carry same multiplier.'
             raise ValueError(message)
         if type(tuplet) != first_type:
             message = 'tuplets must be same type.'
             raise TypeError(message)
     if isinstance(first, scoretools.FixedDurationTuplet):
         total_contents_duration = sum([x._contents_duration for x in self])
         new_target_duration = first_multiplier * total_contents_duration
         new_tuplet = scoretools.FixedDurationTuplet(
             new_target_duration, [])
     elif isinstance(first, scoretools.Tuplet):
         new_tuplet = scoretools.Tuplet(first_multiplier, [])
     else:
         message = 'unknown tuplet type.'
         raise TypeError(message)
     wrapped = False
     if self[0]._get_parentage().root is not \
         self[-1]._get_parentage().root:
         dummy_container = scoretools.Container(self)
         wrapped = True
     mutate(self).swap(new_tuplet)
     if wrapped:
         del (dummy_container[:])
     return new_tuplet
Ejemplo n.º 5
0
 def __init__(self, payload=None, start_offset=None, voice_name=None):
     from abjad.tools import lilypondfiletools
     if isinstance(payload, lilypondfiletools.LilyPondFile):
         payload = payload.items[:]
     payload = scoretools.Container(music=payload)
     StartPositionedPayloadExpression.__init__(
         self,
         payload=payload,
         start_offset=start_offset,
         voice_name=voice_name,
     )
Ejemplo n.º 6
0
def parse_rtm_syntax(rtm):
    r'''Parses RTM syntax.

    ::

        >>> rtm = '(1 (1 (1 (1 1)) 1))'
        >>> rhythmtreetools.parse_rtm_syntax(rtm)
        FixedDurationTuplet(Duration(1, 4), "c'8 c'16 c'16 c'8")

    Also supports fractional durations:

    ::

        >>> rtm = '(3/4 (1 1/2 (4/3 (1 -1/2 1))))'
        >>> rhythmtreetools.parse_rtm_syntax(rtm)
        FixedDurationTuplet(Duration(3, 16), 'c\'8 c\'16 FixedDurationTuplet(Duration(1, 6), "c\'8 r16 c\'8")')

    ::

        >>> print(format(_))
        \tweak #'text #tuplet-number::calc-fraction-text
        \times 9/17 {
            c'8
            c'16
            \tweak #'edge-height #'(0.7 . 0)
            \times 8/15 {
                c'8
                r16
                c'8
            }
        }

    Returns fixed-duration tuplet or container.
    '''
    from abjad.tools import rhythmtreetools

    result = rhythmtreetools.RhythmTreeParser()(rtm)

    con = scoretools.Container()

    for node in result:
        tuplet = node((1, 4))
        # following line added 2012-08-01. tb.
        tuplet = tuplet[0]
        if tuplet.is_trivial:
            con.extend(tuplet[:])
        else:
            con.append(tuplet)

    if len(con) == 1:
        return con[0]
    return con
Ejemplo n.º 7
0
 def _cleanup(self, parsed):
     container = scoretools.Container()
     for x in parsed:
         container.append(x)
     parsed = container
     leaves = parsed.select_leaves(allow_discontiguous_leaves=True)
     if leaves:
         self._apply_spanners(leaves)
     for leaf in leaves:
         detach(indicatortools.Annotation, leaf)
     if 1 < self._toplevel_component_count:
         return parsed
     return parsed[0]
Ejemplo n.º 8
0
    def construct(self):
        r'''Constructs sequential music.

        Returns Abjad container.
        '''
        from abjad.tools import lilypondparsertools
        container = scoretools.Container([])
        for x in self.music:
            if isinstance(x, scoretools.Component):
                container.append(x)
            elif isinstance(x, type(self)):
                container.extend(x.construct())
        return container
Ejemplo n.º 9
0
 def _cleanup(self, parsed):
     import abjad
     container = scoretools.Container()
     for x in parsed:
         container.append(x)
     parsed = container
     leaves = abjad.select(parsed).leaves()
     if leaves:
         self._apply_spanners(leaves)
     for leaf in leaves:
         detach(dict, leaf)
     if 1 < self._toplevel_component_count:
         return parsed
     return parsed[0]
Ejemplo n.º 10
0
 def _construct_sequential_music(self, music):
     # indicator sorting could be rewritten into a single list using tuplets
     # with t[0] being 'forward' or 'backward' and t[1] being the indicator
     # as this better preserves attachment order. Not clear if we need it.
     container = scoretools.Container()
     previous_leaf = None
     apply_forward = []
     apply_backward = []
     # sort events into forward or backwards attaching
     # and attach them to the proper leaf
     for x in music:
         if isinstance(x, scoretools.Component) \
             and not isinstance(x, scoretools.GraceContainer):
             for indicator in apply_forward:
                 attach(indicator, x)
             if previous_leaf:
                 for indicator in apply_backward:
                     attach(indicator, previous_leaf)
             else:
                 for indicator in apply_backward:
                     attach(indicator, x)
             apply_forward = []
             apply_backward = []
             previous_leaf = x
             container.append(x)
         else:
             if isinstance(x, (
                     indicatortools.BarLine,
                     indicatortools.PageBreak,
                     indicatortools.SystemBreak,
             )):
                 apply_backward.append(x)
             elif isinstance(x, indicatortools.LilyPondCommand):
                 if x.name in ('breathe', ):
                     apply_backward.append(x)
             else:
                 apply_forward.append(x)
     # attach remaining events to last leaf
     # or to the container itself if there were no leaves
     if previous_leaf:
         for indicator in apply_forward:
             attach(indicator, previous_leaf)
         for indicator in apply_backward:
             attach(indicator, previous_leaf)
     else:
         for indicator in apply_forward:
             attach(indicator, container)
         for indicator in apply_backward:
             attach(indicator, container)
     return container
Ejemplo n.º 11
0
 def _split_payload_at_offsets(self, offsets):
     assert isinstance(self.payload, scoretools.Container)
     music = self.payload
     self._payload = scoretools.Container()
     shards = mutate([music]).split(
         offsets,
         cyclic=False,
         fracture_spanners=True,
     )
     shards = [shard[0] for shard in shards]
     for shard in shards:
         if not inspect_(shard).is_well_formed():
             inspect_(shard).tabulate_well_formedness_violations_in_expr()
     return shards
Ejemplo n.º 12
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
Ejemplo n.º 13
0
 def _apply_logical_tie_masks(self, selections):
     from abjad.tools import rhythmmakertools
     if self.logical_tie_masks is None:
         return selections
     # wrap every selection in a temporary container;
     # this allows the call to mutate().replace() to work
     containers = []
     for selection in selections:
         container = scoretools.Container(selection)
         attach('temporary container', container)
         containers.append(container)
     logical_ties = iterate(selections).by_logical_tie()
     logical_ties = list(logical_ties)
     total_logical_ties = len(logical_ties)
     for index, logical_tie in enumerate(logical_ties[:]):
         matching_mask = self.logical_tie_masks.get_matching_pattern(
             index,
             total_logical_ties,
         )
         if not isinstance(matching_mask, rhythmmakertools.SilenceMask):
             continue
         if isinstance(logical_tie.head, scoretools.Rest):
             continue
         for leaf in logical_tie:
             rest = scoretools.Rest(leaf.written_duration)
             inspector = inspect_(leaf)
             if inspector.has_indicator(durationtools.Multiplier):
                 multiplier = inspector.get_indicator(
                     durationtools.Multiplier, )
                 multiplier = durationtools.Multiplier(multiplier)
                 attach(multiplier, rest)
             mutate(leaf).replace([rest])
             detach(spannertools.Tie, rest)
     # remove every temporary container and recreate selections
     new_selections = []
     for container in containers:
         inspector = inspect_(container)
         assert inspector.get_indicator(str) == 'temporary container'
         new_selection = mutate(container).eject_contents()
         new_selections.append(new_selection)
     return new_selections
Ejemplo n.º 14
0
    def evaluate(self):
        r'''Evaluate rhythm-maker rhythm region expression.

        Returns none when nonevaluable.

        Returns start-positioned rhythm payload expression when evaluable.
        '''
        from experimental.tools import musicexpressiontools
        if not self.division_list:
            return
        leaf_lists = self.source_expression(self.division_list.pairs)
        rhythm_containers = []
        for x in leaf_lists:
            if isinstance(x, selectiontools.Selection):
                x = scoretools.Container(x)
            rhythm_containers.append(x)
        expression = \
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
            payload=rhythm_containers, start_offset=self.start_offset)
        self._beam_rhythm_containers(rhythm_containers)
        expression._voice_name = self.division_list.voice_name
        return expression
Ejemplo n.º 15
0
def parse_rtm_syntax(rtm):
    r'''Parses RTM syntax.

    ..  container:: example

        Parses tuplet:

        >>> rtm = '(1 (1 (1 (1 1)) 1))'
        >>> tuplet = abjad.rhythmtreetools.parse_rtm_syntax(rtm)
        >>> abjad.show(tuplet) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(tuplet)
            \times 2/3 {
                c'8
                c'16
                c'16
                c'8
            }

    ..  container:: example

        Also supports fractional durations:

        >>> rtm = '(3/4 (1 1/2 (4/3 (1 -1/2 1))))'
        >>> tuplet = abjad.rhythmtreetools.parse_rtm_syntax(rtm)
        >>> abjad.show(tuplet) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(tuplet)
            \tweak text #tuplet-number::calc-fraction-text
            \times 9/17 {
                c'8
                c'16
                \tweak edge-height #'(0.7 . 0)
                \times 8/15 {
                    c'8
                    r16
                    c'8
                }
            }

    Returns tuplet or container.
    '''
    from abjad.tools import rhythmtreetools

    result = rhythmtreetools.RhythmTreeParser()(rtm)

    con = scoretools.Container()

    for node in result:
        tuplet = node((1, 4))
        # following line added 2012-08-01. tb.
        tuplet = tuplet[0]
        if tuplet.trivial():
            con.extend(tuplet[:])
        else:
            con.append(tuplet)

    if len(con) == 1:
        return con[0]
    return con
Ejemplo n.º 16
0
 def p_container__BRACE_L__component_list__BRACE_R(self, p):
     r'''container : BRACE_L component_list BRACE_R
     '''
     p[0] = scoretools.Container()
     for component in p[2]:
         p[0].append(component)
Ejemplo n.º 17
0
    def rotate(self, n, fracture_spanners=True):
        r'''Rotate start-positioned rhythm payload expression.

        Example 1. Rotate by count:

        ::

            >>> payload = [Container("c'8 d'8 e'8 f'8")]
            >>> expression = \
            ...     musicexpressiontools.StartPositionedRhythmPayloadExpression(
            ...     payload, Offset(0))

        ::

            >>> result = expression.rotate(-1)

        ::

            >>> print(format(expression))
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
                payload=scoretools.Container(
                    "{ d'8 e'8 f'8 } { c'8 }"
                    ),
                start_offset=durationtools.Offset(0, 1),
                )

        Example 2. Rotate by duration:

        ::

            >>> payload = [Container("c'8 d'8 e'8 f'8")]
            >>> expression = \
            ...     musicexpressiontools.StartPositionedRhythmPayloadExpression(
            ...     payload, Offset(0))

        ::

            >>> result = expression.rotate(-Duration(3, 16))

        ::

            >>> print(format(expression))
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
                payload=scoretools.Container(
                    "{ d'16 e'8 f'8 } { c'8 d'16 }"
                    ),
                start_offset=durationtools.Offset(0, 1),
                )

        Operates in place and returns start-positioned rhythm
        payload expression.
        '''
        from experimental.tools import musicexpressiontools
        if isinstance(n, int):
            leaves = datastructuretools.CyclicTuple(
                self.payload.select_leaves())
            if 0 < n:
                split_offset = leaves[-n]._get_timespan().start_offset
            elif n == 0:
                return self
            else:
                split_offset = leaves[-(n + 1)]._get_timespan().stop_offset
        elif isinstance(n, musicexpressiontools.RotationExpression):
            rotation_expression = n
            if rotation_expression.level is None:
                components_at_level = self.payload.select_leaves()
            else:
                components_at_level = []
                for component in \
                    iterate(self.payload).by_class():
                    score_index = component._get_parentage().score_index
                    if len(score_index) == rotation_expression.level:
                        components_at_level.append(component)
            components_at_level = datastructuretools.CyclicTuple(
                components_at_level)
            if isinstance(rotation_expression.index, int):
                if 0 < rotation_expression.index:
                    split_offset = components_at_level[-rotation_expression.
                                                       index]._get_timespan(
                                                       ).start_offset
                elif n == 0:
                    return self
                else:
                    split_offset = components_at_level[-(
                        rotation_expression.index +
                        1)]._get_timespan().stop_offset
            else:
                index = durationtools.Duration(rotation_expression.index)
                if 0 <= index:
                    split_offset = self.payload._get_duration() - index
                else:
                    split_offset = abs(index)
            if rotation_expression.fracture_spanners is not None:
                fracture_spanners = rotation_expression.fracture_spanners
        else:
            n = durationtools.Duration(n)
            if 0 <= n:
                split_offset = self.payload._get_duration() - n
            else:
                split_offset = abs(n)
        #self._debug(split_offset, 'split offset')
        try:
            payload_duration = getattr(self, 'payload')
        except AttributeError:
            payload_duration = self.payload._get_duration()
        if split_offset == payload_duration:
            return self
        if fracture_spanners:
            result = mutate([self.payload]).split(
                [split_offset],
                cyclic=False,
                fracture_spanners=True,
                tie_split_notes=False,
            )
            left_half, right_half = result[0][0], result[-1][0]
            payload = scoretools.Container()
            payload.extend(right_half)
            payload.extend(left_half)
            assert inspect_(payload).is_well_formed()
            self._payload = payload
        else:
            result = mutate(self.payload[:]).split(
                [split_offset],
                cyclic=False,
                fracture_spanners=False,
                tie_split_notes=False,
            )
            left_half, right_half = result[0], result[-1]
            prototype = (spannertools.DuratedComplexBeam, )
            descendants = self.payload._get_descendants()
            for spanner in descendants.get_spanners(prototype):
                if left_half[-1] in spanner and right_half[0] in spanner:
                    leaf_right_of_split = right_half[0]
                    split_offset_in_beam = spanner._start_offset_in_me(
                        leaf_right_of_split)
                    left_durations, right_durations = \
                        sequencetools.split_sequence(
                            spanner.durations,
                            [split_offset_in_beam],
                            cyclic=False,
                            overhang=True,
                            )
                    new_durations = right_durations + left_durations
                    spanner._durations = new_durations
            new_payload = right_half + left_half
            self.payload._music = new_payload
            for component in new_payload:
                component._update_later(offsets=True)
            for spanner in self.payload._get_descendants().get_spanners():
                spanner._components.sort(
                    key=lambda x: x._get_parentage().score_index)
            assert inspect_(self.payload).is_well_formed()
        return self
Ejemplo n.º 18
0
def make_mozart_score():
    r'''Makes Mozart score.
    '''

    score_template = templatetools.TwoStaffPianoScoreTemplate()
    score = score_template()

    # select the measures to use
    choices = abjad.demos.mozart.choose_mozart_measures()

    # create and populate the volta containers
    treble_volta = scoretools.Container()
    bass_volta = scoretools.Container()
    for choice in choices[:7]:
        treble, bass = abjad.demos.mozart.make_mozart_measure(choice)
        treble_volta.append(treble)
        bass_volta.append(bass)

    # attach indicators to the volta containers
    command = indicatortools.LilyPondCommand('repeat volta 2', 'before')
    attach(command, treble_volta)
    command = indicatortools.LilyPondCommand('repeat volta 2', 'before')
    attach(command, bass_volta)

    # append the volta containers to our staves
    score['RH Voice'].append(treble_volta)
    score['LH Voice'].append(bass_volta)

    # create and populate the alternative ending containers
    treble_alternative = scoretools.Container()
    bass_alternative = scoretools.Container()
    for choice in choices[7:9]:
        treble, bass = abjad.demos.mozart.make_mozart_measure(choice)
        treble_alternative.append(treble)
        bass_alternative.append(bass)

    # attach indicators to the alternative containers
    command = indicatortools.LilyPondCommand('alternative', 'before')
    attach(command, treble_alternative)
    command = indicatortools.LilyPondCommand('alternative', 'before')
    attach(command, bass_alternative)

    # append the alternative containers to our staves
    score['RH Voice'].append(treble_alternative)
    score['LH Voice'].append(bass_alternative)

    # create the remaining measures
    for choice in choices[9:]:
        treble, bass = abjad.demos.mozart.make_mozart_measure(choice)
        score['RH Voice'].append(treble)
        score['LH Voice'].append(bass)

    # attach indicators
    time_signature = indicatortools.TimeSignature((3, 8))
    attach(time_signature, score['RH Staff'])
    bar_line = indicatortools.BarLine('|.')
    attach(bar_line, score['RH Voice'][-1])
    bar_line = indicatortools.BarLine('|.')
    attach(bar_line, score['LH Voice'][-1])

    # remove the old, default piano instrument attached to the piano staff
    # and attach a custom instrument mark
    detach(instrumenttools.Instrument, score['Piano Staff'])

    klavier = instrumenttools.Piano(
        instrument_name='Katzenklavier',
        short_instrument_name='kk.',
    )
    attach(klavier, score['Piano Staff'])

    return score