Пример #1
0
    def list_octave_transpositions(self, pitch_carrier):
        r"""Lists octave transpositions of `pitch_carrier` in pitch range.

        ..  container:: example

            ::

                >>> chord = Chord("<c' d' e'>4")
                >>> pitch_range = pitchtools.PitchRange.from_pitches(0, 48)
                >>> result = pitch_range.list_octave_transpositions(chord)

            ::

                >>> for chord in result:
                ...     chord
                ...
                Chord("<c' d' e'>4")
                Chord("<c'' d'' e''>4")
                Chord("<c''' d''' e'''>4")
                Chord("<c'''' d'''' e''''>4")

        Returns a list of `pitch_carrier` objects.
        """
        from abjad.tools import pitchtools
        from abjad.tools import scoretools
        if isinstance(pitch_carrier, collections.Iterable):
            if all(isinstance(x, (int, float)) for x in pitch_carrier):
                return self._list_numeric_octave_transpositions(pitch_carrier)
        prototype = (scoretools.Chord, pitchtools.PitchSet)
        if not isinstance(pitch_carrier, prototype):
            message = 'must be chord or pitch-set: {!r}'
            message = message.format(pitch_carrier)
            raise TypeError(message)
        result = []
        interval = pitchtools.NumberedInterval(-12)
        while True:
            pitch_carrier_copy = copy.copy(pitch_carrier)
            candidate = pitchtools.transpose_pitch_carrier_by_interval(
                pitch_carrier_copy, interval)
            if candidate in self:
                result.append(candidate)
                interval -= pitchtools.NumberedInterval(12)
            else:
                break
        result.reverse()
        interval = pitchtools.NumberedInterval(0)
        while True:
            pitch_carrier_copy = copy.copy(pitch_carrier)
            candidate = pitchtools.transpose_pitch_carrier_by_interval(
                pitch_carrier_copy, interval)
            if candidate in self:
                result.append(candidate)
                interval += pitchtools.NumberedInterval(12)
            else:
                break
        return result
Пример #2
0
    def spread(self):
        r'''Spread of interval segment.

        The maximum interval spanned by any combination of
        the intervals within a numbered interval segment.

        ::

            >>> pitchtools.IntervalSegment([1, 2, -3, 1, -2, 1]).spread
            NumberedInterval(4)

        ::

            >>> pitchtools.IntervalSegment([1, 1, 1, 2, -3, -2]).spread
            NumberedInterval(5)

        Returns numbered interval.
        '''
        from abjad.tools import pitchtools
        current = maximum = minimum = 0
        for x in self:
            current += float(x)
            if maximum < current:
                maximum = current
            if current < minimum:
                minimum = current
        return pitchtools.NumberedInterval(maximum - minimum)
Пример #3
0
    def from_pitch_carriers(cls, pitch_carrier_1, pitch_carrier_2):
        '''Calculate named interval from `pitch_carrier_1` to
        `pitch_carrier_2`:

        ::

            >>> pitchtools.NamedInterval.from_pitch_carriers(
            ...     NamedPitch(-2),
            ...     NamedPitch(12),
            ...     )
            NamedInterval('+M9')

        Returns named interval.
        '''
        from abjad.tools import pitchtools
        pitch_1 = pitchtools.NamedPitch.from_pitch_carrier(pitch_carrier_1)
        pitch_2 = pitchtools.NamedPitch.from_pitch_carrier(pitch_carrier_2)
        degree_1 = pitch_1.diatonic_pitch_number
        degree_2 = pitch_2.diatonic_pitch_number
        named_interval_number = abs(degree_1 - degree_2) + 1
        numbered_interval_number = abs(
            pitchtools.NumberedPitch(pitch_1).pitch_number -
            pitchtools.NumberedPitch(pitch_2).pitch_number)
        numbered_interval = pitchtools.NumberedInterval(
            numbered_interval_number, )
        absolute_named_interval = numbered_interval.to_named_interval(
            named_interval_number)
        if pitch_2 < pitch_1:
            named_interval = -absolute_named_interval
        else:
            named_interval = absolute_named_interval
        return cls(named_interval)
