def transform(self, particleArray): '''Given an array of Particles, select one and process ''' if len(particleArray) == 0: # empty return None pIndex = random.choice(range(len(particleArray))) p = particleArray[pIndex] # only process if state matches current state of this particle if p.getState() != self.getState(): return particleArray # return unaltered reference # find transform if self.getState() not in self.transformMap.keys(): return None weights = [] options = [] for o, w in self.transformMap[self.getState()]: weights.append(w) options.append(o) boundary = unit.unitBoundaryProportion(weights) i = unit.unitBoundaryPos(random.random(), boundary) result = options[i] # index is in position if result == None: # remove #environment.printDebug(['transform(); removing particle:', p]) particleArray.pop(pIndex) # if a string value the same as the current state of the particle elif result == p.getState(): pass # do nothing else: # not yet implemented: need to convert do a different state # for this wee need a life cycle argument pass
def next(self, unitVal, previous, order, slide=1): """generate the next value of the a new chain unitVal is floating point number b/n 0 and 1; can be generated by any distribution. this value determines the selection of values previous is a list of values that will be analaized if the list is insufficiant for the order, if slide, will use next available order, otherwise, will use zero order order may be a float; if so it will use weighting from drawer """ symbols = list(self._symbols.keys()) # get appropriate order: if a float, will be dynamically allocated order = drawer.floatToInt(order, 'weight') if order not in list(range(0, self._ordersSrc[-1]+1)): order = self._ordersSrc[-1] # use highest defined #print _MOD, 'using order', order # get appropriate key of given length of previous prevLen = len(previous) if prevLen <= order: # if less then specified by order if slide: # use length as order srcSeq = self._valueListToSymbolList(previous) else: srcSeq = () # jump to zeroth else: # if values are greater in length than order if order == 0: srcSeq = () else: srcSeq = self._valueListToSymbolList(previous[-order:]) # determine of there is a direct match, or an expression match wList = self._findWeights(srcSeq) # may return None # if none, will create equal distribution of all symbols # return parallel lists of weights, symbols, both in same order wPost, sDeclared = self._scrubWeights(wList) #print _MOD, 'order, wPost, sDeclared', order, wPost, sDeclared boundary = unit.unitBoundaryProportion(wPost) i = unit.unitBoundaryPos(unitVal, boundary) # get symbol, then de-signify symbols into the store value return self._symbols[sDeclared[i]]
def next(self, unitVal, previous, order, slide=1): """generate the next value of the a new chain unitVal is floating point number b/n 0 and 1; can be generated by any distribution. this value determines the selection of values previous is a list of values that will be analaized if the list is insufficiant for the order, if slide, will use next available order, otherwise, will use zero order order may be a float; if so it will use weighting from drawer """ symbols = self._symbols.keys() # get appropriate order: if a float, will be dynamically allocated order = drawer.floatToInt(order, 'weight') if order not in range(0, self._ordersSrc[-1]+1): order = self._ordersSrc[-1] # use highest defined #print _MOD, 'using order', order # get appropriate key of given length of previous prevLen = len(previous) if prevLen <= order: # if less then specified by order if slide: # use length as order srcSeq = self._valueListToSymbolList(previous) else: srcSeq = () # jump to zeroth else: # if values are greater in length than order if order == 0: srcSeq = () else: srcSeq = self._valueListToSymbolList(previous[-order:]) # determine of there is a direct match, or an expression match wList = self._findWeights(srcSeq) # may return None # if none, will create equal distribution of all symbols # return parallel lists of weights, symbols, both in same order wPost, sDeclared = self._scrubWeights(wList) #print _MOD, 'order, wPost, sDeclared', order, wPost, sDeclared boundary = unit.unitBoundaryProportion(wPost) i = unit.unitBoundaryPos(unitVal, boundary) # get symbol, then de-signify symbols into the store value return self._symbols[sDeclared[i]]
def __next__(self): '''Apply all rules and produce a new self._state >>> g = Grammar() >>> g.load('a{3}b{4} @ a{bab}b{aab} @ abaa') >>> str(g) 'a{3}b{4}@a{bab}b{aab}@abaa' >>> g.next() >>> g.getState() 'babaabbabbab' >>> g.next() >>> g.getState() 'aabbabaabbabbabaabaabbabaabaabbabaab' >>> g.getState(values=True) [3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0] >>> g = Grammar() >>> g.load('a{3}b{4}c{20}d{2} @ a{bab}b{acb}c{ac}d{cd} @ abd') >>> str(g) 'a{3}b{4}c{20}d{2}@a{bab}c{ac}b{acb}d{cd}@abd' >>> g.next() >>> g.getState() 'babacbcd' >>> g.next() >>> g.getState() 'acbbabacbbabacacbaccd' >>> g = Grammar() >>> g.load('a{a}b{b} @ a{ab}b{a} @ b') >>> g.getState() 'b' >>> g.next() >>> g.getState() 'a' >>> g.next() >>> g.getState() 'ab' >>> g.next() >>> g.getState() 'aba' >>> g.next() >>> g.getState() 'abaab' >>> g.next() >>> g.getState() 'abaababa' ''' if self._state == None or self._state == '': self._state = self._axiom # a copy in principle stateNew = self._state # copy matchTag = [] # matched start indices replacementCount = 0 # make groups of index values, src groups to match # need to find largest rule in size indexCharPairs = [] # self._maxRuleOutputSize #environment.printDebug(['next(): self._state', self._state]) for size in range(1, self._maxRuleOutputSize + 1): #for size in range(1, 2): for i in range(0, len(self._state), size): pair = (i, self._state[i:i + size]) if pair not in indexCharPairs: indexCharPairs.append(pair) for inRule, outRule in list(self._rules.items()): environment.printDebug( ['next(): in/out rule', repr(inRule), outRule]) # grammar.py: next(): in/out rule '*' [('ab',1)] #environment.printDebug(['next(): index char pairs', indexCharPairs]) # char here may be 1 or more characters, up to max rule size for i, char in indexCharPairs: #for i, char in enumerate(self._state): # comparison to rule match = False # test single character, exact match if inRule == self.EXPRESSALL or inRule == char: match = True # if mutliple characters, and one is expressall, and lenght # is the same elif (len(inRule) > 1 and len(inRule) == len(char) and self.EXPRESSALL in inRule): matchChar = 0 for j in range(len(inRule)): if inRule[j] == char[j] or inRule[j] == self.EXPRESSALL: matchChar += 1 if matchChar == len(inRule): match = True if not match: continue # need to find cases of two or more char matches # store a string of index in the temp to mark positions # can find first instance of symbol; will not # be past symbols b/c we are replacing with the old index nums iNew = stateNew.find(char) pre = stateNew[:iNew] # skip location post = stateNew[iNew + len(char):] # insert marker as a random cod tag = self._tagIn(replacementCount) replacementCount += 1 stateNew = pre + tag + post #environment.printDebug(['next(): stateNew', stateNew, repr(pre), repr(tag), repr(post)]) # make a rule section # if only one rule, simply provide it if len(outRule) == 1: # a list of value, weight pairSymbol replacement = outRule[0][0] # if more than one rule, do a weighted selection else: options = [] weights = [] for o, w in outRule: options.append(o) weights.append(w) # create unit boundaries from ordered weights boundary = unit.unitBoundaryProportion(weights) i = unit.unitBoundaryPos(random.random(), boundary) replacement = options[i] # index is in position # a lost of all replacements to make, between the tag and the # replacement matchTag.append([tag, replacement]) # do all replacements #environment.printDebug(['stateNew: prereplace', stateNew]) for tag, replacement in matchTag: # these are not actual indices but tags to points in the scratch iNew = stateNew.find(tag) pre = stateNew[:iNew] # skip location post = stateNew[iNew + len(tag):] # insert final value stateNew = pre + replacement + post #environment.printDebug(['stateNew: post', stateNew]) # replace old self._state = stateNew
def _scoreMain(self): """creates score note: octave choose for every note >>> from athenaCL.libATH.libTM import texture >>> ti = texture.factory('TimeSegment') >>> ti.tmName == 'TimeSegment' True >>> ti.loadDefault() >>> ti.score() == True True """ # texture-wide time elements inst = self.getInst() # needed for preliminary parameter values # tStart, tEnd = self.getTimeRange() # tCurrent = tStart # get field, octave selection method value textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') # this is level tt event count numbers are applied (not count itself) textLevelEventCount = self.getTextStatic('lec', 'level') textTotalSegmentCount = self.getTextStatic('tsc', 'count') segmentManifest = [] # store [count, segWeight, start, end] # process segments first, determine events per segemtn tSeg = 0 if textLevelEventCount == 'segment': # event count per segement for q in range(textTotalSegmentCount): eventCount = self.getTextDynamic('eventCountGenerator', tSeg) segmentManifest.append([int(round(eventCount))]) # store as list tSeg = tSeg + 1 elif textLevelEventCount == 'count': # event count is total # get one value and divide eventCount = self.getTextDynamic('eventCountGenerator', tSeg) segEventCount = int(round((eventCount/textTotalSegmentCount))) if segEventCount <= 0: segEventCount = 1 # force minimum per seg for q in range(textTotalSegmentCount): segmentManifest.append([segEventCount]) # store as list #print _MOD, 'levelEventCount', textLevelEventCount #print _MOD, 'textTotalSegmentCount', textTotalSegmentCount #print _MOD, 'segmentManifest', segmentManifest # get total duration tStart, tEnd = self.getTimeRange() tDurSpan = tEnd - tStart # not final dur, but time start span # get segment proportions tSeg = 0 # segment count as event step size segmentWidth = [] # store widths before getting scaled size for q in range(textTotalSegmentCount): # what if segment widht is zero? val = self.getTextDynamic('segmentWidthGenerator', tSeg) if val <= 0: pass # continue or warn? segmentWidth.append(val) tSeg = tSeg + 1 # transfrom segment width into a collection of boundaries #print _MOD, 'segmentWidth', segmentWidth segmentBounds = unit.unitBoundaryProportion(segmentWidth) for q in range(textTotalSegmentCount): s, m, e = segmentBounds[q] segmentManifest[q].append(s * tDurSpan) segmentManifest[q].append(e * tDurSpan) #print _MOD, 'segmentWidth', segmentManifest # get texture start time as init time tCurrent = tStart # defined abovie # if field/oct vals are taken once per set, pre calculate and store # in a list; access from this list with pathPos index fieldValBuf = [] if textFieldLevel == 'set': for q in range(self.getPathLen()): s, e = self.clockPoints(q) # use path df start time fieldValBuf.append(self.getField(s)) octValBuf = [] if textOctaveLevel == 'set': for q in range(self.getPathLen()): s, e = self.clockPoints(q) octValBuf.append(self.getOct(s)) # iterate through segments in order for segPos in range(textTotalSegmentCount): segEventCount = segmentManifest[segPos][0] # count is first in list tStartSeg = segmentManifest[segPos][1] tEndSeg = segmentManifest[segPos][2] # create events for thsi segment #print _MOD, 'segPos', segPos for i in range(segEventCount): # # get generator value w/n unit interval tUnit = unit.limit(self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSeg, tEndSeg) pathPos = self.clockFindPos(tCurrent) # get pos for current time if pathPos == None: raise ValueError, 'tCurrent out of all time ranges' #print _MOD, 'pp, tc', pathPos, tCurrent #print _MOD, 'tss, tes', tStartSeg, tEndSeg # need to determin path position based on time point of event chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector(range(0,len(chordCurrent)), textPitchSelectorControl) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord # a if the division of path dfs is w/n a single segment # either side of the path may occur more than once. # perhaps pre calculate and store in a list? if textFieldLevel == 'event': # every event transCurrent = self.getField(tCurrent) # choose PITCHFIELD elif textFieldLevel == 'set': transCurrent = fieldValBuf[pathPos] # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE elif textOctaveLevel == 'set': octCurrent = octValBuf[pathPos] # choose OCTAVE #print _MOD, 'pathPos, oct, t', pathPos, octCurrent, tCurrent psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent) self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal) bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) if acc == 0 and not self.silenceMode: # this is a rest tCurrent = tCurrent + dur continue amp = self.getAmp(tCurrent) * acc # choose amp, pan pan = self.getPan(tCurrent) auxiliary = self.getAux(tCurrent) # chooose AUX, pack into list eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, amp, psReal, pan, auxiliary) self.storeEvent(eventDict) # tCurrent = tCurrent + dur # move clocks forward by dur unit # self.clockForward() # advances path positon return 1
def _scoreMain(self): """creates score note: octave choose for every note >>> from athenaCL.libATH.libTM import texture >>> ti = texture.factory('TimeSegment') >>> ti.tmName == 'TimeSegment' True >>> ti.loadDefault() >>> ti.score() == True True """ # texture-wide time elements inst = self.getInst() # needed for preliminary parameter values # tStart, tEnd = self.getTimeRange() # tCurrent = tStart # get field, octave selection method value textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') # this is level tt event count numbers are applied (not count itself) textLevelEventCount = self.getTextStatic('lec', 'level') textTotalSegmentCount = self.getTextStatic('tsc', 'count') segmentManifest = [] # store [count, segWeight, start, end] # process segments first, determine events per segemtn tSeg = 0 if textLevelEventCount == 'segment': # event count per segement for q in range(textTotalSegmentCount): eventCount = self.getTextDynamic('eventCountGenerator', tSeg) segmentManifest.append([int(round(eventCount)) ]) # store as list tSeg = tSeg + 1 elif textLevelEventCount == 'count': # event count is total # get one value and divide eventCount = self.getTextDynamic('eventCountGenerator', tSeg) segEventCount = int(round((eventCount / textTotalSegmentCount))) if segEventCount <= 0: segEventCount = 1 # force minimum per seg for q in range(textTotalSegmentCount): segmentManifest.append([segEventCount]) # store as list #print _MOD, 'levelEventCount', textLevelEventCount #print _MOD, 'textTotalSegmentCount', textTotalSegmentCount #print _MOD, 'segmentManifest', segmentManifest # get total duration tStart, tEnd = self.getTimeRange() tDurSpan = tEnd - tStart # not final dur, but time start span # get segment proportions tSeg = 0 # segment count as event step size segmentWidth = [] # store widths before getting scaled size for q in range(textTotalSegmentCount): # what if segment widht is zero? val = self.getTextDynamic('segmentWidthGenerator', tSeg) if val <= 0: pass # continue or warn? segmentWidth.append(val) tSeg = tSeg + 1 # transfrom segment width into a collection of boundaries #print _MOD, 'segmentWidth', segmentWidth segmentBounds = unit.unitBoundaryProportion(segmentWidth) for q in range(textTotalSegmentCount): s, m, e = segmentBounds[q] segmentManifest[q].append(s * tDurSpan) segmentManifest[q].append(e * tDurSpan) #print _MOD, 'segmentWidth', segmentManifest # get texture start time as init time tCurrent = tStart # defined abovie # if field/oct vals are taken once per set, pre calculate and store # in a list; access from this list with pathPos index fieldValBuf = [] if textFieldLevel == 'set': for q in range(self.getPathLen()): s, e = self.clockPoints(q) # use path df start time fieldValBuf.append(self.getField(s)) octValBuf = [] if textOctaveLevel == 'set': for q in range(self.getPathLen()): s, e = self.clockPoints(q) octValBuf.append(self.getOct(s)) # iterate through segments in order for segPos in range(textTotalSegmentCount): segEventCount = segmentManifest[segPos][ 0] # count is first in list tStartSeg = segmentManifest[segPos][1] tEndSeg = segmentManifest[segPos][2] # create events for thsi segment #print _MOD, 'segPos', segPos for i in range(segEventCount): # # get generator value w/n unit interval tUnit = unit.limit( self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSeg, tEndSeg) pathPos = self.clockFindPos( tCurrent) # get pos for current time if pathPos == None: raise ValueError, 'tCurrent out of all time ranges' #print _MOD, 'pp, tc', pathPos, tCurrent #print _MOD, 'tss, tes', tStartSeg, tEndSeg # need to determin path position based on time point of event chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector( range(0, len(chordCurrent)), textPitchSelectorControl) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord # a if the division of path dfs is w/n a single segment # either side of the path may occur more than once. # perhaps pre calculate and store in a list? if textFieldLevel == 'event': # every event transCurrent = self.getField(tCurrent) # choose PITCHFIELD elif textFieldLevel == 'set': transCurrent = fieldValBuf[pathPos] # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE elif textOctaveLevel == 'set': octCurrent = octValBuf[pathPos] # choose OCTAVE #print _MOD, 'pathPos, oct, t', pathPos, octCurrent, tCurrent psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent) self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal) bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) if acc == 0 and not self.silenceMode: # this is a rest tCurrent = tCurrent + dur continue amp = self.getAmp(tCurrent) * acc # choose amp, pan pan = self.getPan(tCurrent) auxiliary = self.getAux( tCurrent) # chooose AUX, pack into list eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, amp, psReal, pan, auxiliary) self.storeEvent(eventDict) # tCurrent = tCurrent + dur # move clocks forward by dur unit # self.clockForward() # advances path positon return 1
def next(self): '''Apply all rules and produce a new self._state >>> g = Grammar() >>> g.load('a{3}b{4} @ a{bab}b{aab} @ abaa') >>> str(g) 'a{3}b{4}@a{bab}b{aab}@abaa' >>> g.next() >>> g.getState() 'babaabbabbab' >>> g.next() >>> g.getState() 'aabbabaabbabbabaabaabbabaabaabbabaab' >>> g.getState(values=True) [3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0, 3.0, 3.0, 4.0, 4.0, 3.0, 4.0, 3.0, 3.0, 4.0] >>> g = Grammar() >>> g.load('a{3}b{4}c{20}d{2} @ a{bab}b{acb}c{ac}d{cd} @ abd') >>> str(g) 'a{3}b{4}c{20}d{2}@a{bab}c{ac}b{acb}d{cd}@abd' >>> g.next() >>> g.getState() 'babacbcd' >>> g.next() >>> g.getState() 'acbbabacbbabacacbaccd' >>> g = Grammar() >>> g.load('a{a}b{b} @ a{ab}b{a} @ b') >>> g.getState() 'b' >>> g.next() >>> g.getState() 'a' >>> g.next() >>> g.getState() 'ab' >>> g.next() >>> g.getState() 'aba' >>> g.next() >>> g.getState() 'abaab' >>> g.next() >>> g.getState() 'abaababa' ''' if self._state == None or self._state == '': self._state = self._axiom # a copy in principle stateNew = self._state # copy matchTag = [] # matched start indices replacementCount = 0 # make groups of index values, src groups to match # need to find largest rule in size indexCharPairs = [] # self._maxRuleOutputSize #environment.printDebug(['next(): self._state', self._state]) for size in range(1, self._maxRuleOutputSize+1): #for size in range(1, 2): for i in range(0, len(self._state), size): pair = (i, self._state[i:i+size]) if pair not in indexCharPairs: indexCharPairs.append(pair) for inRule, outRule in self._rules.items(): environment.printDebug(['next(): in/out rule', repr(inRule), outRule]) # grammar.py: next(): in/out rule '*' [('ab',1)] #environment.printDebug(['next(): index char pairs', indexCharPairs]) # char here may be 1 or more characters, up to max rule size for i, char in indexCharPairs: #for i, char in enumerate(self._state): # comparison to rule match = False # test single character, exact match if inRule == self.EXPRESSALL or inRule == char: match = True # if mutliple characters, and one is expressall, and lenght # is the same elif (len(inRule) > 1 and len(inRule) == len(char) and self.EXPRESSALL in inRule): matchChar = 0 for j in range(len(inRule)): if inRule[j] == char[j] or inRule[j] == self.EXPRESSALL: matchChar += 1 if matchChar == len(inRule): match = True if not match: continue # need to find cases of two or more char matches # store a string of index in the temp to mark positions # can find first instance of symbol; will not # be past symbols b/c we are replacing with the old index nums iNew = stateNew.find(char) pre = stateNew[:iNew] # skip location post = stateNew[iNew+len(char):] # insert marker as a random cod tag = self._tagIn(replacementCount) replacementCount += 1 stateNew = pre + tag + post #environment.printDebug(['next(): stateNew', stateNew, repr(pre), repr(tag), repr(post)]) # make a rule section # if only one rule, simply provide it if len(outRule) == 1: # a list of value, weight pairSymbol replacement = outRule[0][0] # if more than one rule, do a weighted selection else: options = [] weights = [] for o, w in outRule: options.append(o) weights.append(w) # create unit boundaries from ordered weights boundary = unit.unitBoundaryProportion(weights) i = unit.unitBoundaryPos(random.random(), boundary) replacement = options[i] # index is in position # a lost of all replacements to make, between the tag and the # replacement matchTag.append([tag, replacement]) # do all replacements #environment.printDebug(['stateNew: prereplace', stateNew]) for tag, replacement in matchTag: # these are not actual indices but tags to points in the scratch iNew = stateNew.find(tag) pre = stateNew[:iNew] # skip location post = stateNew[iNew+len(tag):] # insert final value stateNew = pre + replacement + post #environment.printDebug(['stateNew: post', stateNew]) # replace old self._state = stateNew