def test_init(input_, expected_semitones): if isinstance(expected_semitones, type) and issubclass( expected_semitones, Exception): with pytest.raises(expected_semitones): abjad.NamedPitchClass(input_) return instance = abjad.NamedPitchClass(input_) assert float(instance) == expected_semitones
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 _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 __init__( self, root=None, quality_string='major', extent='triad', inversion='root', ): import abjad from abjad.tools import tonalanalysistools root = root or 'c' root = abjad.NamedPitchClass(root) chord_quality = tonalanalysistools.RootlessChordClass( quality_string=quality_string, extent=extent, inversion=inversion, ) npcs = [] for hdi in chord_quality: mdi = abjad.NamedInterval(hdi) npc = root + mdi npcs.append(npc) bass = npcs[0] PitchClassSet.__init__( self, items=npcs, item_class=abjad.NamedPitchClass, ) self._root = root self._chord_quality = chord_quality self._bass = bass
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 __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 _mk_midi_pitch2abjad_pitch_tuple() -> tuple: pitch_number2pitch_class = tuple( abjad.NamedPitchClass(name) for name in "c df d ef e f gf g af a bf b".split(" ") ) # pitch_number2pitch_class = tuple( # abjad.NumberedPitchClass(number) for number in range(12) # ) midi_pitch2abjad_pitch = tuple(abjad.NamedPitch(n - 60) for n in range(127)) midi_pitch2abjad_pitch = tuple(abjad.NamedPitch(n - 60) for n in range(127)) return tuple( abjad.NamedPitch( name=pitch_number2pitch_class[p.pitch_class.number], octave=p.octave ) for p in midi_pitch2abjad_pitch )
def pitch_class(self): r'''Gets pitch-class of named pitch. .. container:: example >>> abjad.NamedPitch("c''").pitch_class NamedPitchClass('c') >>> abjad.NamedPitch("cs''").pitch_class NamedPitchClass('cs') >>> abjad.NamedPitch("df''").pitch_class NamedPitchClass('df') Returns named pitch-class. ''' import abjad return abjad.NamedPitchClass(self._get_pitch_class_name())
def shadow_pitch_contour_reservoir(pitch_contour_reservoir): r'''Shadows pitch contour reservoir. ''' shadow_pitch_lookup = { abjad.NamedPitchClass('a'): -5, # add a P4 below abjad.NamedPitchClass('g'): -3, # add a m3 below abjad.NamedPitchClass('f'): -1, # add a m2 below abjad.NamedPitchClass('e'): -4, # add a M3 below abjad.NamedPitchClass('d'): -2, # add a M2 below abjad.NamedPitchClass('c'): -3, # add a m3 below abjad.NamedPitchClass('b'): -2, # add a M2 below } shadowed_reservoir = {} for name, pitch_contours in pitch_contour_reservoir.items(): # The viola does not receive any diads if name == 'Viola': shadowed_reservoir['Viola'] = pitch_contours continue shadowed_pitch_contours = [] for pitch_contour in pitch_contours[:-1]: shadowed_pitch_contour = [] for pitch in pitch_contour: pitch_class = pitch.pitch_class shadow_pitch = pitch + shadow_pitch_lookup[pitch_class] diad = (shadow_pitch, pitch) shadowed_pitch_contour.append(diad) shadowed_pitch_contours.append(tuple(shadowed_pitch_contour)) # treat the final contour differently: the last note does not become a diad final_shadowed_pitch_contour = [] for pitch in pitch_contours[-1][:-1]: pitch_class = pitch.pitch_class shadow_pitch = pitch + shadow_pitch_lookup[pitch_class] diad = (shadow_pitch, pitch) final_shadowed_pitch_contour.append(diad) final_shadowed_pitch_contour.append(pitch_contours[-1][-1]) shadowed_pitch_contours.append(tuple(final_shadowed_pitch_contour)) shadowed_reservoir[name] = tuple(shadowed_pitch_contours) return shadowed_reservoir
def voice_pitch_class(self, pitch_class): """ Voices `pitch_class`: .. container:: example Voices C three times: >>> pitch_range = abjad.PitchRange('[C4, C6]') >>> pitch_range.voice_pitch_class('c') (NamedPitch("c'"), NamedPitch("c''"), NamedPitch("c'''")) .. container:: example Voices B two times: >>> pitch_range = abjad.PitchRange('[C4, C6]') >>> pitch_range.voice_pitch_class('b') (NamedPitch("b'"), NamedPitch("b''")) .. container:: example Returns empty because B can not voice: >>> pitch_range = abjad.PitchRange('[C4, A4)') >>> pitch_range.voice_pitch_class('b') () Returns tuple of zero or more named pitches. """ import abjad named_pitch_class = abjad.NamedPitchClass(pitch_class) pair = (named_pitch_class.name, self.start_pitch.octave.number) named_pitch = abjad.NamedPitch(pair) result = [] while named_pitch <= self.stop_pitch: if named_pitch in self: result.append(named_pitch) named_pitch += 12 return tuple(result)
def named_pitch_class_to_scale_degree(self, pitch_class): r'''Changes named `pitch_class` to scale degree. .. container:: example >>> scale = abjad.tonalanalysistools.Scale(('c', 'major')) >>> scale.named_pitch_class_to_scale_degree('c') ScaleDegree('1') >>> scale.named_pitch_class_to_scale_degree('d') ScaleDegree('2') >>> scale.named_pitch_class_to_scale_degree('e') ScaleDegree('3') >>> scale.named_pitch_class_to_scale_degree('f') ScaleDegree('4') >>> scale.named_pitch_class_to_scale_degree('g') ScaleDegree('5') >>> scale.named_pitch_class_to_scale_degree('a') ScaleDegree('6') >>> scale.named_pitch_class_to_scale_degree('b') ScaleDegree('7') >>> scale.named_pitch_class_to_scale_degree('df') ScaleDegree('b2') Returns scale degree. ''' import abjad foreign_pitch_class = abjad.NamedPitchClass(pitch_class) letter = foreign_pitch_class._get_diatonic_pitch_class_name() for i, pc in enumerate(self): if pc._get_diatonic_pitch_class_name() == letter: native_pitch_class = pc scale_degree_index = i number = scale_degree_index + 1 break native_pitch = abjad.NamedPitch((native_pitch_class.name, 4)) foreign_pitch = abjad.NamedPitch((foreign_pitch_class.name, 4)) accidental = foreign_pitch.accidental - native_pitch.accidental class_ = abjad.tonalanalysistools.ScaleDegree scale_degree = class_.from_accidental_and_number(accidental, number) return scale_degree
("c'", 0), ("cs'", 1), ("gff''", 17), ("", 0), ("dss,,", -32), ("fake", ValueError), (("bf", 2), -14), (("c", 4), 0), (("cs", 4), 1), (("dss", 1), -32), (("gff", 5), 17), (abjad.NamedPitch("bs'"), 12), (abjad.NamedPitch("c"), -12), (abjad.NamedPitch("cf,"), -25), (abjad.NamedPitch(), 0), (abjad.NamedPitchClass("cs'"), 1), (abjad.NamedPitchClass("c"), 0), (abjad.NamedPitchClass("cf,"), 11), (None, 0), (abjad.NumberedPitch("bs'"), 12), (abjad.NumberedPitch("c"), -12), (abjad.NumberedPitch("cf,"), -25), (abjad.NumberedPitch(), 0), (abjad.NumberedPitchClass("bs'"), 0), (abjad.NumberedPitchClass("c"), 0), (abjad.NumberedPitchClass("cf,"), 11), ]) @pytest.mark.parametrize("input_, expected_semitones", values) def test_init(input_, expected_semitones):
def return_cent_deviation_markup( ratio=1, fundamental="a'", chris=False ): # chris values are temp. pitch = None ratio = quicktions.Fraction(ratio) tonic_cent_difference = abjad.NamedPitch(fundamental).number * 100 log_ratio = quicktions.Fraction(math.log10(ratio)) log_2 = quicktions.Fraction(1200 / math.log10(2)) ji_cents = quicktions.Fraction(log_ratio * log_2) et_cents = ( make_ji_bundle(fundamental, ratio).pitch.number * 100 ) - tonic_cent_difference cent_difference = ji_cents - et_cents final_cents = round(float(cent_difference)) if chris is True: final_cents = round(float(cent_difference), 2) if chris is True: p_string = f"{fundamental}4" demo_note = abjad.Note(p_string) demo_head = demo_note.note_head tune_to_ratio(demo_head, quicktions.Fraction(ratio) * quicktions.Fraction(9, 8)) pitch = abjad.NumberedPitch(demo_head.written_pitch) if 50 < abs(final_cents): if chris is False: p_string = f"{fundamental}4" demo_note = abjad.Note(p_string) demo_head = demo_note.note_head tune_to_ratio(demo_head, ratio) pitch = abjad.NumberedPitch(demo_head.written_pitch) semitones = final_cents / 100 parts = math.modf(semitones) pitch += parts[1] remainder = round(parts[0] * 100) if 50 < abs(remainder): if 0 < remainder: pitch += 1 remainder = -100 + remainder else: pitch -= 1 remainder = 100 + remainder final_cents = remainder if final_cents < 0: cent_string = f"{final_cents}" if chris is True: if not cent_string[0].isalpha(): pitch_string = str(abjad.NamedPitchClass(pitch)) pos, acc = pitch_string[0], pitch_string[1:] pos = pos.capitalize() acc = acc.replace("s", "♯") acc = acc.replace("f", "♭") cent_string = pos + acc + cent_string cent_string = cent_string.replace("A♭", "G♯") if chris is False: if pitch is not None: pitch_string = str(abjad.NamedPitchClass(pitch)) pos, acc = pitch_string[0], pitch_string[1:] pos = pos.capitalize() acc = acc.replace("s", "♯") acc = acc.replace("f", "♭") cent_string = pos + acc + cent_string else: cent_string = f"+{final_cents}" if chris is True: if not cent_string[0].isalpha(): pitch_string = str(abjad.NamedPitchClass(pitch)) pos, acc = pitch_string[0], pitch_string[1:] pos = pos.capitalize() acc = acc.replace("s", "♯") acc = acc.replace("f", "♭") cent_string = pos + acc + cent_string cent_string = cent_string.replace("A♭", "G♯") if chris is False: if pitch is not None: pitch_string = str(abjad.NamedPitchClass(pitch)) pos, acc = pitch_string[0], pitch_string[1:] pos = pos.capitalize() acc = acc.replace("s", "♯") acc = acc.replace("f", "♭") cent_string = pos + acc + cent_string mark = abjad.Markup( fr"\markup \center-align {{ {cent_string} }}", direction=abjad.Up, literal=True, ) return mark
("c'", 0), ("cs'", 1), ("gff''", 17), ("", 0), ("dss,,", -32), ("fake", ValueError), (("bf", 2), -14), (("c", 4), 0), (("cs", 4), 1), (("dss", 1), -32), (("gff", 5), 17), (abjad.NamedPitch("bs'"), 12), (abjad.NamedPitch("c"), -12), (abjad.NamedPitch("cf,"), -25), (abjad.NamedPitch(), 0), (abjad.NamedPitchClass("cs'"), 1), (abjad.NamedPitchClass("c"), 0), (abjad.NamedPitchClass("cf,"), -1), # TODO: Is this correct? (None, 0), (abjad.NumberedPitch("bs'"), 12), (abjad.NumberedPitch("c"), -12), (abjad.NumberedPitch("cf,"), -25), (abjad.NumberedPitch(), 0), (abjad.NumberedPitchClass("bs'"), 0), (abjad.NumberedPitchClass("c"), 0), (abjad.NumberedPitchClass("cf,"), 11), ]) @pytest.mark.parametrize("input_, expected_semitones", values) def test_init(input_, expected_semitones):
def pitch_class(self): return abjad.NamedPitchClass(self.pitch)
values = [ ("bf,", 2), ("c'", 4), ("cs'", 4), ("gff''", 5), ("dss,,", 1), (("bf", 2), 2), (("c", 4), 4), (("cs", 4), 4), (("dss", 1), 1), (("gff", 5), 5), (abjad.NamedPitch("bs'"), 4), (abjad.NamedPitch("c"), 3), (abjad.NamedPitch("cf,"), 2), (abjad.NamedPitch(), 4), (abjad.NamedPitchClass("cs'"), 4), (abjad.NamedPitchClass("c"), 4), (abjad.NamedPitchClass("cf,"), 4), (abjad.NumberedPitch("bs'"), 5), (abjad.NumberedPitch("c"), 3), (abjad.NumberedPitch("cf,"), 1), (abjad.NumberedPitch(), 4), (abjad.NumberedPitchClass("bs'"), 4), (abjad.NumberedPitchClass("c"), 4), (abjad.NumberedPitchClass("cf,"), 4), ] @pytest.mark.parametrize("input_, expected_number", values) def test_init_from_pitch(input_, expected_number): octave = abjad.NamedPitch(input_).octave
"g_i": "g_i", "e_ii": "e_ii", "cs_v": "cs_v", "bf_i": "bf_i", "g_ii": "g_ii", "e_v": "e_v", "cs_i": "cs_i", } } """Lookup table used for make_diads function harmonizing in diatonic variations of C scales C maj // Harmonic Minor """ diatonic_register_lookup = { 'd2': { abjad.NamedPitchClass("c"): 2, abjad.NamedPitchClass("b"): 1, abjad.NamedPitchClass("bf"): 2, abjad.NamedPitchClass("as"): 2, abjad.NamedPitchClass("a"): 2, abjad.NamedPitchClass("af"): 1, abjad.NamedPitchClass("gs"): 1, abjad.NamedPitchClass("g"): 2, abjad.NamedPitchClass("fss"): 2, abjad.NamedPitchClass("fs"): 1, abjad.NamedPitchClass("f"): 2, abjad.NamedPitchClass("e"): 1, abjad.NamedPitchClass("ef"): 2, abjad.NamedPitchClass("ds"): 2, abjad.NamedPitchClass("d"): 2, abjad.NamedPitchClass("df"): 1,
def voice_pitch_classes( self, pitch_classes, allow_open_strings=True, ): r"""Voices `pitch_classes`. .. container:: example >>> tuning = abjad.Tuning(('G3', 'D4', 'A4', 'E5')) >>> voicings = tuning.voice_pitch_classes(('a',)) >>> for voicing in voicings: ... voicing ... (None, None, None, NamedPitch("a''")) (None, None, None, NamedPitch("a'''")) (None, None, NamedPitch("a'"), None) (None, None, NamedPitch("a''"), None) (None, None, NamedPitch("a'''"), None) (None, NamedPitch("a'"), None, None) (None, NamedPitch("a''"), None, None) (NamedPitch('a'), None, None, None) (NamedPitch("a'"), None, None, None) >>> voicings = tuning.voice_pitch_classes( ... ('a', 'd'), ... allow_open_strings=False, ... ) >>> for voicing in voicings: ... voicing ... (None, None, NamedPitch("d''"), NamedPitch("a''")) (None, None, NamedPitch("d''"), NamedPitch("a'''")) (None, None, NamedPitch("a''"), NamedPitch("d'''")) (None, None, NamedPitch("a''"), NamedPitch("d''''")) (None, None, NamedPitch("d'''"), NamedPitch("a''")) (None, None, NamedPitch("d'''"), NamedPitch("a'''")) (None, None, NamedPitch("a'''"), NamedPitch("d'''")) (None, None, NamedPitch("a'''"), NamedPitch("d''''")) (None, NamedPitch("a'"), None, NamedPitch("d'''")) (None, NamedPitch("a'"), None, NamedPitch("d''''")) (None, NamedPitch("a'"), NamedPitch("d''"), None) (None, NamedPitch("a'"), NamedPitch("d'''"), None) (None, NamedPitch("d''"), None, NamedPitch("a''")) (None, NamedPitch("d''"), None, NamedPitch("a'''")) (None, NamedPitch("d''"), NamedPitch("a''"), None) (None, NamedPitch("d''"), NamedPitch("a'''"), None) (None, NamedPitch("a''"), None, NamedPitch("d'''")) (None, NamedPitch("a''"), None, NamedPitch("d''''")) (None, NamedPitch("a''"), NamedPitch("d''"), None) (None, NamedPitch("a''"), NamedPitch("d'''"), None) (None, NamedPitch("d'''"), None, NamedPitch("a''")) (None, NamedPitch("d'''"), None, NamedPitch("a'''")) (None, NamedPitch("d'''"), NamedPitch("a''"), None) (None, NamedPitch("d'''"), NamedPitch("a'''"), None) (NamedPitch('a'), None, None, NamedPitch("d'''")) (NamedPitch('a'), None, None, NamedPitch("d''''")) (NamedPitch('a'), None, NamedPitch("d''"), None) (NamedPitch('a'), None, NamedPitch("d'''"), None) (NamedPitch('a'), NamedPitch("d''"), None, None) (NamedPitch('a'), NamedPitch("d'''"), None, None) (NamedPitch("d'"), None, None, NamedPitch("a''")) (NamedPitch("d'"), None, None, NamedPitch("a'''")) (NamedPitch("d'"), None, NamedPitch("a''"), None) (NamedPitch("d'"), None, NamedPitch("a'''"), None) (NamedPitch("d'"), NamedPitch("a'"), None, None) (NamedPitch("d'"), NamedPitch("a''"), None, None) (NamedPitch("a'"), None, None, NamedPitch("d'''")) (NamedPitch("a'"), None, None, NamedPitch("d''''")) (NamedPitch("a'"), None, NamedPitch("d''"), None) (NamedPitch("a'"), None, NamedPitch("d'''"), None) (NamedPitch("a'"), NamedPitch("d''"), None, None) (NamedPitch("a'"), NamedPitch("d'''"), None, None) (NamedPitch("d''"), None, None, NamedPitch("a''")) (NamedPitch("d''"), None, None, NamedPitch("a'''")) (NamedPitch("d''"), None, NamedPitch("a''"), None) (NamedPitch("d''"), None, NamedPitch("a'''"), None) (NamedPitch("d''"), NamedPitch("a'"), None, None) (NamedPitch("d''"), NamedPitch("a''"), None, None) Returns tuple of sequences. """ import abjad pitch_classes = [abjad.NamedPitchClass(_) for _ in pitch_classes] pitch_classes.extend([None] * (len(self.pitches) - len(pitch_classes))) enumerator = abjad.Enumerator(pitch_classes) permutations = enumerator.yield_permutations() permutations = set([tuple(_) for _ in permutations]) pitch_ranges = self.pitch_ranges result = [] for permutation in permutations: sequences = [] for pitch_range, pitch_class in zip(pitch_ranges, permutation): if pitch_class is None: sequences.append([None]) continue pitches = pitch_range.voice_pitch_class(pitch_class) if not allow_open_strings: pitches = [ pitch for pitch in pitches if pitch != pitch_range.start_pitch ] if not pitches: pitches = [None] sequences.append(pitches) enumerator = abjad.Enumerator(sequences) subresult = enumerator.yield_outer_product() subresult = [tuple(x) for x in subresult] result.extend(subresult) result.sort() return tuple(result)
def __init__(self, tonic='c', mode='major'): import abjad self._tonic = abjad.NamedPitchClass(tonic) self._mode = abjad.tonalanalysistools.Mode(mode)
def _get_lilypond_format(self): import abjad return format(abjad.NamedPitchClass(self), 'lilypond')