def list_octave_transpositions(self, pitch_carrier): """ Lists octave transpositions of `pitch_carrier` in pitch range. .. container:: example Lists octave transpositions of three-pitch chord: >>> chord = abjad.Chord("<c' d' e'>4") >>> pitch_range = abjad.PitchRange.from_pitches(0, 48) >>> result = pitch_range.list_octave_transpositions(chord) >>> for chord in result: ... chord ... Chord("<c' d' e'>4") Chord("<c'' d'' e''>4") Chord("<c''' d''' e'''>4") Chord("<c'''' d'''' e''''>4") Returns a list of `pitch_carrier` objects. """ import abjad if isinstance(pitch_carrier, collections.abc.Iterable): if all(isinstance(x, (int, float)) for x in pitch_carrier): return self._list_numeric_octave_transpositions(pitch_carrier) prototype = (abjad.Chord, abjad.PitchSet) if not isinstance(pitch_carrier, prototype): message = "must be chord or pitch-set: {!r}" message = message.format(pitch_carrier) raise TypeError(message) result = [] interval = abjad.NumberedInterval(-12) while True: pitch_carrier_copy = copy.copy(pitch_carrier) candidate = interval.transpose(pitch_carrier_copy) if candidate in self: result.append(candidate) interval -= 12 else: break result.reverse() interval = abjad.NumberedInterval(0) while True: pitch_carrier_copy = copy.copy(pitch_carrier) candidate = interval.transpose(pitch_carrier_copy) if candidate in self: result.append(candidate) interval += abjad.NumberedInterval(12) else: break return result
def test_init(input_, semitones, name): class_ = abjad.NamedInterval if isinstance(semitones, type) and issubclass(semitones, Exception): with pytest.raises(semitones): class_(input_) return instance = class_(input_) assert float(instance) == semitones assert instance.name == name abjad.NamedInterval(instance) abjad.NumberedInterval(instance) abjad.NamedIntervalClass(instance) abjad.NumberedIntervalClass(instance) if isinstance(input_, str): group_dict = abjad.pitch._lib._interval_name_abbreviation_regex.match( input_).groupdict() inflected_up = class_("{}{}{}{}".format( group_dict["direction"] or "", group_dict["quality"], "+", group_dict["number"], )) inflected_down = class_("{}{}{}{}".format( group_dict["direction"] or "", group_dict["quality"], "~", group_dict["number"], )) if (math.sign(float(instance)) == instance.direction_number) and abs(instance.number) != 1: direction = math.sign(float(instance)) assert float(inflected_up) == (abs(float(instance)) + 0.5) * direction assert float(inflected_down) == (abs(float(instance)) - 0.5) * direction
def __add__(self, argument): """ Adds `argument` to numbered pitch-class. .. container:: example >>> pitch_class = abjad.NumberedPitchClass(9) >>> pitch_class + abjad.NumberedInterval(0) NumberedPitchClass(9) >>> pitch_class + abjad.NumberedInterval(1) NumberedPitchClass(10) >>> pitch_class + abjad.NumberedInterval(2) NumberedPitchClass(11) >>> pitch_class + abjad.NumberedInterval(3) NumberedPitchClass(0) Returns new numbered pitch-class. """ import abjad interval = abjad.NumberedInterval(argument) return type(self)(self.number + interval.number % 12)
def spread(self): """ Gets spread of interval segment. .. container:: example The maximum interval spanned by any combination of the intervals within a numbered interval segment. >>> abjad.IntervalSegment([1, 2, -3, 1, -2, 1]).spread NumberedInterval(4) >>> abjad.IntervalSegment([1, 1, 1, 2, -3, -2]).spread NumberedInterval(5) Returns numbered interval. """ import abjad current = maximum = minimum = 0 for x in self: current += float(x.number) if maximum < current: maximum = current if current < minimum: minimum = current return abjad.NumberedInterval(maximum - minimum)
def test_init(input_, semitones, name): class_ = abjad.NamedIntervalClass if isinstance(semitones, type) and issubclass(semitones, Exception): with pytest.raises(semitones): class_(input_) return instance = class_(input_) assert float(instance) == semitones assert instance.name == name abjad.NamedInterval(instance) abjad.NamedIntervalClass(instance) abjad.NumberedInterval(instance) abjad.NumberedIntervalClass(instance)
def transpose(self, n=0): r'''Tranposes numbered pitch by `n` semitones. .. container:: example >>> abjad.NumberedPitch(13).transpose(1) NumberedPitch(14) Returns new numbered pitch. ''' import abjad interval = abjad.NumberedInterval(n) return interval.transpose(self)
def transpose(self, n=0): """ Tranposes numbered pitch by `n` semitones. .. container:: example >>> abjad.NumberedPitch(13).transpose(1) NumberedPitch(14) Returns new numbered pitch. """ import abjad interval = abjad.NumberedInterval(n) return type(self)(float(self) + float(interval))
def from_pitch_carriers(class_, pitch_carrier_1, pitch_carrier_2): '''Makes named interval calculated from `pitch_carrier_1` to `pitch_carrier_2`. .. container:: example >>> abjad.NamedInterval.from_pitch_carriers( ... abjad.NamedPitch(-2), ... abjad.NamedPitch(12), ... ) NamedInterval('+M9') .. todo:: Improve this behavior. >>> abjad.NamedInterval.from_pitch_carriers( ... abjad.NamedPitch("cs'"), ... abjad.NamedPitch("cf'"), ... ) NamedInterval('-M2') Returns named interval. ''' import abjad pitch_1 = abjad.NamedPitch.from_pitch_carrier(pitch_carrier_1) pitch_2 = abjad.NamedPitch.from_pitch_carrier(pitch_carrier_2) degree_1 = pitch_1._get_diatonic_pitch_number() degree_2 = pitch_2._get_diatonic_pitch_number() named_interval_number = abs(degree_1 - degree_2) + 1 number = abs( abjad.NumberedPitch(pitch_1).number - abjad.NumberedPitch(pitch_2).number ) numbered_interval = abjad.NumberedInterval(number) absolute_named_interval = numbered_interval.to_named_interval( named_interval_number ) if pitch_2 < pitch_1: named_interval = -absolute_named_interval else: named_interval = absolute_named_interval return class_(named_interval)
def __sub__(self, argument): """ Subtracts `argument` from numbered pitch. .. container:: example >>> abjad.NumberedPitch(12) - abjad.NumberedPitch(12) NumberedInterval(0) >>> abjad.NumberedPitch(12) - abjad.NumberedPitch(13) NumberedInterval(1) >>> abjad.NumberedPitch(13) - abjad.NumberedPitch(12) NumberedInterval(-1) Returns numbered interval. """ import abjad if isinstance(argument, type(self)): return abjad.NumberedInterval.from_pitch_carriers(self, argument) interval = abjad.NumberedInterval(argument) interval = -interval return interval.transpose(self)
def get_alteration(pitch, value, spell=None): r""" Gets alteration. .. container:: example >>> pitch = abjad.NumberedPitch(0) >>> bundle = microtones.get_alteration(pitch, "2/1") >>> bundle.pitch NumberedPitch(2) >>> bundle.accidental_string '\\abjad-natural-markup' .. container:: example >>> pitch = abjad.NumberedPitch(0) >>> bundle = microtones.get_alteration(pitch, "1/1") >>> bundle.pitch NumberedPitch(1) >>> bundle.accidental_string '\\abjad-sharp-markup' .. container:: example >>> pitch = abjad.NumberedPitch(0) >>> bundle = microtones.get_alteration(pitch, "1/1", "flat") >>> bundle.pitch NamedPitch("df'") >>> bundle.accidental_string '\\abjad-flat-markup' .. container:: example >>> pitch = abjad.NumberedPitch(0) >>> bundle = microtones.get_alteration(pitch, "3/2", "sharp") >>> bundle.pitch NumberedPitch(1) >>> bundle.accidental_string '\\three-quarters-sharp-markup' .. container:: example >>> pitch = abjad.NumberedPitch(0) >>> bundle = microtones.get_alteration(pitch, "11/6", "sharp") >>> bundle.pitch NumberedPitch(1) >>> bundle.accidental_string '\\eleven-twelfths-sharp-markup' """ value = quicktions.Fraction(value) semitones = int(math.modf(value)[1]) remainder = quicktions.Fraction(value - int(math.modf(value)[1])) if semitones != 0: pitch = abjad.NumberedInterval(semitones).transpose(pitch) transposed_accidental_value = get_value_sum(pitch, remainder) key = str(transposed_accidental_value) new_accidental = _value_to_accidental[key] + "-markup" if spell is not None: if spell == "sharp": if quicktions.Fraction( _reversed_value_to_accidental[new_accidental]) < 0: # make sharp temp_note = abjad.Note(abjad.NamedPitch(pitch), (1, 4)) abjad.iterpitches.respell_with_sharps([temp_note]) pitch = temp_note.written_pitch transposed_accidental_value = get_value_sum(pitch, remainder) key = str(transposed_accidental_value) new_accidental = _value_to_accidental[key] + "-markup" if spell == "flat": if 0 < quicktions.Fraction( _reversed_value_to_accidental[new_accidental]): # make flat temp_note = abjad.Note(abjad.NamedPitch(pitch), (1, 4)) abjad.iterpitches.respell_with_flats([temp_note]) pitch = temp_note.written_pitch transposed_accidental_value = get_value_sum(pitch, remainder) key = str(transposed_accidental_value) new_accidental = _value_to_accidental[key] + "-markup" return ETBundle(pitch, new_accidental)