Beispiel #1
0
 def _initialize_with_mode_name(self, mode_name):
     mdi_segment = []
     m2 = pitchtools.NamedInterval('minor', 2)
     M2 = pitchtools.NamedInterval('major', 2)
     A2 = pitchtools.NamedInterval('augmented', 2)
     dorian = [M2, m2, M2, M2, M2, m2, M2]
     if mode_name == 'dorian':
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, 0))
     elif mode_name == 'phrygian':
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -1))
     elif mode_name == 'lydian':
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -2))
     elif mode_name == 'mixolydian':
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -3))
     elif mode_name in ('aeolian', 'minor', 'natural minor'):
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -4))
     elif mode_name == 'locrian':
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -5))
     elif mode_name in ('ionian', 'major'):
         mdi_segment.extend(sequencetools.rotate_sequence(dorian, -6))
     elif mode_name == 'melodic minor':
         mdi_segment.extend([M2, m2, M2, M2, M2, M2, m2])
     elif mode_name == 'harmonic minor':
         mdi_segment.extend([M2, m2, M2, M2, m2, A2, m2])
     else:
         message = 'unknown mode name: {!r}.'
         message = message.format(mode_name)
         raise ValueError(message)
     return pitchtools.IntervalSegment(
         items=mdi_segment,
         item_class=pitchtools.NamedInterval,
         )
Beispiel #2
0
 def _initialize_triad(quality_string):
     if quality_string == 'major':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('perfect', 5),
             ]
     elif quality_string == 'minor':
         intervals = [
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('perfect', 5),
             ]
     elif quality_string == 'diminished':
         intervals = [
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('diminished', 5),
             ]
     elif quality_string == 'augmented':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('augmented', 5),
             ]
     else:
         message = 'unacceptable quality string: {!r}.'
         message = message.format(quality_string)
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('perfect', 1))
     return intervals
Beispiel #3
0
 def __lt__(self, arg):
     r'''Is true when `arg` is a named interval class with a number greater
     than that of this named interval.
     '''
     from abjad.tools import pitchtools
     if isinstance(arg, type(self)):
         if self.number == arg.number:
             return pitchtools.NamedInterval(self).semitones < \
                 pitchtools.NamedInterval(arg).semitones
         return self.number < arg.number
     return False
 def _initialize_ninth(quality_string):
     if quality_string == 'dominant':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('P5'),
             pitchtools.NamedInterval('m7'),
             pitchtools.NamedInterval('M9'),
         ]
     else:
         message = 'unacceptable quality string.'
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('P1'))
     return intervals
Beispiel #5
0
 def _initialize_ninth(quality_string):
     if quality_string == 'dominant':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('perfect', 5),
             pitchtools.NamedInterval('minor', 7),
             pitchtools.NamedInterval('major', 9),
             ]
     else:
         message = 'unacceptable quality string.'
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('perfect', 1))
     return intervals
 def __init__(
     self,
     interval=None,
     overrides=None,
 ):
     Spanner.__init__(
         self,
         overrides=overrides,
     )
     if interval is not None:
         interval = pitchtools.NamedInterval(interval)
     self._interval = interval
Beispiel #7
0
    def __add__(self, interval):
        r'''Adds named pitch to `interval`.

        ::

            >>> pitch + pitchtools.NamedInterval('+M2')
            NamedPitch("ds''")

        Returns new named pitch.
        '''
        from abjad.tools import pitchtools
        interval = pitchtools.NamedInterval(interval)
        return pitchtools.transpose_pitch_carrier_by_interval(
            self, interval)
Beispiel #8
0
    def transpose(self, expr):
        r'''Transposes named pitch-class by named interval `expr`.

        ::

            >>> named_interval = pitchtools.NamedInterval('major', 2)
            >>> pitchtools.NamedPitchClass('cs').transpose(named_interval)
            NamedPitchClass('ds')

        Returns new named pitch-class.
        '''
        from abjad.tools import pitchtools
        named_interval = pitchtools.NamedInterval(expr)
        pitch = pitchtools.NamedPitch(self, 4)
        transposed_pitch = \
            pitchtools.transpose_pitch_carrier_by_interval(
                pitch, named_interval)
        return type(self)(transposed_pitch)