Пример #4
0
 def _transpose_pitch_carrier_by_numbered_interval(pitch_carrier,
                                                   numbered_interval):
     mci = pitchtools.NumberedInterval(numbered_interval)
     if isinstance(pitch_carrier, pitchtools.Pitch):
         number = pitch_carrier.pitch_number + mci.semitones
         return type(pitch_carrier)(number)
     elif isinstance(pitch_carrier, numbers.Number):
         pitch_carrier = pitchtools.NumberedPitch(pitch_carrier)
         result = _transpose_pitch_carrier_by_numbered_interval(
             pitch_carrier, mci)
         return result.pitch_number
     elif isinstance(pitch_carrier, scoretools.Note):
         new_note = copy.copy(pitch_carrier)
         number = pitchtools.NumberedPitch(
             pitch_carrier.written_pitch).pitch_number
         number += mci.number
         new_pitch = pitchtools.NamedPitch(number)
         new_note.written_pitch = new_pitch
         return new_note
     elif isinstance(pitch_carrier, scoretools.Chord):
         new_chord = copy.copy(pitch_carrier)
         pairs = zip(new_chord.note_heads, pitch_carrier.note_heads)
         for new_nh, old_nh in pairs:
             number = \
                 pitchtools.NumberedPitch(old_nh.written_pitch).pitch_number
             number += mci.number
             new_pitch = pitchtools.NamedPitch(number)
             new_nh.written_pitch = new_pitch
         return new_chord
     else:
         return pitch_carrier
    def __add__(self, argument):
        r'''Adds `argument` to numbered pitch-class.

        ..  container:: example

            ::

                >>> pitch_class = abjad.NumberedPitchClass(9)

            ::

                >>> pitch_class + abjad.NumberedInterval(0)
                NumberedPitchClass(9)

            ::

                >>> pitch_class + abjad.NumberedInterval(1)
                NumberedPitchClass(10)

            ::

                >>> pitch_class + abjad.NumberedInterval(2)
                NumberedPitchClass(11)

            ::

                >>> pitch_class + abjad.NumberedInterval(3)
                NumberedPitchClass(0)

        Returns new numbered pitch-class.
        '''
        from abjad.tools import pitchtools
        interval = pitchtools.NumberedInterval(argument)
        return type(self)(self.number + interval.number % 12)
Пример #6
0
def label_leaves_in_expr_with_numbered_interval_classes(
        expr, markup_direction=Up):
    r"""Label leaves in `expr` with numbered interval classes:

    ::

        >>> notes = scoretools.make_notes(
        ...     [0, 25, 11, -4, -14, -13, 9, 10, 6, 5],
        ...     [Duration(1, 8)],
        ...     )
        >>> staff = Staff(notes)
        >>> labeltools.label_leaves_in_expr_with_numbered_interval_classes(
        ...     staff)

    ..  doctest::

        >>> print(format(staff))
        \new Staff {
            c'8 ^ \markup { +1 }
            cs'''8 ^ \markup { -2 }
            b'8 ^ \markup { -3 }
            af8 ^ \markup { -10 }
            bf,8 ^ \markup { +1 }
            b,8 ^ \markup { +10 }
            a'8 ^ \markup { +1 }
            bf'8 ^ \markup { -4 }
            fs'8 ^ \markup { -1 }
            f'8
        }

    ::

        >>> show(staff) # doctest: +SKIP

    Returns none.
    """

    for note in iterate(expr).by_class(scoretools.Note):
        logical_voice_iterator = iterate(note).by_logical_voice_from_component(
            scoretools.Leaf, )
        try:
            next(logical_voice_iterator)
            next_leaf = next(logical_voice_iterator)
            if isinstance(next_leaf, scoretools.Note):
                mdi = note.written_pitch - next_leaf.written_pitch
                mci = pitchtools.NumberedInterval(mdi)
                mcic = pitchtools.NumberedIntervalClass(mci)
                markup = markuptools.Markup(mcic, markup_direction)
                attach(markup, note)
        except StopIteration:
            pass
Пример #7
0
    def __add__(self, expr):
        r'''Adds `expr` to numbered pitch-class.

        ::

            >>> pitch_class = pitchtools.NumberedPitchClass(9)
            >>> interval = pitchtools.NumberedInterval(4)
            >>> pitch_class + interval
            NumberedPitchClass(1)

        Returns new numbered pitch-class.
        '''
        from abjad.tools import pitchtools
        interval = pitchtools.NumberedInterval(expr)
        return type(self)(self.pitch_class_number + interval.number % 12)
Пример #8
0
    def __sub__(self, argument):
        r'''Subtracts `argument` from numbered pitch.

        ..  container:: example

            >>> abjad.NumberedPitch(12) - abjad.NumberedPitch(12)
            NumberedInterval(0)

            >>> abjad.NumberedPitch(12) - abjad.NumberedPitch(13)
            NumberedInterval(1)

            >>> abjad.NumberedPitch(13) - abjad.NumberedPitch(12)
            NumberedInterval(-1)

        Returns numbered interval.
        '''
        from abjad.tools import pitchtools
        if isinstance(argument, type(self)):
            return pitchtools.NumberedInterval.from_pitch_carriers(
                self, argument)
        interval = pitchtools.NumberedInterval(argument)
        interval = -interval
        return interval.transpose(self)
Пример #9
0
def instantiate_pitch_and_interval_test_collection():
    r'''Instantiate pitch and interval test collection:

    ::

        >>> for x in pitchtools.instantiate_pitch_and_interval_test_collection(): x
        ...
        NumberedInversionEquivalentIntervalClass(1)
        NamedInversionEquivalentIntervalClass('+M2')
        NumberedInterval(1)
        NumberedIntervalClass(1)
        NamedInterval('+M2')
        NamedIntervalClass('+M2')
        NamedPitch('c')
        NamedPitchClass('c')
        NumberedPitch(1)
        NumberedPitchClass(1)

    Use to test pitch and interval interface consistency.

    Returns list.
    '''
    from abjad.tools import pitchtools

    result = []
    result.append(pitchtools.NumberedInversionEquivalentIntervalClass(1))
    result.append(pitchtools.NamedInversionEquivalentIntervalClass('M2'))
    result.append(pitchtools.NumberedInterval(1))
    result.append(pitchtools.NumberedIntervalClass(1))
    result.append(pitchtools.NamedInterval('M2'))
    result.append(pitchtools.NamedIntervalClass('M2'))
    result.append(pitchtools.NamedPitch('c'))
    result.append(pitchtools.NamedPitchClass('c'))
    result.append(pitchtools.NumberedPitch(1))
    result.append(pitchtools.NumberedPitchClass(1))
    return result
