コード例 #1
0
ファイル: Pitch.py プロジェクト: aarongrisez/abjad
 def __init__(self, argument, accidental=None, arrow=None, octave=None):
     import abjad
     if isinstance(argument, str):
         match = constants._comprehensive_pitch_name_regex.match(argument)
         if not match:
             match = constants._comprehensive_pitch_class_name_regex.match(
                 argument)
         if not match:
             message = 'can not instantiate {} from {!r}.'
             message = message.format(type(self).__name__, argument)
             raise ValueError(message)
         group_dict = match.groupdict()
         _dpc_name = group_dict['diatonic_pc_name'].lower()
         _dpc_number = constants._diatonic_pc_name_to_diatonic_pc_number[
             _dpc_name]
         _alteration = abjad.Accidental(
             group_dict['comprehensive_accidental']).semitones
         _octave = abjad.Octave(group_dict.get('comprehensive_octave',
                                               '')).number
         self._from_named_parts(_dpc_number, _alteration, _octave)
     elif isinstance(argument, numbers.Number):
         self._from_number(argument)
     elif isinstance(argument, (abjad.Pitch, abjad.PitchClass)):
         self._from_pitch_or_pitch_class(argument)
     elif isinstance(argument, tuple) and len(argument) == 2:
         _pitch_class = abjad.NamedPitchClass(argument[0])
         _octave = abjad.Octave(argument[1])
         self._from_named_parts(
             _pitch_class._get_diatonic_pc_number(),
             _pitch_class._get_alteration(),
             _octave.number,
         )
     elif hasattr(argument, 'written_pitch'):
         self._from_pitch_or_pitch_class(argument.written_pitch)
     elif isinstance(argument, abjad.Chord) and len(argument.note_heads):
         self._from_pitch_or_pitch_class(argument.note_heads[0])
     else:
         message = 'can not instantiate {} from {!r}.'
         message = message.format(type(self).__name__, argument)
         raise ValueError(message)
     if accidental is not None:
         accidental = abjad.Accidental(accidental)
         self._pitch_class = type(self._pitch_class)(
             self._pitch_class,
             accidental=accidental,
         )
     if arrow is not None:
         self._pitch_class = type(self._pitch_class)(
             self._pitch_class,
             arrow=arrow,
         )
     if octave is not None:
         octave = abjad.Octave(octave)
         self._octave = octave
コード例 #2
0
 def _from_named_parts(self, dpc_number, alteration, octave):
     import abjad
     dpc_name = constants._diatonic_pc_number_to_diatonic_pc_name[dpc_number]
     accidental = abjad.Accidental(alteration)
     octave = abjad.Octave(octave)
     self._octave = octave
     self._pitch_class = abjad.NamedPitchClass(dpc_name + str(accidental))
コード例 #3
0
    def __init__(self, argument):
        import abjad

        if isinstance(argument, str):
            match = constants._comprehensive_pitch_name_regex.match(argument)
            if not match:
                match = constants._comprehensive_pitch_class_name_regex.match(
                    argument)
            if not match:
                message = "can not instantiate {} from {!r}."
                message = message.format(type(self).__name__, argument)
                raise ValueError(message)
            group_dict = match.groupdict()
            dpc_name = group_dict["diatonic_pc_name"].lower()
            dpc_number = constants._diatonic_pc_name_to_diatonic_pc_number[
                dpc_name]
            alteration = abjad.Accidental(
                group_dict["comprehensive_accidental"]).semitones
            self._from_named_parts(dpc_number, alteration)
        elif isinstance(argument, numbers.Number):
            self._from_number(argument)
        elif isinstance(argument, (abjad.Pitch, abjad.PitchClass)):
            self._from_pitch_or_pitch_class(argument)
        else:
            try:
                pitch = abjad.NamedPitch(argument)
                self._from_pitch_or_pitch_class(pitch)
            except Exception:
                message = "can not instantiate {} from {!r}."
                message = message.format(type(self).__name__, argument)
                raise ValueError(message)