Beispiel #9
0
 def __init__(self, root=None, *args):
     from abjad.tools import tonalanalysistools
     root = root or 'c'
     root = pitchtools.NamedPitchClass(root)
     chord_quality = tonalanalysistools.RootlessChordClass(*args)
     npcs = []
     for hdi in chord_quality:
         mdi = pitchtools.NamedInterval(hdi)
         npc = root + mdi
         npcs.append(npc)
     bass = npcs[0]
     PitchClassSet.__init__(
         self,
         items=npcs,
         item_class=pitchtools.NamedPitchClass,
     )
     self._root = root
     self._chord_quality = chord_quality
     self._bass = bass
Beispiel #10
0
    def transpose(self, expr):
        r'''Transposes named pitch by `expr`.

        ::

            >>> NamedPitch("c'").transpose('m2')
            NamedPitch("df'")

        ::

            >>> NamedPitch("c'").transpose('-M2')
            NamedPitch('bf')

        Returns new named pitch.
        '''
        from abjad.tools import pitchtools
        named_interval = pitchtools.NamedInterval(expr)
        transposed_pitch = pitchtools.transpose_pitch_carrier_by_interval(
            self, named_interval)
        return type(self)(transposed_pitch)
Beispiel #11
0
 def _set_ascending_named_diatonic_pitches_on_logical_ties_in_expr(
     self, expr):
     from abjad.tools import pitchtools
     from abjad.tools import scoretools
     dicg = self.named_interval_class_segment
     length = len(dicg)
     octave_number = 4
     pitch = pitchtools.NamedPitch(self[0], octave_number)
     for i, logical_tie in enumerate(iterate(expr).by_logical_tie()):
         if isinstance(logical_tie[0], scoretools.Note):
             for note in logical_tie:
                 note.written_pitch = pitch
         elif isinstance(logical_tie[0], scoretools.Chord):
             for chord in logical_tie:
                 chord.written_pitches = [pitch]
         else:
             pass
         dic = dicg[i % length]
         ascending_mdi = pitchtools.NamedInterval(dic.quality_string, dic.number)
         pitch += ascending_mdi
Beispiel #12
0
 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
Beispiel #13
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
Beispiel #14
0
    def transpose(self, n=0):
        r'''Transposes named pitch-class by index named interval `n`.

        ..  container:: example

            >>> interval = abjad.NamedInterval('-M2')
            >>> abjad.NamedPitchClass('cs').transpose(interval)
            NamedPitchClass('b')

            >>> interval = abjad.NamedInterval('P1')
            >>> abjad.NamedPitchClass('cs').transpose(interval)
            NamedPitchClass('cs')

            >>> interval = abjad.NamedInterval('+M2')
            >>> abjad.NamedPitchClass('cs').transpose(interval)
            NamedPitchClass('ds')

        Returns new named pitch-class.
        '''
        from abjad.tools import pitchtools
        interval = pitchtools.NamedInterval(n)
        pitch = pitchtools.NamedPitch((self.name, 4))
        pitch = interval.transpose(pitch)
        return type(self)(pitch)
