def test_tonalanalysistools_RootedChordClass_quality_pair_01(): cc = tonalanalysistools.RootedChordClass('c', 'major', 'triad', 'root') assert cc.quality_pair == ('major', 'triad') cc = tonalanalysistools.RootedChordClass('c', 'minor', 'triad', 'root') assert cc.quality_pair == ('minor', 'triad')
def test_tonalanalysistools_RootedChordClass_quality_pair_02(): cc = tonalanalysistools.RootedChordClass('c', 'dominant', 'seventh', 'root') assert cc.quality_pair == ('dominant', 'seventh') cc = tonalanalysistools.RootedChordClass('c', 'diminished', 'seventh', 'root') assert cc.quality_pair == ('diminished', 'seventh')
def _analyze_incomplete_chord(expr): from abjad.tools import tonalanalysistools pitches = pitchtools.PitchSegment.from_selection(expr) npcset = pitchtools.PitchClassSet( pitches, item_class=pitchtools.NamedPitchClass) dicv = pitchtools.IntervalClassVector( items=npcset, item_class=pitchtools.NamedInversionEquivalentIntervalClass, ) # TODO: eliminate code duplication # if dicv == TonalAnalysisAgent._make_dicv('c', 'ef'): model_npcs = ['c', 'ef'] quality, extent = 'minor', 'triad' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e'): model_npcs = ['c', 'e'] quality, extent = 'major', 'triad' elif dicv == TonalAnalysisAgent._make_dicv('c', 'ef', 'bff'): model_npcs = ['c', 'ef', 'bff'] quality, extent = 'diminished', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'ef', 'bf'): model_npcs = ['c', 'ef', 'bf'] quality, extent = 'minor', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e', 'bf'): model_npcs = ['c', 'e', 'bf'] quality, extent = 'dominant', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e', 'b'): model_npcs = ['c', 'e', 'b'] quality, extent = 'major', 'seventh' else: message = 'can not identify incomplete tertian chord.' raise ValueError(message) bass = min(pitches).named_pitch_class try: npcseg = npcset.order_by( pitchtools.PitchClassSegment( model_npcs, item_class=pitchtools.NamedPitchClass, )) except ValueError: message = 'can not identify incomplete tertian chord.' raise ValueError(message) inversion = npcseg.index(bass) root = npcseg[0] return tonalanalysistools.RootedChordClass( root, quality, extent, inversion, )
def test_tonalanalysistools_RootedChordClass_root_string_01(): assert tonalanalysistools.RootedChordClass('c', 'major', 'triad').root_string == 'C' assert tonalanalysistools.RootedChordClass('c', 'minor', 'triad').root_string == 'c' assert tonalanalysistools.RootedChordClass('cs', 'major', 'triad').root_string == 'C#' assert tonalanalysistools.RootedChordClass('cs', 'minor', 'triad').root_string == 'c#' assert tonalanalysistools.RootedChordClass('cf', 'major', 'triad').root_string == 'Cb' assert tonalanalysistools.RootedChordClass('cf', 'minor', 'triad').root_string == 'cb'
def _analyze_chord(expr): from abjad.tools import tonalanalysistools pitches = pitchtools.PitchSegment.from_selection(expr) npcset = pitchtools.PitchClassSet( pitches, item_class=pitchtools.NamedPitchClass, ) ordered_npcs = [] letters = ('c', 'e', 'g', 'b', 'd', 'f', 'a') for letter in letters: for npc in npcset: if npc.diatonic_pitch_class_name == letter: ordered_npcs.append(npc) ordered_npcs = pitchtools.PitchClassSegment( ordered_npcs, item_class=pitchtools.NamedPitchClass) for x in range(len(ordered_npcs)): ordered_npcs = ordered_npcs.rotate(1) segment = \ pitchtools.IntervalClassSegment( items=mathtools.difference_series(ordered_npcs), item_class=pitchtools.NamedInversionEquivalentIntervalClass, ) if segment.is_tertian: break else: return None root = ordered_npcs[0] class_ = tonalanalysistools.RootlessChordClass rootless_chord_class = class_.from_interval_class_segment(segment) bass = min(pitches).named_pitch_class inversion = ordered_npcs.index(bass) return tonalanalysistools.RootedChordClass( root, rootless_chord_class.quality_string, rootless_chord_class.extent, inversion, )