コード例 #4
0
    def _apply_accidental(self, accidental):
        import abjad

        name = self._get_diatonic_pc_name()
        name += str(self.accidental + abjad.Accidental(accidental))
        name += self.octave.ticks
        return type(self)(name)
コード例 #5
0
    def _get_lilypond_format(self):
        import abjad

        return "{}{!s}".format(
            self._get_diatonic_pc_name(),
            abjad.Accidental(self._get_alteration()),
        )
コード例 #6
0
    def _apply_accidental(self, accidental=None):
        import abjad

        accidental = abjad.Accidental(accidental)
        new_accidental = self.accidental + accidental
        new_name = self._get_diatonic_pc_name() + str(new_accidental)
        return type(self)(new_name)
コード例 #7
0
ファイル: NamedPitchClass.py プロジェクト: aarongrisez/abjad
 def _from_pitch_or_pitch_class(self, pitch_or_pitch_class):
     import abjad
     if isinstance(pitch_or_pitch_class, Pitch):
         pitch_or_pitch_class = pitch_or_pitch_class.pitch_class
     self._diatonic_pc_number = pitch_or_pitch_class._get_diatonic_pc_number()
     self._accidental = abjad.Accidental(
         pitch_or_pitch_class._get_alteration(),
         arrow=pitch_or_pitch_class.arrow,
         )
コード例 #8
0
 def _initialize_by_pitch_name(self, argument):
     import abjad
     match = abjad.Pitch._pitch_name_regex.match(argument.lower())
     assert match is not None, repr(match)
     groups = match.groups()
     diatonic_pitch_class_name = groups[0]
     abbreviation = groups[1]
     accidental = abjad.Accidental(abbreviation)
     self._alteration = accidental.semitones
     self._diatonic_pitch_class_number = \
         self._diatonic_pitch_class_name_to_diatonic_pitch_class_number[
             diatonic_pitch_class_name]
コード例 #9
0
    def simplify(self):
        """
        Reduce alteration to between -2 and 2 while maintaining identical pitch
        number.

            >>> abjad.NamedPitch("cssqs'").simplify()
            NamedPitch("dqs'")

            >>> abjad.NamedPitch("cfffqf'").simplify()
            NamedPitch('aqf')

            >>> float(abjad.NamedPitch("cfffqf'").simplify()) == float(NamedPitch('aqf'))
            True

        ..  note:: LilyPond by default only supports accidentals from
                   double-flat to double-sharp.

        Returns named pitch.
        """
        import abjad

        alteration = self._get_alteration()
        if abs(alteration) <= 2:
            return self
        diatonic_pc_number = self._get_diatonic_pc_number()
        octave = int(self.octave)
        while alteration > 2:
            step_size = 2
            if diatonic_pc_number == 2:  # e to f
                step_size = 1
            elif diatonic_pc_number == 6:  # b to c
                step_size = 1
                octave += 1
            diatonic_pc_number = (diatonic_pc_number + 1) % 7
            alteration -= step_size
        while alteration < -2:
            step_size = 2
            if diatonic_pc_number == 3:  # f to e
                step_size = 1
            elif diatonic_pc_number == 0:  # c to b
                step_size = 1
                octave -= 1
            diatonic_pc_number = (diatonic_pc_number - 1) % 7
            alteration += step_size
        diatonic_pc_name = constants._diatonic_pc_number_to_diatonic_pc_name[
            diatonic_pc_number]
        accidental = abjad.Accidental(alteration)
        octave = abjad.Octave(octave)
        pitch_name = "{}{!s}{!s}".format(diatonic_pc_name, accidental, octave)
        return type(self)(pitch_name, arrow=self.arrow)
コード例 #10
0
ファイル: ScaleDegree.py プロジェクト: tchiwinpiti/abjad
    def from_accidental_and_number(accidental, number):
        r'''Makes scale degree from `accidental` and `number`.

        ..  container:: example

            >>> class_ = abjad.tonalanalysistools.ScaleDegree
            >>> class_.from_accidental_and_number('sharp', 4)
            ScaleDegree('#4')

        Returns new scale degree.
        '''
        import abjad
        accidental = abjad.Accidental(accidental)
        string = '{}{}'.format(accidental.symbol, number)
        return ScaleDegree(string=string)
