def pcSetTransposer(chord, trans): """transposes an entire set by trans. w/ mod12 will strip oct info, retain micro info >>> pcSetTransposer([3,4,5], 3) (6, 7, 8) """ newSet = [] for pc in chord: newSet.append(pitchTools.pcTransposer(pc, trans)) return tuple(newSet)
def psSetToMason(chord): """named after a music educator named Mason by Michael Gogins convert any pitch space / class set to a 'mason' value OR-ing, to be precise, mod 4095 (the total number of unordered pitch-class sets in 12TET), not adding. In other words, a bit-field of 12 bits, one bit per pitch-class. """ newSet = [] for pc in chord: pc = pitchTools.pcTransposer(pc, 0) # make mod 12 if pc not in newSet: # remove redundancies newSet.append(pc) mason = 0 for i in newSet: mason = mason + pow(2, i) return mason % 4095
def extractNeighbors(pitchGroup, baseNote, scales=None): """takes a set, or a whole path, and derives a pc scale, a pitch space scale, and provides the upper and lower note to baseNote baseNote should be represented in the pitch group we need to know our current reference position in the pitchGroup pitchGroup has pitch pre-temperament; thus baseNote should be pre-temperament may be a psReal pitchGroup: from a refDict, containing stateCurrentChord, or statePathList will be a list of raw psReal values: could be floats, and could have micro specification """ # if scales given and no pitchGroup is given if scales != None and pitchGroup == None: colPitchSpace = scales[0] colPitchClass = scales[1] else: # given a set or path as pitchGroup if drawer.isNum(pitchGroup[0]): pitchGroup = [ pitchGroup, ] # make all look like paths colPitchSpace = [] colPitchClass = [] for set in pitchGroup: for entry in set: if entry not in colPitchSpace: colPitchSpace.append(entry) # round; zero trans gets mod12 entryPC = pitchTools.pcTransposer(entry, 0) if entryPC not in colPitchClass: colPitchClass.append(entryPC) colPitchSpace.sort() colPitchClass.sort() scales = colPitchSpace, colPitchClass # use pitch class space to get neighbors # can use pitch space in the future? wrap around is strange octaveAdjust = 0 baseOctMult, basePC = pitchTools.splitOctPs(baseNote) # although baseNote may be a float (already tempered) # basePC seems to need to be an int, as it is used to find # a position in the scale; for this reason it seems like # the path positions value, and not the tempered pitch # should be coming in as the baseNote: tmerperament could cause # a rounding error and pass a pitch that is not in the scale at all #print _MOD, basePC, colPitchClass idx = None try: idx = colPitchClass.index(basePC) except ValueError: # not in the collected pitches; try rounding for i in range(len(colPitchClass)): # compare rounded versions, as floats may not match if round(colPitchClass[i], 2) == round(basePC, 2): idx = i # print _MOD, 'found rounded match' if idx == None: idx = 0 environment.printDebug( 'no match between base pitch and collected pitches') idxL = idx - 1 # lower neighbor if idxL == -1: # wrap index around idxL = len(colPitchClass) - 1 octaveAdjust = -1 idxU = idx + 1 # upper neighbor if idxU == len(colPitchClass): idxU = 0 octaveAdjust = 1 neighborL = colPitchClass[idxL] if octaveAdjust == -1: neighborL = pitchTools.psTransposer(neighborL, -12) neighborU = colPitchClass[idxU] if octaveAdjust == 1: neighborU = pitchTools.psTransposer(neighborU, 12) # do octave adjust ment relative to baseNote in pitch space neighborL = pitchTools.psTransposer(neighborL, (12 * baseOctMult)) neighborU = pitchTools.psTransposer(neighborU, (12 * baseOctMult)) lowerUpper = neighborL, neighborU return scales, lowerUpper
def extractNeighbors(pitchGroup, baseNote, scales=None): """takes a set, or a whole path, and derives a pc scale, a pitch space scale, and provides the upper and lower note to baseNote baseNote should be represented in the pitch group we need to know our current reference position in the pitchGroup pitchGroup has pitch pre-temperament; thus baseNote should be pre-temperament may be a psReal pitchGroup: from a refDict, containing stateCurrentChord, or statePathList will be a list of raw psReal values: could be floats, and could have micro specification """ # if scales given and no pitchGroup is given if scales != None and pitchGroup == None: colPitchSpace = scales[0] colPitchClass = scales[1] else: # given a set or path as pitchGroup if drawer.isNum(pitchGroup[0]): pitchGroup = [pitchGroup, ] # make all look like paths colPitchSpace = [] colPitchClass = [] for set in pitchGroup: for entry in set: if entry not in colPitchSpace: colPitchSpace.append(entry) # round; zero trans gets mod12 entryPC = pitchTools.pcTransposer(entry, 0) if entryPC not in colPitchClass: colPitchClass.append(entryPC) colPitchSpace.sort() colPitchClass.sort() scales = colPitchSpace, colPitchClass # use pitch class space to get neighbors # can use pitch space in the future? wrap around is strange octaveAdjust = 0 baseOctMult, basePC = pitchTools.splitOctPs(baseNote) # although baseNote may be a float (already tempered) # basePC seems to need to be an int, as it is used to find # a position in the scale; for this reason it seems like # the path positions value, and not the tempered pitch # should be coming in as the baseNote: tmerperament could cause # a rounding error and pass a pitch that is not in the scale at all #print _MOD, basePC, colPitchClass idx = None try: idx = colPitchClass.index(basePC) except ValueError: # not in the collected pitches; try rounding for i in range(len(colPitchClass)): # compare rounded versions, as floats may not match if round(colPitchClass[i], 2) == round(basePC, 2): idx = i # print _MOD, 'found rounded match' if idx == None: idx = 0 environment.printDebug('no match between base pitch and collected pitches') idxL = idx - 1 # lower neighbor if idxL == -1: # wrap index around idxL = len(colPitchClass) - 1 octaveAdjust = -1 idxU = idx + 1 # upper neighbor if idxU == len(colPitchClass): idxU = 0 octaveAdjust = 1 neighborL = colPitchClass[idxL] if octaveAdjust == -1: neighborL = pitchTools.psTransposer(neighborL, -12) neighborU = colPitchClass[idxU] if octaveAdjust == 1: neighborU = pitchTools.psTransposer(neighborU, 12) # do octave adjust ment relative to baseNote in pitch space neighborL = pitchTools.psTransposer(neighborL, (12 * baseOctMult)) neighborU = pitchTools.psTransposer(neighborU, (12 * baseOctMult)) lowerUpper = neighborL, neighborU return scales, lowerUpper