示例#1
0
 def __call__(self, t=None, refDict=None):
     self.bpm = refDict['bpm']
     if self.valueBuffer == []: # empty
         failCount = 0
         # note that t and refDict are constant within this loop
         while 1:
             q = self.controlObj(t, refDict) # this should be a number
             q = drawer.floatToInt(q)
             if q < 0: # skip values
                 for r in range(-drawer.floatToInt(q)):
                     skip = self.rthmObj(t, refDict) # discard value
             elif q > 0: # repeat values
                 # drop list reprsentation,get object
                 valTriple = self.rthmObj(t, refDict)
                 valObj = self.rthmObj.currentPulse # get pulse object
                 for r in range(q): # pack same value multiple times
                     self.valueBuffer.append((valTriple, valObj)) 
             # force the selection of a new value, examin results
             failCount = failCount + 1        
             if failCount > self.FAILLIMIT and self.valueBuffer == []:
                 print(lang.WARN, self.type, 'no values obtained; supplying value')
                 valTriple = self.rthmObj(t, refDict)
                 valObj = self.rthmObj.currentPulse
                 self.valueBuffer.append((valTriple, valObj))
             # leave loop of values in buffer
             if self.valueBuffer != []: break
     # get value from value buffer
     valTriple, self.currentPulse = self.valueBuffer.pop(0) # get and remove
     if self.currentPulse != None: # use bpm if possible
         self.currentValue = self.currentPulse(self.bpm) # dur, sus, acc 
     else:
         self.currentValue = valTriple
     return self.currentValue
示例#2
0
 def __call__(self, t=None, refDict=None):
     self.bpm = refDict['bpm']
     if self.valueBuffer == []: # empty
         failCount = 0
         # note that t and refDict are constant within this loop
         while 1:
             q = self.controlObj(t, refDict) # this should be a number
             q = drawer.floatToInt(q)
             if q < 0: # skip values
                 for r in range(-drawer.floatToInt(q)):
                     skip = self.rthmObj(t, refDict) # discard value
             elif q > 0: # repeat values
                 # drop list reprsentation,get object
                 valTriple = self.rthmObj(t, refDict)
                 valObj = self.rthmObj.currentPulse # get pulse object
                 for r in range(q): # pack same value multiple times
                     self.valueBuffer.append((valTriple, valObj)) 
             # force the selection of a new value, examin results
             failCount = failCount + 1        
             if failCount > self.FAILLIMIT and self.valueBuffer == []:
                 print lang.WARN, self.type, 'no values obtained; supplying value'
                 valTriple = self.rthmObj(t, refDict)
                 valObj = self.rthmObj.currentPulse
                 self.valueBuffer.append((valTriple, valObj))
             # leave loop of values in buffer
             if self.valueBuffer != []: break
     # get value from value buffer
     valTriple, self.currentPulse = self.valueBuffer.pop(0) # get and remove
     if self.currentPulse != None: # use bpm if possible
         self.currentValue = self.currentPulse(self.bpm) # dur, sus, acc 
     else:
         self.currentValue = valTriple
     return self.currentValue
示例#3
0
 def _ruleFilter(self, rule):
     """self.ruleMax must be defined before calling this
     """
     # ruleMax may be a decimal object, so conver to float before comparing
     # continuous ca have a ruleMax == 1.0
     try:
         if float(self.ruleMax) > 1.0:  # not continuous
             return drawer.floatToInt(rule, 'weight') % self.ruleMax
         else:  # continuous, leave as float, no weighting
             return rule % self.ruleMax
     except OverflowError:  # ruleMax may be very very large, and no float pos
         return drawer.floatToInt(rule, 'weight') % self.ruleMax
示例#4
0
 def _ruleFilter(self, rule):
     """self.ruleMax must be defined before calling this
     """
     # ruleMax may be a decimal object, so conver to float before comparing
     # continuous ca have a ruleMax == 1.0
     try:
         if float(self.ruleMax) > 1.0: # not continuous
             return drawer.floatToInt(rule, 'weight') % self.ruleMax
         else: # continuous, leave as float, no weighting
             return rule % self.ruleMax
     except OverflowError: # ruleMax may be very very large, and no float pos
         return drawer.floatToInt(rule, 'weight') % self.ruleMax
示例#5
0
 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]]
示例#6
0
 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]]