コード例 #11
0
ファイル: NamedPitch.py プロジェクト: tchiwinpiti/abjad
    def from_pitch_number(
        class_,
        pitch_number,
        diatonic_pitch_class_name,
    ):
        r'''Makes named pitch from `pitch_number`.

        ..  container:: example

            >>> abjad.NamedPitch.from_pitch_number(12, 'b')
            NamedPitch("bs'")
            >>> abjad.NamedPitch.from_pitch_number(12, 'c')
            NamedPitch("c''")
            >>> abjad.NamedPitch.from_pitch_number(12, 'd')
            NamedPitch("dff''")

        ..  container:: example

            >>> abjad.NamedPitch.from_pitch_number(13, 'b')
            NamedPitch("bss'")
            >>> abjad.NamedPitch.from_pitch_number(13, 'c')
            NamedPitch("cs''")
            >>> abjad.NamedPitch.from_pitch_number(13, 'd')
            NamedPitch("df''")

        ..  container:: example

            >>> abjad.NamedPitch.from_pitch_number(14, 'c')
            NamedPitch("css''")
            >>> abjad.NamedPitch.from_pitch_number(14, 'd')
            NamedPitch("d''")
            >>> abjad.NamedPitch.from_pitch_number(14, 'e')
            NamedPitch("eff''")

        Returns new named pitch.
        '''
        import abjad
        pc = abjad.PitchClass._diatonic_pitch_class_name_to_pitch_class_number[
            diatonic_pitch_class_name]
        nearest_neighbor = class_._to_nearest_octave(pitch_number, pc)
        semitones = pitch_number - nearest_neighbor
        accidental = abjad.Accidental(semitones)
        octave = int(math.floor((pitch_number - semitones) / 12)) + 4
        octave = abjad.Octave(octave)
        name = diatonic_pitch_class_name + str(accidental) + octave.ticks
        return class_(name)
コード例 #12
0
ファイル: NamedPitch.py プロジェクト: tchiwinpiti/abjad
    def accidental(self):
        r'''Gets accidental of named pitch.

        ..  container:: example

            >>> abjad.NamedPitch("c''").accidental
            Accidental('natural')

            >>> abjad.NamedPitch("cs''").accidental
            Accidental('sharp')

            >>> abjad.NamedPitch("df''").accidental
            Accidental('flat')

        Returns accidental.
        '''
        import abjad
        return abjad.Accidental(self._parse_name()[1])
コード例 #13
0
ファイル: ScaleDegree.py プロジェクト: tchiwinpiti/abjad
 def __init__(self, string=1):
     import abjad
     assert isinstance(string, (str, int, type(self))), repr(string)
     string = str(string)
     match = self._string_regex.match(string)
     if match is None:
         raise Exception(repr(string))
     groups = match.groups()
     accidental, roman_numeral = groups
     accidental = abjad.Accidental(accidental)
     roman_numeral = roman_numeral.upper()
     try:
         number = self._roman_numeral_string_to_scale_degree_number[
             roman_numeral]
     except KeyError:
         number = int(roman_numeral)
     self._accidental = accidental
     self._number = number
コード例 #14
0
    def transpose(self, n=0):
        """
        Transposes named pitch by index `n`.

        ..  container:: example

            Transposes C4 up a minor second:

            >>> abjad.NamedPitch("c'").transpose(n='m2')
            NamedPitch("df'")

        ..  container:: example

            Transposes C4 down a major second:

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

        Returns new named pitch.
        """
        import abjad
        interval = abjad.NamedInterval(n)
        pitch_number = self.number + interval.semitones
        diatonic_pc_number = self._get_diatonic_pc_number()
        diatonic_pc_number += interval.staff_spaces
        diatonic_pc_number %= 7
        diatonic_pc_name = \
            constants._diatonic_pc_number_to_diatonic_pc_name[
                diatonic_pc_number]
        pc = constants._diatonic_pc_name_to_pitch_class_number[
            diatonic_pc_name
            ]
        nearest_neighbor = self._to_nearest_octave(pitch_number, pc)
        semitones = pitch_number - nearest_neighbor
        accidental = abjad.Accidental(semitones)
        octave = int(math.floor((pitch_number - semitones) / 12)) + 4
        octave = abjad.Octave(octave)
        name = diatonic_pc_name + str(accidental) + octave.ticks
        return type(self)(name)
