def psInverter(normalChord): """returns the inversion of a chord (list of pitches in normal form) returns inversion with same starting value in pitch space must be entered as normal form """ modInversiontSet = pcInverter(normalChord) sourceSetAsOctMultipliers = [] for entry in normalChord: octMultiplier, modPC = pitchTools.splitOctPs(entry) # gives original order of oct multipliers fo each member of set sourceSetAsOctMultipliers.append(octMultiplier) modInversiontSet = list(modInversiontSet) # do mod 12 transposition invertedChord = pcSetTransposer(modInversiontSet, normalChord[0]) invertedChord = list(invertedChord) #check octaves for i in range(0, len(normalChord)): sourceOct = sourceSetAsOctMultipliers[i] currentOct, modPC = pitchTools.splitOctPs(invertedChord[i]) if sourceOct == currentOct: pass else: # find difference and make up if sourceOct > currentOct: direction = 'up' else: direction = 'down' distance = abs(currentOct - sourceOct) if direction == 'up': invertedChord[i] = invertedChord[i] + (12 * distance) else: invertedChord[i] = invertedChord[i] - (12 * distance) return tuple(invertedChord)
def psInverter(normalChord): """returns the inversion of a chord (list of pitches in normal form) returns inversion with same starting value in pitch space must be entered as normal form """ modInversiontSet = pcInverter(normalChord) sourceSetAsOctMultipliers = [] for entry in normalChord: octMultiplier, modPC = pitchTools.splitOctPs(entry) # gives original order of oct multipliers fo each member of set sourceSetAsOctMultipliers.append(octMultiplier) modInversiontSet = list(modInversiontSet) # do mod 12 transposition invertedChord = pcSetTransposer(modInversiontSet, normalChord[0]) invertedChord = list(invertedChord) #check octaves for i in range(0,len(normalChord)) : sourceOct = sourceSetAsOctMultipliers[i] currentOct, modPC = pitchTools.splitOctPs(invertedChord[i]) if sourceOct == currentOct: pass else: # find difference and make up if sourceOct > currentOct: direction = 'up' else: direction = 'down' distance = abs(currentOct - sourceOct) if direction == 'up': invertedChord[i] = invertedChord[i] + (12 * distance) else: invertedChord[i] = invertedChord[i] - (12 * distance) return tuple(invertedChord)
def getOct(self, valArray, tEvalArray, refDict): """value input is a ps value, need to extract octave information and only process this, then restore it to pitch space""" octArray = [] pcArray = [] # get octave data form ps; micro will not be lost for val in valArray: oct, pc = pitchTools.splitOctPs(val) octArray.append(oct) pcArray.append(pc) # process oct data octArray = self.pmtrObjDict['octQ'](octArray, tEvalArray, refDict) # micro in pc will not be lost valArray = [] for i in range(0, len(octArray)): # restpr w/ pc oct = octArray[i] pc = pcArray[i] valArray.append(pitchTools.joinPsReal(oct, pc, 0)) return valArray
def getOct(self, valArray, tEvalArray, refDict): """value input is a ps value, need to extract octave information and only process this, then restore it to pitch space""" octArray = [] pcArray = [] # get octave data form ps; micro will not be lost for val in valArray: oct, pc = pitchTools.splitOctPs(val) octArray.append(oct) pcArray.append(pc) # process oct data octArray = self.pmtrObjDict['octQ'](octArray, tEvalArray, refDict) # micro in pc will not be lost valArray = [] for i in range(0, len(octArray)): # restpr w/ pc oct = octArray[i] pc = pcArray[i] valArray.append(pitchTools.joinPsReal(oct, pc, 0)) return valArray
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