示例#7
0
 def __call__(self, t=None, refDict=None):
     """all rhythm objects must use self.beatT in the 'call' method 
     in order to account for changes in tempo
     """
     self.bpm = refDict['bpm'] # bpm is not used to calc values
     # these are calculated values, not raw pulse values
     d = abs(drawer.floatToInt(self.divObj(t, refDict), 'weight'))
     if d == 0: d = 1
     m = abs(drawer.floatToInt(self.multObj(t, refDict), 'weight'))
     if m == 0: m = 1
     # used to be round; this is no longer done, as acc are implemented
     acc = abs(self.accObj(t, refDict))
     if acc <= 0: acc = 0 # must limit b/n 0 and 1
     elif acc >= 1: acc = 1
     sus = abs(self.susObj(t, refDict)) # dont round or weight
     if sus == 0: sus = 1 # sus of 0 is an error
     # create pulse object
     self.currentPulse = rhythm.Pulse((d, m, acc), 'triple')
     self.currentPulse.setSus(sus)
     self.currentValue = self.currentPulse(self.bpm) # call w/ bpm
     return self.currentValue
示例#8
0
 def __call__(self, t=None, refDict=None):
     """all rhythm objects must use self.beatT in the 'call' method 
     in order to account for changes in tempo
     """
     self.bpm = refDict['bpm'] # bpm is not used to calc values
     # these are calculated values, not raw pulse values
     d = abs(drawer.floatToInt(self.divObj(t, refDict), 'weight'))
     if d == 0: d = 1
     m = abs(drawer.floatToInt(self.multObj(t, refDict), 'weight'))
     if m == 0: m = 1
     # used to be round; this is no longer done, as acc are implemented
     acc = abs(self.accObj(t, refDict))
     if acc <= 0: acc = 0 # must limit b/n 0 and 1
     elif acc >= 1: acc = 1
     sus = abs(self.susObj(t, refDict)) # dont round or weight
     if sus == 0: sus = 1 # sus of 0 is an error
     # create pulse object
     self.currentPulse = rhythm.Pulse((d, m, acc), 'triple')
     self.currentPulse.setSus(sus)
     self.currentValue = self.currentPulse(self.bpm) # call w/ bpm
     return self.currentValue
示例#9
0
 def __call__(self, t=None, refDict=None):
     self.bpm = refDict['bpm']
     
     if self.valueBuffer == []: # empty
         failCount = 0
         # note that t and refDict are static while updating
         while 1:
             pos = self.selector() # get position in obj arary
             q = self.countObj(t, refDict) # this should be a number
             q = drawer.floatToInt(q)
             if q < 0: # skip values
                 for r in range(q): 
                     skip = self.genObj(t, refDict) # discard value
             elif q > 0: # gen values
                 for r in range(q): 
                     # there is a potential problem here if t is not changed
                     # some parameter objects will return the same value
                     valTriple = self.objArray[pos](t, refDict)
                     valObj = self.objArray[pos].currentPulse
                     # must store obj and triple, incase no obj exists
                     self.valueBuffer.append((valTriple, valObj))
             # force the selection of a new value, examine results
             failCount = failCount + 1        
             if failCount > self.FAILLIMIT and self.valueBuffer == []:
                 print(lang.WARN, self.type, 'no values obtained; supplying value')
                 valTriple = self.objArray[pos](t, refDict)
                 valObj = self.objArray[pos].currentPulse
                 self.valueBuffer.append((valTriple, valObj))
             # leave loop if values in buffer
             if self.valueBuffer != []: break
     # get value from value buffer
     valTriple, self.currentPulse = self.valueBuffer.pop(0) # get and remove
     if self.currentPulse != None: # use bpm if possible
         self.currentValue = self.currentPulse(self.bpm) # dur, sus, acc 
     else:
         self.currentValue = valTriple
     return self.currentValue