コード例 #15
0
def test_init(input_, semitones, string):
    accidental = abjad.Accidental(input_)
    assert accidental.semitones == semitones
    assert str(accidental) == string
コード例 #16
0
ファイル: NamedPitchClass.py プロジェクト: aarongrisez/abjad
 def _from_named_parts(self, dpc_number, alteration):
     import abjad
     self._diatonic_pc_number = dpc_number
     self._accidental = abjad.Accidental(alteration)
コード例 #17
0
    def _apply_accidental(self, accidental=None):
        import abjad

        accidental = abjad.Accidental(accidental)
        semitones = self.number + accidental.semitones
        return type(self)(semitones)
コード例 #18
0
def respell_accidentals(
    selection: abjad.Selection,
    *,
    include_multiples: bool = False,
    respell_by_pitch_class: bool = False,
) -> None:
    r"""Mutates an input |abjad.Selection| in place and has no return value;
    this function changes the accidentals of individual pitches of all chords
    in a container in order to avoid augmented unisons.

    Basic usage:
        To use this function, apply it to a selection that contains chords that
        have augmented unisons.

        >>> container = abjad.Container(r"c'4 r4 <ef' e'>4 g'4 <c' cs'>4 r2.")
        >>> auxjad.mutate(container[:]).respell_accidentals()
        >>> abjad.f(container)
        {
            c'4
            r4
            <ds' e'>4
            g'4
            <c' df'>4
            r2.
        }

        .. figure:: ../_images/respell_accidentals-x33afbbamt.png

    .. note::

        Auxjad automatically adds this function as an extension method to
        |abjad.mutate()|. It can thus be used from either
        :func:`auxjad.mutate()` or |abjad.mutate()|. Therefore, the two lines
        below are equivalent:

        >>> auxjad.mutate(staff[:]).respell_accidentals()
        >>> abjad.mutate(staff[:]).respell_accidentals()

    2-note chords:
        The example below shows the default spelling of 2-note chords in
        Abjad in the upper staff, and the respelt 2-note chords in the bottom
        staff.

        >>> staff1 = abjad.Staff()
        >>> staff2 = abjad.Staff()
        >>> for pitch in range(12):
        ...     staff1.append(abjad.Chord([pitch, pitch + 1], (1, 16)))
        ...     staff2.append(abjad.Chord([pitch, pitch + 1], (1, 16)))
        >>> auxjad.mutate(staff2[:]).respell_accidentals()
        >>> literal = abjad.LilyPondLiteral(r'\accidentalStyle dodecaphonic')
        >>> abjad.attach(literal, staff1)
        >>> abjad.attach(literal, staff2)
        >>> score = abjad.Score([staff1, staff2])
        >>> abjad.f(score)
        \new Score
        <<
            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' cs'>16
                <cs' d'>16
                <d' ef'>16
                <ef' e'>16
                <e' f'>16
                <f' fs'>16
                <fs' g'>16
                <g' af'>16
                <af' a'>16
                <a' bf'>16
                <bf' b'>16
                <b' c''>16
            }
            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' df'>16
                <cs' d'>16
                <d' ef'>16
                <ds' e'>16
                <e' f'>16
                <f' gf'>16
                <fs' g'>16
                <g' af'>16
                <gs' a'>16
                <a' bf'>16
                <as' b'>16
                <b' c''>16
            }
        >>

        .. figure:: ../_images/respell_accidentals-jvg032q24il.png

    augmented unissons in larger chords:
        The function looks for all augmented unissons in chords of 3 or more
        pitches:

        >>> container1 = abjad.Container(r"<a c' cs' f'>1")
        >>> container2 = abjad.Container(r"<a c' cs' f'>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals()
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <a c' cs' f'>1
            }
            {
                <a c' df' f'>1
            }
        }

        .. figure:: ../_images/respell_accidentals-gyficck05p.png

        It is not a problem if the pitches are input out of order.

        >>> container1 = abjad.Container(r"<e' cs' g' ef'>1")
        >>> container2 = abjad.Container(r"<e' cs' g' ef'>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals()
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <cs' ef' e' g'>1
            }
            {
                <cs' ds' e' g'>1
            }
        }

        .. figure:: ../_images/respell_accidentals-xbu6u6mu6qo.png

    ``include_multiples``:
        By default, this function only changes spelling for pitches that are
        1 semitone apart.

        >>> container1 = abjad.Container(r"<c' cs''>1")
        >>> container2 = abjad.Container(r"<c' cs''>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals()
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <c' cs''>1
            }
            {
                <c' cs''>1
            }
        }

        .. figure:: ../_images/respell_accidentals-uszf11qb72d.png

        To consider pitches in different octaves (thus including augmented
        unisons, augmented octaves, augmented fifteenths, etc.), call this
        function with the keyword argument ``include_multiples`` set to
        ``True``.

        >>> container1 = abjad.Container(r"<c' cs''>1")
        >>> container2 = abjad.Container(r"<c' cs''>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals(
        ...     include_multiples=True,
        ... )
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <c' cs''>1
            }
            {
                <c' df''>1
            }
        }

        .. figure:: ../_images/respell_accidentals-8am8cu2rmgi.png

    ``respell_by_pitch_class``:
        By default, when this function changes the spelling of a pitch, it does
        not change the spelling of all other pitches with the same pitch-class.

        >>> container1 = abjad.Container(r"<c' cs' cs''>1")
        >>> container2 = abjad.Container(r"<c' cs' cs''>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals()
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <c' cs' cs''>1
            }
            {
                <c' df' cs''>1
            }
        }

        .. figure:: ../_images/respell_accidentals-47d16xk6gvs.png

        To alter all pitch-classes, call this function with the keyword
        argument ``respell_by_pitch_class`` set to ``True``.

        >>> container1 = abjad.Container(r"<c' cs' cs''>1")
        >>> container2 = abjad.Container(r"<c' cs' cs''>1")
        >>> auxjad.mutate(container2[:]).respell_accidentals(
        ...     respell_by_pitch_class=True,
        ... )
        >>> staff = abjad.Staff([container1, container2])
        >>> abjad.f(staff)
        \new Staff
        {
            {
                <c' cs' cs''>1
            }
            {
                <c' df' df''>1
            }
        }

        .. figure:: ../_images/respell_accidentals-kobft0oq9sl.png
    """
    if not isinstance(selection, abjad.Selection):
        raise TypeError("argument must be 'abjad.Selection'")
    if not isinstance(respell_by_pitch_class, bool):
        raise TypeError("'respell_by_pitch_class' must be 'bool'")
    if not isinstance(include_multiples, bool):
        raise TypeError("'include_multiples' must be 'bool'")

    for leaf in selection.leaves():
        if isinstance(leaf, abjad.Chord):
            accidentals = [pitch.accidental for pitch in leaf.written_pitches]
            if not include_multiples:
                # dealing only with intervals of size equal to 1 semitone
                for i in range(len(leaf.written_pitches) - 1):
                    p1 = leaf.written_pitches[i]
                    p2 = leaf.written_pitches[i + 1]
                    interval12 = p1 - p2
                    try:
                        p3 = leaf.written_pitches[i + 2]
                        interval23 = p2 - p3
                    except IndexError:
                        p3 = None
                        interval23 = None
                    if (interval12 == abjad.NamedInterval('+A1')
                            and interval23 != abjad.NamedInterval('+A1')
                            and interval23 != abjad.NamedInterval('+m2')):
                        if not respell_by_pitch_class:
                            # respelling only one single note
                            if p1.accidental == abjad.Accidental('f'):
                                accidentals[i] = abjad.Accidental('s')
                            elif p1.accidental == abjad.Accidental(''):
                                accidentals[i + 1] = abjad.Accidental('f')
                        else:
                            # respelling all matching pitch-classes
                            if p1.accidental == abjad.Accidental('f'):
                                for j, p in enumerate(leaf.written_pitches):
                                    if p.pitch_class == p1.pitch_class:
                                        accidentals[j] = abjad.Accidental('s')
                            elif p1.accidental == abjad.Accidental(''):
                                for j, p in enumerate(leaf.written_pitches):
                                    if p.pitch_class == p2.pitch_class:
                                        accidentals[j] = abjad.Accidental('f')
            else:
                # dealing with augmented unisons as well as augmented 8as,
                # 15ths, etc.
                for i in range(len(leaf.written_pitches) - 1):
                    for j in range(i + 1, len(leaf.written_pitches)):
                        # no p3 this time since p1 and p2 are not necessary
                        # consecutive pitches in the chord
                        p1 = leaf.written_pitches[i]
                        p2 = leaf.written_pitches[j]
                        interval = abjad.NamedIntervalClass(p1 - p2)
                        if (interval in (
                                abjad.NamedIntervalClass('+A1'),
                                abjad.NamedIntervalClass('-d1'),
                        )):
                            # no need for respell_by_pitch_class since this
                            # will go through all notes in the chord anyway
                            if p1.accidental == abjad.Accidental('f'):
                                accidentals[i] = abjad.Accidental('s')
                            if p1.accidental == abjad.Accidental('s'):
                                accidentals[i] = abjad.Accidental('f')
                            elif p1.accidental == abjad.Accidental(''):
                                if p2.accidental == abjad.Accidental('s'):
                                    accidentals[j] = abjad.Accidental('f')
                                elif p2.accidental == abjad.Accidental('f'):
                                    accidentals[j] = abjad.Accidental('s')
            # rewritting chord with new spelling
            respelt_pitches = []
            for pitch, accidental in zip(leaf.written_pitches, accidentals):
                if accidental == abjad.Accidental('f'):
                    respelt_pitches.append(pitch._respell_with_flats())
                elif accidental == abjad.Accidental('s'):
                    respelt_pitches.append(pitch._respell_with_sharps())
                else:
                    respelt_pitches.append(pitch)
            leaf.written_pitches = respelt_pitches
