def test_init(input_, expected_number): if isinstance(expected_number, type) and issubclass( expected_number, Exception): with pytest.raises(expected_number): abjad.Octave(input_) return octave = abjad.Octave(input_) assert octave.number == expected_number
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_number(self, number): import abjad self._number = self._to_nearest_quarter_tone(number) octave_number, pc_number = divmod(self._number, 12) self._octave = abjad.Octave(octave_number + 4) self._pitch_class = abjad.NumberedPitchClass(pc_number)
def _american_name_to_lilypond_name(name): import abjad match = NamedPitch._pitch_class_octave_number_regex.match(name) group_dict = match.groupdict() name = abjad.NamedPitchClass(name).name name += abjad.Octave(int(group_dict['octave_number'])).ticks return name
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 _from_pitch_or_pitch_class(self, pitch_or_pitch_class): import abjad self._number = self._to_nearest_quarter_tone( float(pitch_or_pitch_class)) octave_number, pc_number = divmod(self._number, 12) self._octave = abjad.Octave(octave_number + 4) self._pitch_class = abjad.NumberedPitchClass( pc_number, arrow=pitch_or_pitch_class.arrow)
def _from_named_parts(self, dpc_number, alteration, octave): import abjad pc_number = constants._diatonic_pc_number_to_pitch_class_number[ dpc_number] pc_number += alteration pc_number += (octave - 4) * 12 self._number = mathtools.integer_equivalent_number_to_integer( pc_number) octave_number, pc_number = divmod(self._number, 12) self._pitch_class = abjad.NumberedPitchClass(pc_number) self._octave = abjad.Octave(octave_number + 4)
def __init__(self, name="c'", arrow=None): import abjad if self._is_pitch_name(name): pass elif self._is_pitch_class_octave_number_string(name): name = self._american_name_to_lilypond_name(name) elif isinstance(name, type(self)): arrow = name.arrow name = name.name elif isinstance(name, abjad.NamedPitchClass): name = name.name + "'" elif isinstance(name, tuple) and len(name) == 2: pitch_class, octave = name pitch_class = abjad.NamedPitchClass(pitch_class) octave = abjad.Octave(octave) name = str(pitch_class) + str(abjad.Octave(octave)) elif isinstance(name, numbers.Number) or hasattr(name, 'number'): number = getattr(name, 'number', name) named_pitch_class = abjad.NamedPitchClass(number) octave = number // 12 + 4 if named_pitch_class == 'c': rounded = 12 * (octave - 4) + named_pitch_class.number if 0.5 <= abs(number - rounded): octave += 1 name = named_pitch_class.name + abjad.Octave(octave).ticks elif isinstance(name, abjad.Note): name = name.written_pitch.name else: message = 'can not initialize {} from {!r}.' message = message.format(type(self).__name__, name) raise ValueError(message) assert self._is_pitch_name(name) self._name = name if arrow not in (abjad.Up, abjad.Down, None): message = 'arrow must be up, down or none: {!r}.' message = message.format(arrow) raise TypeError(message) if not hasattr(self, '_arrow'): self._arrow = arrow
def _from_pitch_or_pitch_class(self, pitch_or_pitch_class): import abjad name = format(pitch_or_pitch_class, "lilypond") if not isinstance(pitch_or_pitch_class, Pitch): name += "'" if isinstance(pitch_or_pitch_class, Pitch): self._pitch_class = abjad.NamedPitchClass( pitch_or_pitch_class.pitch_class) self._octave = pitch_or_pitch_class.octave else: self._pitch_class = abjad.NamedPitchClass(pitch_or_pitch_class) self._octave = abjad.Octave()
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_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 octave(self): r'''Gets octave of named pitch. .. container:: example >>> abjad.NamedPitch("c''").octave Octave(5) >>> abjad.NamedPitch("cs''").octave Octave(5) >>> abjad.NamedPitch("df''").octave Octave(5) Returns octave. ''' import abjad return abjad.Octave(self._parse_name()[2])
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 octave(self): return abjad.Octave(self.pitch)
("0", 0), ("1", 1), ("2", 2), ("3", 3), ("4", 4), (-1, -1), (-2, -2), (-3, -3), (-4, -4), (0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (None, 4), (abjad.Octave(), 4), (abjad.Octave(3), 3), (abjad.Octave(5), 5), ] @pytest.mark.parametrize("input_, expected_number", values) def test_init(input_, expected_number): if isinstance(expected_number, type) and issubclass( expected_number, Exception): with pytest.raises(expected_number): abjad.Octave(input_) return octave = abjad.Octave(input_) assert octave.number == expected_number