示例#10
0
 def __call__(self, t=None, refDict=None):
     self.bpm = refDict['bpm']
     
     if self.valueBuffer == []: # empty
         failCount = 0
         # note that t and refDict are static while updating
         while 1:
             pos = self.selector() # get position in obj arary
             q = self.countObj(t, refDict) # this should be a number
             q = drawer.floatToInt(q)
             if q < 0: # skip values
                 for r in range(q): 
                     skip = self.genObj(t, refDict) # discard value
             elif q > 0: # gen values
                 for r in range(q): 
                     # there is a potential problem here if t is not changed
                     # some parameter objects will return the same value
                     valTriple = self.objArray[pos](t, refDict)
                     valObj = self.objArray[pos].currentPulse
                     # must store obj and triple, incase no obj exists
                     self.valueBuffer.append((valTriple, valObj))
             # force the selection of a new value, examine results
             failCount = failCount + 1        
             if failCount > self.FAILLIMIT and self.valueBuffer == []:
                 print lang.WARN, self.type, 'no values obtained; supplying value'
                 valTriple = self.objArray[pos](t, refDict)
                 valObj = self.objArray[pos].currentPulse
                 self.valueBuffer.append((valTriple, valObj))
             # leave loop if values in buffer
             if self.valueBuffer != []: break
     # get value from value buffer
     valTriple, self.currentPulse = self.valueBuffer.pop(0) # get and remove
     if self.currentPulse != None: # use bpm if possible
         self.currentValue = self.currentPulse(self.bpm) # dur, sus, acc 
     else:
         self.currentValue = valTriple
     return self.currentValue
示例#11
0
    def advance(self, ageStep=1):
        """Advance the particle one frame.

        The `ageStep` argumetn can be a function that returns a number or a number (value around 1).
        This value is rounded to the nearest integer; floating point values outside of .5 and 1.5 cause shifts.

        >>> pairs = [('a', 2)]
        >>> a = Particle(pairs)
        >>> a.advance()
        True
        >>> a.advance()
        True
        >>> a.advance()
        False

        >>> pairs = [('a', 2)]
        >>> a = Particle(pairs)
        >>> a.advance(2)
        True
        >>> a.advance(2)
        False

        >>> pairs = [('a', 1), ('b', 1), ('c', 1)]
        >>> a = Particle(pairs)
        >>> a.advance()
        True
        >>> a.state
        'a'
        >>> a.advance()
        True
        >>> a.state
        'b'
        >>> a.advance()
        True
        >>> a.state
        'c'
        >>> a.advance()
        False
        >>> a.state == None
        True
        """
        if drawer.isNum(ageStep):
            ageUnit = ageStep
        else:
            ageUnit = ageStep()  # assume it is a function

        # Probabilistic rounding of floating point values
        ageUnitInt = drawer.floatToInt(ageUnit, 'weight')
        self.age += ageUnitInt

        if self.age > self.lifeSpan:  # must be greater, not >=
            self.state = None
            return False  # cant advance, as is dead
        # check each state in the life bounds, see if this age
        # is within the range of any of those bounds
        for key in self.lifeBounds:
            if (self.age >= self.lifeBounds[key][0]
                    and self.age <= self.lifeBounds[key][1]):
                self.state = key  # assign new state
                break
        return True  # still alive