コード例 #19
0
def respell_augmented_unisons(
    selection: abjad.Selection,
    *,
    include_multiples: bool = False,
    respell_by_pitch_class: bool = False,
) -> None:
    r"""Mutates an input |abjad.Selection| in place and has no return value;
    this function changes the accidentals of individual pitches of all chords
    in a container in order to avoid augmented unisons.

    Basic usage:
        To use this function, apply it to a selection that contains chords that
        have augmented unisons.

        >>> container = abjad.Container(r"c'4 r4 <ef' e'>4 g'4 <c' cs'>4 r2.")
        >>> abjad.show(container)

        ..  docs::

            {
                c'4
                r4
                <ef' e'>4
                g'4
                <c' cs'>4
                r2.
            }

        ..  figure:: ../_images/respell_augmented_unisons-OXnGvQzGT2.png

        >>> auxjad.mutate.respell_augmented_unisons(container[:])
        >>> abjad.show(container)

        ..  docs::

            {
                c'4
                r4
                <ds' e'>4
                g'4
                <c' df'>4
                r2.
            }

        ..  figure:: ../_images/respell_augmented_unisons-x33afbbamt.png

        This can be useful when using tuples of integers to create chords that
        contain minor seconds:

        >>> pitches = [(0, 1), (8, 9, 12), (0, 4, 5, 6), (-1, 5, 6)]
        >>> durations = [(1, 8), (3, 8), (7, 16), (1, 16)]
        >>> maker = abjad.LeafMaker()
        >>> chords = maker(pitches, durations)
        >>> staff = abjad.Staff(chords)
        >>> literal = abjad.LilyPondLiteral(r'\accidentalStyle dodecaphonic')
        >>> abjad.attach(literal, staff)
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' cs'>8
                <af' a' c''>4.
                <c' e' f' fs'>4..
                <b f' fs'>16
            }

        ..  figure:: ../_images/respell_augmented_unisons-mWVWwV9uBx.png

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' df'>8
                <gs' a' c''>4.
                <c' e' f' gf'>4..
                <b f' gf'>16
            }

        ..  figure:: ../_images/respell_augmented_unisons-IfzaseW4oS.png

    ..  note::

        Auxjad automatically adds this function as an extension function to
        |abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or
        |abjad.mutate| namespaces. Therefore, the two lines below are
        equivalent:

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.mutate.respell_augmented_unisons(staff[:])

    2-note chords:
        The example below shows first the default spelling of 2-note chords in
        Abjad followed by the respelt 2-note chords.

        >>> staff = abjad.Staff()
        >>> for pitch in range(12):
        ...     staff.append(abjad.Chord([pitch, pitch + 1], (1, 16)))
        >>> literal = abjad.LilyPondLiteral(r'\accidentalStyle dodecaphonic')
        >>> abjad.attach(literal, staff)
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' cs'>16
                <cs' d'>16
                <d' ef'>16
                <ef' e'>16
                <e' f'>16
                <f' fs'>16
                <fs' g'>16
                <g' af'>16
                <af' a'>16
                <a' bf'>16
                <bf' b'>16
                <b' c''>16
            }

        ..  figure:: ../_images/respell_augmented_unisons-qQduIqCRpz.png

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                \accidentalStyle dodecaphonic
                <c' df'>16
                <cs' d'>16
                <d' ef'>16
                <ds' e'>16
                <e' f'>16
                <f' gf'>16
                <fs' g'>16
                <g' af'>16
                <gs' a'>16
                <a' bf'>16
                <as' b'>16
                <b' c''>16
            }

        ..  figure:: ../_images/respell_augmented_unisons-jvg032q24il.png

    augmented unissons in chords with 3 or more pitches:
        The function looks for all augmented unissons in chords of 3 or more
        pitches:

        >>> staff = abjad.Staff(r"<a c' cs' f'>1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <a c' cs' f'>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-IklJO81q1E.png

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <a c' df' f'>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-gyficck05p.png

    ``include_multiples``:
        By default, this function only changes spelling for pitches that are
        1 semitone apart.

        >>> staff = abjad.Staff(r"<c' cs''>1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <c' cs''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-HPqFrADjeh.png

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <c' cs''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-uszf11qb72d.png

        To consider pitches in different octaves (thus including augmented
        unisons, augmented octaves, augmented fifteenths, etc.), call this
        function with the keyword argument ``include_multiples`` set to
        ``True``.

        >>> staff = abjad.Staff(r"<c' cs''>1")
        >>> auxjad.mutate.respell_augmented_unisons(
        ...     staff[:],
        ...     include_multiples=True,
        ... )

        ..  docs::

            \new Staff
            {
                <c' df''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-8am8cu2rmgi.png

    ``respell_by_pitch_class``:
        By default, when this function changes the spelling of a pitch, it does
        not change the spelling of all other pitches with the same pitch-class.

        >>> staff = abjad.Staff(r"<c' cs' cs''>1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                    <c' cs' cs''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-eWixL7iCEq.png

        >>> auxjad.mutate.respell_augmented_unisons(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <c' df' cs''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-47d16xk6gvs.png

        To alter all pitch-classes, call this function with the keyword
        argument ``respell_by_pitch_class`` set to ``True``.

        >>> staff = abjad.Staff(r"<c' cs' cs''>1")
        >>> auxjad.mutate.respell_augmented_unisons(
        ...     staff[:],
        ...     respell_by_pitch_class=True,
        ... )
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                <c' df' df''>1
            }

        ..  figure:: ../_images/respell_augmented_unisons-kobft0oq9sl.png
    """
    if not isinstance(selection, abjad.Selection):
        raise TypeError("argument must be 'abjad.Selection'")
    if not isinstance(respell_by_pitch_class, bool):
        raise TypeError("'respell_by_pitch_class' must be 'bool'")
    if not isinstance(include_multiples, bool):
        raise TypeError("'include_multiples' must be 'bool'")

    for leaf in selection.leaves():
        if isinstance(leaf, abjad.Chord):
            accidentals = [pitch.accidental for pitch in leaf.written_pitches]
            original_accidentals = accidentals[:]
            if not include_multiples:
                # dealing only with intervals of size equal to 1 semitone
                for i in range(len(leaf.written_pitches) - 1):
                    p1 = leaf.written_pitches[i]
                    p2 = leaf.written_pitches[i + 1]
                    interval12 = p1 - p2
                    try:
                        p3 = leaf.written_pitches[i + 2]
                        interval23 = p2 - p3
                    except IndexError:
                        p3 = None
                        interval23 = None
                    if (interval12 == abjad.NamedInterval('+A1')
                            and interval23 != abjad.NamedInterval('+A1')
                            and interval23 != abjad.NamedInterval('+m2')):
                        if not respell_by_pitch_class:
                            # respelling only one single note
                            if p1.accidental == abjad.Accidental('f'):
                                accidentals[i] = abjad.Accidental('s')
                            elif p1.accidental == abjad.Accidental(''):
                                accidentals[i + 1] = abjad.Accidental('f')
                        else:
                            # respelling all matching pitch-classes
                            if p1.accidental == abjad.Accidental('f'):
                                for j, p in enumerate(leaf.written_pitches):
                                    if p.pitch_class == p1.pitch_class:
                                        accidentals[j] = abjad.Accidental('s')
                            elif p1.accidental == abjad.Accidental(''):
                                for j, p in enumerate(leaf.written_pitches):
                                    if p.pitch_class == p2.pitch_class:
                                        accidentals[j] = abjad.Accidental('f')
            else:
                # dealing with augmented unisons as well as augmented 8as,
                # 15ths, etc.
                for i in range(len(leaf.written_pitches) - 1):
                    for j in range(i + 1, len(leaf.written_pitches)):
                        # no p3 this time since p1 and p2 are not necessary
                        # consecutive pitches in the chord
                        p1 = leaf.written_pitches[i]
                        p2 = leaf.written_pitches[j]
                        interval = abjad.NamedIntervalClass(p1 - p2)
                        if (interval in (
                                abjad.NamedIntervalClass('+A1'),
                                abjad.NamedIntervalClass('-d1'),
                        )):
                            # no need for respell_by_pitch_class since this
                            # will go through all notes in the chord anyway
                            if p1.accidental == abjad.Accidental('f'):
                                accidentals[i] = abjad.Accidental('s')
                            if p1.accidental == abjad.Accidental('s'):
                                accidentals[i] = abjad.Accidental('f')
                            elif p1.accidental == abjad.Accidental(''):
                                if p2.accidental == abjad.Accidental('s'):
                                    accidentals[j] = abjad.Accidental('f')
                                elif p2.accidental == abjad.Accidental('f'):
                                    accidentals[j] = abjad.Accidental('s')
            # rewritting chord with new spelling
            respelt_pitches = []
            for pitch, accidental, original_accidental in zip(
                    leaf.written_pitches,
                    accidentals,
                    original_accidentals,
            ):
                if (accidental != original_accidental
                        and accidental == abjad.Accidental('f')):
                    respelt_pitches.append(pitch._respell(accidental='flats'))
                elif (accidental != original_accidental
                      and accidental == abjad.Accidental('s')):
                    respelt_pitches.append(pitch._respell(accidental='sharps'))
                else:
                    respelt_pitches.append(pitch)
            leaf.written_pitches = respelt_pitches