Beispiel #15
0
    def to_named_interval(self, staff_positions):
        r'''Changes numbered interval to named interval that encompasses
        `staff_positions`.

        ..  container:: example

            >>> abjad.NumberedInterval(0).to_named_interval(0)
            NamedInterval('aug0')

            >>> abjad.NumberedInterval(0).to_named_interval(1)
            NamedInterval('P1')

            >>> abjad.NumberedInterval(0).to_named_interval(2)
            NamedInterval('+dim2')

        ..  container:: example

            >>> abjad.NumberedInterval(1).to_named_interval(1)
            NamedInterval('+aug1')

            >>> abjad.NumberedInterval(1).to_named_interval(2)
            NamedInterval('+m2')

        ..  container:: example

            >>> abjad.NumberedInterval(-1).to_named_interval(1)
            NamedInterval('-aug1')

            >>> abjad.NumberedInterval(-1).to_named_interval(2)
            NamedInterval('-m2')

        ..  container:: example

            >>> abjad.NumberedInterval(2).to_named_interval(2)
            NamedInterval('+M2')

        Returns named interval.
        '''
        from abjad.tools import pitchtools
        direction_number = mathtools.sign(self.number)
        quality_string = None
        if staff_positions == 1:
            if self.number % 12 == 11:
                quality_string = 'augmented'
            elif self.number % 12 == 0:
                quality_string = 'perfect'
            elif self.number % 12 == 1:
                quality_string = 'augmented'
            if not direction_number == 0:
                staff_positions *= direction_number
            if quality_string is None:
                # TODO: handle double-augmented named intervals
                return pitchtools.NamedInterval(self.number)
            named_interval = pitchtools.NamedInterval.from_quality_and_number(
                quality_string,
                staff_positions,
                )
            return named_interval
        named_interval_class_number = staff_positions % 7
        numbered_interval_class_number = abs(self.number) % 12
        if named_interval_class_number == 0:
            if numbered_interval_class_number == 9:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 10:
                quality_string = 'minor'
            elif numbered_interval_class_number == 11:
                quality_string = 'major'
            elif numbered_interval_class_number == 0:
                quality_string = 'augmented'
        elif named_interval_class_number == 1:
            if numbered_interval_class_number == 11:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 0:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 1:
                quality_string = 'augmented'
        elif named_interval_class_number == 2:
            if numbered_interval_class_number == 0:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 1:
                quality_string = 'minor'
            elif numbered_interval_class_number == 2:
                quality_string = 'major'
            elif numbered_interval_class_number == 3:
                quality_string = 'augmented'
        elif named_interval_class_number == 3:
            if numbered_interval_class_number == 2:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 3:
                quality_string = 'minor'
            elif numbered_interval_class_number == 4:
                quality_string = 'major'
            elif numbered_interval_class_number == 5:
                quality_string = 'augmented'
        elif named_interval_class_number == 4:
            if numbered_interval_class_number == 4:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 5:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 6:
                quality_string = 'augmented'
        elif named_interval_class_number == 5:
            if numbered_interval_class_number == 6:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 7:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 8:
                quality_string = 'augmented'
        elif named_interval_class_number == 6:
            if numbered_interval_class_number == 7:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 8:
                quality_string = 'minor'
            elif numbered_interval_class_number == 9:
                quality_string = 'major'
            elif numbered_interval_class_number == 10:
                quality_string = 'augmented'
        elif named_interval_class_number == 7:
            if numbered_interval_class_number == 9:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 10:
                quality_string = 'minor'
            elif numbered_interval_class_number == 11:
                quality_string = 'major'
            elif numbered_interval_class_number == 0:
                quality_string = 'augmented'
        elif named_interval_class_number == 8:
            if numbered_interval_class_number == 11:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 0:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 1:
                quality_string = 'augmented'
        if not direction_number == 0:
            staff_positions *= direction_number
        if quality_string is None:
            # TODO: It is possible to for quality string to *never* get set to
            #       anything, generally during inversion with double-sharps or
            #       double-flats. This suite provides a sane result.
            #       Don't remove it - fix whatever's allowing quality string to
            #       remain unset.
            return pitchtools.NamedInterval(self.number)
        named_interval = pitchtools.NamedInterval.from_quality_and_number(
            quality_string,
            staff_positions,
            )
        return named_interval
Beispiel #16
0
 def _initialize_seventh(quality_string):
     if quality_string == 'dominant':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('perfect', 5),
             pitchtools.NamedInterval('minor', 7),
             ]
     elif quality_string == 'major':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('perfect', 5),
             pitchtools.NamedInterval('major', 7),
             ]
     elif quality_string == 'minor':
         intervals = [
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('perfect', 5),
             pitchtools.NamedInterval('minor', 7),
             ]
     elif quality_string in ('diminished', 'fully diminished'):
         intervals = [
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('diminished', 5),
             pitchtools.NamedInterval('diminished', 7),
             ]
     elif quality_string == 'half diminished':
         intervals = [
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('perfect', 5),
             pitchtools.NamedInterval('diminished', 7),
             ]
     else:
        message = 'unaccpetable quality string.'
        raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('perfect', 1))
     return intervals