示例#12
0
    def _scoreMain(self):
        """creates score
        note: octave choose for every note

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('HarmonicAssembly')
        >>> ti.tmName == 'HarmonicAssembly'
        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
        textMaxTimeOffset    = self.getTextStatic('mto', 'time') 
        textFieldLevel = self.getTextStatic('lfp', 'level') 
        textOctaveLevel = self.getTextStatic('lop', 'level')
    
        pLen = self.getPathLen()

        # random generator for creating offset in vetical attacks
        # same technique used in LiteralVertical, DroneArticulate
        self.gaussPmtrObj = parameter.factory(('randomGauss', .5, .1, -1, 1))


        while tCurrent < tEnd:
            # takes absolute value, and proportionally weight toward nearest int
            # modulus of path length
            pathPos = abs(drawer.floatToInt(
                      self.getTextDynamic('multisetPosition', tCurrent), 'weight')) % pLen
    
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            # get number of simultaneities from this multiset
            # count is probabilistic, absolute value; cannot be zero
            multisetCount = abs(drawer.floatToInt(
                self.getTextDynamic('countPerMultiset', tCurrent), 'weight'))
            # make zero == 1; alternatively, make zero a skib and continue
            if multisetCount == 0: multisetCount = 1

            if textFieldLevel == 'set':
                transCurrent = self.getField(tCurrent) # choose PITCHFIELD
            if textOctaveLevel == 'set':
                octCurrent = self.getOct(tCurrent) # choose OCTAVE

            # number of times a simultaneity is drawn
            for k in range(multisetCount):
                if tCurrent > tEnd: break

                # determine how many pitches in this simultaneity
                # abs value, rounded to nearest integer
                simultaneityCount = abs(drawer.floatToInt(
                    self.getTextDynamic('countPerSimultaneity', tCurrent), 'weight'))
                # if zero set to max chord size
                if simultaneityCount == 0: 
                    simultaneityCount = len(chordCurrent)
                elif simultaneityCount > len(chordCurrent):
                    simultaneityCount = len(chordCurrent)

                self.stateUpdate(tCurrent, chordCurrent, None, 
                                      multisetCurrent, None, None)
    
                if textFieldLevel == 'event':
                    transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                if textOctaveLevel == 'event':
                    octCurrent = self.getOct(tCurrent) # choose OCTAVE

                # rhythm, amp, pan, aux: all chosen once per simultaneity
                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)
    
                tThisChord = copy.deepcopy(tCurrent)

                # get each pitch in the simultaneity
                for i in range(simultaneityCount): # pitch in chord

                    # use a generator to get pitches from chord as index values
                    # get values from generator for each pitch in simultaneity
                    # may want to reset parameter object for each chord above
                    # take modulus of chord length; proportional weighting to integer
                    chordPos = abs(drawer.floatToInt(
                          self.getTextDynamic('pitchPosition', tCurrent), 'weight')) % len(chordCurrent)

                    # get position w/n chord
                    ps = chordCurrent[chordPos] 
                    self.stateUpdate(tCurrent, chordCurrent, ps, 
                                          multisetCurrent, None, None)
                                          
                    if textFieldLevel == 'voice':
                        transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                    if textOctaveLevel == 'voice':
                        octCurrent = self.getOct(tCurrent) # choose OCTAVE

                    psReal = pitchTools.psToTempered(ps, octCurrent, 
                                          self.temperamentObj, transCurrent)                                      
                    self.stateUpdate(tCurrent, chordCurrent, ps, 
                                          multisetCurrent, None, psReal)

                    # aux values are drawn here once per voice; 
                    # this is common to TMs: DroneArticulate, DroneSustain
                    auxiliary = self.getAux(tCurrent) # chooose AUX, pack into list
                    # offset value is between -textMaxOffset, 0, and +textMaxOffset
                    offset = self.gaussPmtrObj(0.0) * textMaxTimeOffset
                    tCurrent = tCurrent + offset
                    if tCurrent < 0: # cant start before 0
                        tCurrent = tThisChord # reset
    
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, 
                                                        acc, amp, psReal, pan, auxiliary)
                    self.storeEvent(eventDict)
                    # restore time to tCurrent before processing offset again
                    tCurrent = tThisChord

                # move clocks forward by dur unit
                tCurrent = tCurrent + dur        

        return 1
示例#13
0
    def _scoreMain(self):
        """creates score
        note: octave choose for every note

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('HarmonicShuffle')
        >>> ti.tmName == 'HarmonicShuffle'
        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 static texture values
        textMultisetSelectorControl = self.getTextStatic('msc', 'selectionString')       
        textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') 
        textMaxTimeOffset    = self.getTextStatic('mto', 'time') 
        textFieldLevel = self.getTextStatic('lfp', 'level') 
        textOctaveLevel = self.getTextStatic('lop', 'level')     
  
        pLen = self.getPathLen()
        selectorMultisetPos = basePmtr.Selector(range(pLen),
                                                         textMultisetSelectorControl)

        # random generator for creating offset in vetical attacks
        # same technique used in LiteralVertical, DroneArticulate
        self.gaussPmtrObj = parameter.factory(('randomGauss', .5, .1, -1, 1))

        while tCurrent < tEnd:
            pathPos = selectorMultisetPos() # select path position
    
            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            # get number of simultaneities from this multiset
            # count is probabilistic, absolute value; cannot be zero
            multisetCount = abs(drawer.floatToInt(
                self.getTextDynamic('countPerMultiset', tCurrent), 'weight'))
            # make zero == 1; alternatively, make zero a skib and continue
            if multisetCount == 0: multisetCount = 1

            if textFieldLevel == 'set':
                transCurrent = self.getField(tCurrent) # choose PITCHFIELD
            if textOctaveLevel == 'set':
                octCurrent = self.getOct(tCurrent) # choose OCTAVE

            # number of times a simultaneity is drawn
            for k in range(multisetCount):
                if tCurrent > tEnd: break

                # create a selector to get pitches from chord as index values
                # only need to create one for each chord
                selectorChordPos = basePmtr.Selector(range(len(chordCurrent)),
                                                                 textPitchSelectorControl)

                # determine how many pitches in this simultaneity
                # abs value, rounded to nearest integer
                simultaneityCount = abs(drawer.floatToInt(
                    self.getTextDynamic('countPerSimultaneity', tCurrent), 'weight'))
                # if zero set to max chord size
                if simultaneityCount == 0: 
                    simultaneityCount = len(chordCurrent)
                elif simultaneityCount > len(chordCurrent):
                    simultaneityCount = len(chordCurrent)

                self.stateUpdate(tCurrent, chordCurrent, None, 
                                      multisetCurrent, None, None)
    
                if textFieldLevel == 'event':
                    transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                if textOctaveLevel == 'event':
                    octCurrent = self.getOct(tCurrent) # choose OCTAVE

                # rhythm, amp, pan, aux: all chosen once per simultaneity
                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)
    
                tThisChord = copy.deepcopy(tCurrent)

                # get each pitch in the simultaneity
                for i in range(simultaneityCount): # pitch in chord

                    ps = chordCurrent[selectorChordPos()] # get position w/n chord
                    self.stateUpdate(tCurrent, chordCurrent, ps, 
                                          multisetCurrent, None, None)
                                          
                    if textFieldLevel == 'voice':
                        transCurrent = self.getField(tCurrent) # choose PITCHFIELD
                    if textOctaveLevel == 'voice':
                        octCurrent = self.getOct(tCurrent) # choose OCTAVE

                    psReal = pitchTools.psToTempered(ps, octCurrent, 
                                          self.temperamentObj, transCurrent)                                      
                    self.stateUpdate(tCurrent, chordCurrent, ps, 
                                          multisetCurrent, None, psReal)

                    # aux values are drawn here once per voice; 
                    # this is common to TMs: DroneArticulate, DroneSustain
                    auxiliary = self.getAux(tCurrent) # chooose AUX, pack into list
                    # offset value is between -textMaxOffset, 0, and +textMaxOffset
                    offset = self.gaussPmtrObj(0.0) * textMaxTimeOffset
                    tCurrent = tCurrent + offset
                    if tCurrent < 0: # cant start before 0
                        tCurrent = tThisChord # reset
    
                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, 
                                                        acc, amp, psReal, pan, auxiliary)
                    self.storeEvent(eventDict)
                    # restore time to tCurrent before processing offset again
                    tCurrent = tThisChord

                # move clocks forward by dur unit
                tCurrent = tCurrent + dur        

        return 1
