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
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))
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)
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)
def _get_lilypond_format(self): import abjad return "{}{!s}".format( self._get_diatonic_pc_name(), abjad.Accidental(self._get_alteration()), )
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)
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, )
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]
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)
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)
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)
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])
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
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)
def test_init(input_, semitones, string): accidental = abjad.Accidental(input_) assert accidental.semitones == semitones assert str(accidental) == string
def _from_named_parts(self, dpc_number, alteration): import abjad self._diatonic_pc_number = dpc_number self._accidental = abjad.Accidental(alteration)
def _apply_accidental(self, accidental=None): import abjad accidental = abjad.Accidental(accidental) semitones = self.number + accidental.semitones return type(self)(semitones)
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
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