Beispiel #17
0
def spell_numbered_interval_number(
    named_interval_number,
    numbered_interval_number,
):
    '''Spell `numbered_interval_number` according to `named_interval_number`:

    ::

        >>> pitchtools.spell_numbered_interval_number(2, 1)
        NamedInterval('+m2')

    Returns named interval.
    '''
    from abjad.tools import pitchtools

    if not isinstance(numbered_interval_number, int):
        message = 'can not determine diatonic interval from float.'
        raise TypeError(message)

    direction_number = mathtools.sign(numbered_interval_number)

    if named_interval_number == 1:
        if numbered_interval_number % 12 == 11:
            quality_string = 'augmented'
        elif numbered_interval_number % 12 == 0:
            quality_string = 'perfect'
        elif numbered_interval_number % 12 == 1:
            quality_string = 'augmented'
        if not direction_number == 0:
            named_interval_number *= direction_number
        named_interval = pitchtools.NamedInterval(quality_string,
                                                  named_interval_number)
        return named_interval

    named_interval_class_number = named_interval_number % 7
    numbered_interval_class_number = abs(numbered_interval_number) % 12

    if named_interval_class_number == 0:
        if numbered_interval_class_number == 9:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 10:
            quality_string = 'minor'
        elif numbered_interval_class_number == 11:
            quality_string = 'major'
        elif numbered_interval_class_number == 0:
            quality_string = 'augmented'
    elif named_interval_class_number == 1:
        if numbered_interval_class_number == 11:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 0:
            quality_string = 'perfect'
        elif numbered_interval_class_number == 1:
            quality_string = 'augmented'
    elif named_interval_class_number == 2:
        if numbered_interval_class_number == 0:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 1:
            quality_string = 'minor'
        elif numbered_interval_class_number == 2:
            quality_string = 'major'
        elif numbered_interval_class_number == 3:
            quality_string = 'augmented'
    elif named_interval_class_number == 3:
        if numbered_interval_class_number == 2:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 3:
            quality_string = 'minor'
        elif numbered_interval_class_number == 4:
            quality_string = 'major'
        elif numbered_interval_class_number == 5:
            quality_string = 'augmented'
    elif named_interval_class_number == 4:
        if numbered_interval_class_number == 4:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 5:
            quality_string = 'perfect'
        elif numbered_interval_class_number == 6:
            quality_string = 'augmented'
    elif named_interval_class_number == 5:
        if numbered_interval_class_number == 6:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 7:
            quality_string = 'perfect'
        elif numbered_interval_class_number == 8:
            quality_string = 'augmented'
    elif named_interval_class_number == 6:
        if numbered_interval_class_number == 7:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 8:
            quality_string = 'minor'
        elif numbered_interval_class_number == 9:
            quality_string = 'major'
        elif numbered_interval_class_number == 10:
            quality_string = 'augmented'
    elif named_interval_class_number == 7:
        if numbered_interval_class_number == 9:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 10:
            quality_string = 'minor'
        elif numbered_interval_class_number == 11:
            quality_string = 'major'
        elif numbered_interval_class_number == 0:
            quality_string = 'augmented'
    elif named_interval_class_number == 8:
        if numbered_interval_class_number == 11:
            quality_string = 'diminished'
        elif numbered_interval_class_number == 0:
            quality_string = 'perfect'
        elif numbered_interval_class_number == 1:
            quality_string = 'augmented'

    if not direction_number == 0:
        named_interval_number *= direction_number

    named_interval = pitchtools.NamedInterval(quality_string,
                                              named_interval_number)

    return named_interval
Beispiel #18
0
 def _initialize_augmented_sixth(quality_string):
     if quality_string == 'French':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('major', 2),
             pitchtools.NamedInterval('major', 3),
             ]
     elif quality_string == 'German':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('minor', 3),
             pitchtools.NamedInterval('augmented', 2),
             ]
     elif quality_string == 'Italian':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('perfect', 1),
             pitchtools.NamedInterval('augmented', 4),
             ]
     elif quality_string == 'Swiss':
         intervals = [
             pitchtools.NamedInterval('major', 3),
             pitchtools.NamedInterval('augmented', 2),
             pitchtools.NamedInterval('minor', 3),
             ]
     else:
         message = 'unaccpetable quality string.'
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('perfect', 1))
     return intervals
Beispiel #19
0
 def _initialize_augmented_sixth(quality_string):
     if quality_string == 'French':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('M2'),
             pitchtools.NamedInterval('M3'),
         ]
     elif quality_string == 'German':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('m3'),
             pitchtools.NamedInterval('aug2'),
         ]
     elif quality_string == 'Italian':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('P1'),
             pitchtools.NamedInterval('aug4'),
         ]
     elif quality_string == 'Swiss':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('aug2'),
             pitchtools.NamedInterval('m3'),
         ]
     else:
         message = 'unaccpetable quality string.'
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('P1'))
     return intervals