示例#14
0
    def advance(self, ageStep=1):
        """Advance the particle one frame.

        The `ageStep` argumetn can be a function that returns a number or a number (value around 1).
        This value is rounded to the nearest integer; floating point values outside of .5 and 1.5 cause shifts.

        >>> pairs = [('a', 2)]
        >>> a = Particle(pairs)
        >>> a.advance()
        True
        >>> a.advance()
        True
        >>> a.advance()
        False

        >>> pairs = [('a', 2)]
        >>> a = Particle(pairs)
        >>> a.advance(2)
        True
        >>> a.advance(2)
        False

        >>> pairs = [('a', 1), ('b', 1), ('c', 1)]
        >>> a = Particle(pairs)
        >>> a.advance()
        True
        >>> a.state
        'a'
        >>> a.advance()
        True
        >>> a.state
        'b'
        >>> a.advance()
        True
        >>> a.state
        'c'
        >>> a.advance()
        False
        >>> a.state == None
        True
        """
        if drawer.isNum(ageStep):
            ageUnit = ageStep
        else:
            ageUnit = ageStep() # assume it is a function

        # Probabilistic rounding of floating point values
        ageUnitInt = drawer.floatToInt(ageUnit, 'weight')
        self.age += ageUnitInt

        if self.age > self.lifeSpan: # must be greater, not >=
            self.state = None
            return False # cant advance, as is dead
        # check each state in the life bounds, see if this age
        # is within the range of any of those bounds
        for key in self.lifeBounds:
            if (self.age >= self.lifeBounds[key][0] and self.age <= 
                self.lifeBounds[key][1]):
                self.state = key # assign new state
                break
        return True # still alive