Пример #10
0
def transpose_pitch_carrier_by_interval(pitch_carrier, interval):
    '''Transpose `pitch_carrier` by named `interval`:

    ::

        >>> chord = Chord("<c' e' g'>4")

    ::

        >>> pitchtools.transpose_pitch_carrier_by_interval(
        ...     chord, '+m2')
        Chord("<df' f' af'>4")

    Transpose `pitch_carrier` by numbered `interval`:

    ::

        >>> chord = Chord("<c' e' g'>4")

    ::

        >>> pitchtools.transpose_pitch_carrier_by_interval(chord, 1)
        Chord("<cs' f' af'>4")

    Returns non-pitch-carrying input unchaged:

    ::

        >>> rest = Rest('r4')

    ::

        >>> pitchtools.transpose_pitch_carrier_by_interval(rest, 1)
        Rest('r4')

    Return `pitch_carrier`.
    '''
    from abjad.tools import pitchtools
    from abjad.tools import scoretools

    def _transpose_pitch_by_named_interval(pitch, mdi):
        pitch_number = pitch.pitch_number + mdi.semitones
        diatonic_pitch_class_number = \
            (pitch.diatonic_pitch_class_number + mdi.staff_spaces) % 7
        diatonic_pitch_class_name = \
            pitchtools.PitchClass._diatonic_pitch_class_number_to_diatonic_pitch_class_name[
                diatonic_pitch_class_number]
        named_pitch = pitchtools.NamedPitch(pitch_number,
                                            diatonic_pitch_class_name)
        return type(pitch)(named_pitch)

    def _transpose_pitch_carrier_by_named_interval(pitch_carrier,
                                                   named_interval):
        mdi = pitchtools.NamedInterval(named_interval)
        if isinstance(pitch_carrier, pitchtools.Pitch):
            return _transpose_pitch_by_named_interval(pitch_carrier, mdi)
        elif isinstance(pitch_carrier, scoretools.Note):
            new_note = copy.copy(pitch_carrier)
            new_pitch = _transpose_pitch_by_named_interval(
                pitch_carrier.written_pitch, mdi)
            new_note.written_pitch = new_pitch
            return new_note
        elif isinstance(pitch_carrier, scoretools.Chord):
            new_chord = copy.copy(pitch_carrier)
            for new_nh, old_nh in \
                zip(new_chord.note_heads, pitch_carrier.note_heads):
                new_pitch = _transpose_pitch_by_named_interval(
                    old_nh.written_pitch, mdi)
                new_nh.written_pitch = new_pitch
            return new_chord
        else:
            return pitch_carrier

    def _transpose_pitch_carrier_by_numbered_interval(pitch_carrier,
                                                      numbered_interval):
        mci = pitchtools.NumberedInterval(numbered_interval)
        if isinstance(pitch_carrier, pitchtools.Pitch):
            number = pitch_carrier.pitch_number + mci.semitones
            return type(pitch_carrier)(number)
        elif isinstance(pitch_carrier, numbers.Number):
            pitch_carrier = pitchtools.NumberedPitch(pitch_carrier)
            result = _transpose_pitch_carrier_by_numbered_interval(
                pitch_carrier, mci)
            return result.pitch_number
        elif isinstance(pitch_carrier, scoretools.Note):
            new_note = copy.copy(pitch_carrier)
            number = pitchtools.NumberedPitch(
                pitch_carrier.written_pitch).pitch_number
            number += mci.number
            new_pitch = pitchtools.NamedPitch(number)
            new_note.written_pitch = new_pitch
            return new_note
        elif isinstance(pitch_carrier, scoretools.Chord):
            new_chord = copy.copy(pitch_carrier)
            pairs = zip(new_chord.note_heads, pitch_carrier.note_heads)
            for new_nh, old_nh in pairs:
                number = \
                    pitchtools.NumberedPitch(old_nh.written_pitch).pitch_number
                number += mci.number
                new_pitch = pitchtools.NamedPitch(number)
                new_nh.written_pitch = new_pitch
            return new_chord
        else:
            return pitch_carrier

    diatonic_types = (pitchtools.NamedInterval, str)
    if isinstance(interval, diatonic_types):
        interval = \
            pitchtools.NamedInterval(interval)
        return _transpose_pitch_carrier_by_named_interval(
            pitch_carrier, interval)
    else:
        interval = \
            pitchtools.NumberedInterval(interval)
        return _transpose_pitch_carrier_by_numbered_interval(
            pitch_carrier, interval)