Beispiel #20
0
 def _initialize_seventh(quality_string):
     if quality_string == 'dominant':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('P5'),
             pitchtools.NamedInterval('m7'),
         ]
     elif quality_string == 'major':
         intervals = [
             pitchtools.NamedInterval('M3'),
             pitchtools.NamedInterval('P5'),
             pitchtools.NamedInterval('M7'),
         ]
     elif quality_string == 'minor':
         intervals = [
             pitchtools.NamedInterval('m3'),
             pitchtools.NamedInterval('P5'),
             pitchtools.NamedInterval('m7'),
         ]
     elif quality_string in ('diminished', 'fully diminished'):
         intervals = [
             pitchtools.NamedInterval('m3'),
             pitchtools.NamedInterval('dim5'),
             pitchtools.NamedInterval('dim7'),
         ]
     elif quality_string == 'half diminished':
         intervals = [
             pitchtools.NamedInterval('m3'),
             pitchtools.NamedInterval('P5'),
             pitchtools.NamedInterval('dim7'),
         ]
     else:
         message = 'unacceptable quality string.'
         raise ValueError(message)
     intervals.insert(0, pitchtools.NamedInterval('P1'))
     return intervals
Beispiel #21
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)
Beispiel #22
0
    def to_named_interval(self, staff_positions):
        r'''Changes numbered interval to named interval that encompasses
        `staff_positions`.

        ..  container:: example

            ::

                >>> numbered_interval = pitchtools.NumberedInterval(1)
                >>> numbered_interval.to_named_interval(2)
                NamedInterval('+m2')

        Returns named interval.
        '''
        from abjad.tools import pitchtools
        direction_number = mathtools.sign(self.number)
        if staff_positions == 1:
            quality_string = None
            if self.number % 12 == 11:
                quality_string = 'augmented'
            elif self.number % 12 == 0:
                quality_string = 'perfect'
            elif self.number % 12 == 1:
                quality_string = 'augmented'
            if not direction_number == 0:
                staff_positions *= direction_number
            if quality_string is None:
                # TODO: handle double-augmented named intervals
                return pitchtools.NamedInterval(self.number)
            named_interval = pitchtools.NamedInterval(quality_string,
                                                      staff_positions)
            return named_interval
        named_interval_class_number = staff_positions % 7
        numbered_interval_class_number = abs(self.number) % 12
        if named_interval_class_number == 0:
            if numbered_interval_class_number == 9:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 10:
                quality_string = 'minor'
            elif numbered_interval_class_number == 11:
                quality_string = 'major'
            elif numbered_interval_class_number == 0:
                quality_string = 'augmented'
        elif named_interval_class_number == 1:
            if numbered_interval_class_number == 11:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 0:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 1:
                quality_string = 'augmented'
        elif named_interval_class_number == 2:
            if numbered_interval_class_number == 0:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 1:
                quality_string = 'minor'
            elif numbered_interval_class_number == 2:
                quality_string = 'major'
            elif numbered_interval_class_number == 3:
                quality_string = 'augmented'
        elif named_interval_class_number == 3:
            if numbered_interval_class_number == 2:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 3:
                quality_string = 'minor'
            elif numbered_interval_class_number == 4:
                quality_string = 'major'
            elif numbered_interval_class_number == 5:
                quality_string = 'augmented'
        elif named_interval_class_number == 4:
            if numbered_interval_class_number == 4:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 5:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 6:
                quality_string = 'augmented'
        elif named_interval_class_number == 5:
            if numbered_interval_class_number == 6:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 7:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 8:
                quality_string = 'augmented'
        elif named_interval_class_number == 6:
            if numbered_interval_class_number == 7:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 8:
                quality_string = 'minor'
            elif numbered_interval_class_number == 9:
                quality_string = 'major'
            elif numbered_interval_class_number == 10:
                quality_string = 'augmented'
        elif named_interval_class_number == 7:
            if numbered_interval_class_number == 9:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 10:
                quality_string = 'minor'
            elif numbered_interval_class_number == 11:
                quality_string = 'major'
            elif numbered_interval_class_number == 0:
                quality_string = 'augmented'
        elif named_interval_class_number == 8:
            if numbered_interval_class_number == 11:
                quality_string = 'diminished'
            elif numbered_interval_class_number == 0:
                quality_string = 'perfect'
            elif numbered_interval_class_number == 1:
                quality_string = 'augmented'
        if not direction_number == 0:
            staff_positions *= direction_number
        named_interval = pitchtools.NamedInterval(
            quality_string,
            staff_positions,
        )
        return named_interval