示例#15
0
    def _scoreMain(self):
        """creates score
        note: octave choose for every note

        >>> from athenaCL.libATH.libTM import texture
        >>> ti = texture.factory('HarmonicShuffle')
        >>> ti.tmName == 'HarmonicShuffle'
        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 static texture values
        textMultisetSelectorControl = self.getTextStatic("msc", "selectionString")
        textPitchSelectorControl = self.getTextStatic("psc", "selectionString")
        textMaxTimeOffset = self.getTextStatic("mto", "time")
        textFieldLevel = self.getTextStatic("lfp", "level")
        textOctaveLevel = self.getTextStatic("lop", "level")

        pLen = self.getPathLen()
        selectorMultisetPos = basePmtr.Selector(range(pLen), textMultisetSelectorControl)

        # random generator for creating offset in vetical attacks
        # same technique used in LiteralVertical, DroneArticulate
        self.gaussPmtrObj = parameter.factory(("randomGauss", 0.5, 0.1, -1, 1))

        while tCurrent < tEnd:
            pathPos = selectorMultisetPos()  # select path position

            chordCurrent = self.getPitchGroup(pathPos)
            multisetCurrent = self.getMultiset(pathPos)

            # get number of simultaneities from this multiset
            # count is probabilistic, absolute value; cannot be zero
            multisetCount = abs(drawer.floatToInt(self.getTextDynamic("countPerMultiset", tCurrent), "weight"))
            # make zero == 1; alternatively, make zero a skib and continue
            if multisetCount == 0:
                multisetCount = 1

            if textFieldLevel == "set":
                transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
            if textOctaveLevel == "set":
                octCurrent = self.getOct(tCurrent)  # choose OCTAVE

            # number of times a simultaneity is drawn
            for k in range(multisetCount):
                if tCurrent > tEnd:
                    break

                # create a selector to get pitches from chord as index values
                # only need to create one for each chord
                selectorChordPos = basePmtr.Selector(range(len(chordCurrent)), textPitchSelectorControl)

                # determine how many pitches in this simultaneity
                # abs value, rounded to nearest integer
                simultaneityCount = abs(
                    drawer.floatToInt(self.getTextDynamic("countPerSimultaneity", tCurrent), "weight")
                )
                # if zero set to max chord size
                if simultaneityCount == 0:
                    simultaneityCount = len(chordCurrent)
                elif simultaneityCount > len(chordCurrent):
                    simultaneityCount = len(chordCurrent)

                self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None)

                if textFieldLevel == "event":
                    transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
                if textOctaveLevel == "event":
                    octCurrent = self.getOct(tCurrent)  # choose OCTAVE

                # rhythm, amp, pan, aux: all chosen once per simultaneity
                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)

                tThisChord = copy.deepcopy(tCurrent)

                # get each pitch in the simultaneity
                for i in range(simultaneityCount):  # pitch in chord

                    ps = chordCurrent[selectorChordPos()]  # get position w/n chord
                    self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None)

                    if textFieldLevel == "voice":
                        transCurrent = self.getField(tCurrent)  # choose PITCHFIELD
                    if textOctaveLevel == "voice":
                        octCurrent = self.getOct(tCurrent)  # choose OCTAVE

                    psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent)
                    self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal)

                    # aux values are drawn here once per voice;
                    # this is common to TMs: DroneArticulate, DroneSustain
                    auxiliary = self.getAux(tCurrent)  # chooose AUX, pack into list
                    # offset value is between -textMaxOffset, 0, and +textMaxOffset
                    offset = self.gaussPmtrObj(0.0) * textMaxTimeOffset
                    tCurrent = tCurrent + offset
                    if tCurrent < 0:  # cant start before 0
                        tCurrent = tThisChord  # reset

                    eventDict = self.makeEvent(tCurrent, bpm, pulse, dur, sus, acc, amp, psReal, pan, auxiliary)
                    self.storeEvent(eventDict)
                    # restore time to tCurrent before processing offset again
                    tCurrent = tThisChord

                # move clocks forward by dur unit
                tCurrent = tCurrent + dur

        return 1