def durToAdsr(tStart, propAbsSwitch, dur, attack, decay, sustain, release, susScalar, min=0, max=1): """create an adsr envelope sustain scalar is a value, w/n the unit interval, of the difference between min and max >>> durToAdsr(0, 'absolute', 10, 2, 1, 2, 2, .5) [[0, 0.0], [2, 1.0], [3, 0.5], [5, 0.5], [7, 0.0], [9.999..., 0.0]] """ # will automatically sort min, max peak = unit.denorm(1, min, max) nadir = unit.denorm(0, min, max) susLevel = (peak - nadir) * unit.limit(susScalar) if propAbsSwitch not in ['absolute', 'proportional']: raise error.ParameterObjectSyntaxError('incorrect switch') if propAbsSwitch == 'absolute': timeUnitDenorm = [attack, decay, sustain, release] if sum(timeUnitDenorm) > dur: # force proportional propAbsSwitch = 'proportional' if propAbsSwitch == 'proportional': timeUnit = unit.unitNormProportion([attack, decay, sustain, release]) timeUnitDenorm = [x * dur for x in timeUnit] tEnd = tStart + dur t = tStart envelope = [] envelope.append([t, nadir]) t = t + _stepFilter(timeUnitDenorm[0]) # attack envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[1]) # decay envelope.append([t, susLevel]) t = t + _stepFilter(timeUnitDenorm[2]) # sustain envelope.append([t, susLevel]) if propAbsSwitch == 'proportional': t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) else: # absolute t = t + _stepFilter(timeUnitDenorm[3]) # sustain envelope.append([t, nadir]) t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) return envelope
def durToTrapezoid(tStart, propAbsSwitch, dur, rampUp, widthMax, rampDown, widthMin, min=0, max=1): """assume dir of peal is widthOn will automatically convert to proportion if abs sum extends past dur this is an trapezoid with only one ramp; may not have complete duration time; always leads on >>> durToTrapezoid(0, 'absolute', 10, 3, 3, 3, .5) [[0, 0.0], [3, 1.0], [6, 1.0], [9, 0.0], [9.999..., 0.0]] """ # will automatically sort min, max peak = unit.denorm(1, min, max) nadir = unit.denorm(0, min, max) if propAbsSwitch not in ['absolute', 'proportional']: raise error.ParameterObjectSyntaxError('incorrect switch') if propAbsSwitch == 'absolute': timeUnitDenorm = [rampUp, widthMax, rampDown, widthMin] if sum(timeUnitDenorm) > dur: # force proportional propAbsSwitch = 'proportional' if propAbsSwitch == 'proportional': timeUnit = unit.unitNormProportion( [rampUp, widthMax, rampDown, widthMin]) timeUnitDenorm = [x * dur for x in timeUnit] tEnd = tStart + dur t = tStart envelope = [] envelope.append([t, nadir]) t = t + _stepFilter(timeUnitDenorm[0]) # ramp envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[1]) # width envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[2]) # ramp envelope.append([t, nadir]) t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) return envelope
def durToAdsr(tStart, propAbsSwitch, dur, attack, decay, sustain, release, susScalar, min=0, max=1): """create an adsr envelope sustain scalar is a value, w/n the unit interval, of the difference between min and max >>> durToAdsr(0, 'absolute', 10, 2, 1, 2, 2, .5) [[0, 0.0], [2, 1.0], [3, 0.5], [5, 0.5], [7, 0.0], [9.999..., 0.0]] """ # will automatically sort min, max peak = unit.denorm(1, min, max) nadir = unit.denorm(0, min, max) susLevel = (peak-nadir) * unit.limit(susScalar) if propAbsSwitch not in ['absolute', 'proportional']: raise error.ParameterObjectSyntaxError, 'incorrect switch' if propAbsSwitch == 'absolute': timeUnitDenorm = [attack, decay, sustain, release] if sum(timeUnitDenorm) > dur: # force proportional propAbsSwitch = 'proportional' if propAbsSwitch == 'proportional': timeUnit = unit.unitNormProportion([attack, decay, sustain, release]) timeUnitDenorm = [x*dur for x in timeUnit] tEnd = tStart + dur t = tStart envelope = [] envelope.append([t, nadir]) t = t + _stepFilter(timeUnitDenorm[0]) # attack envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[1]) # decay envelope.append([t, susLevel]) t = t + _stepFilter(timeUnitDenorm[2]) # sustain envelope.append([t, susLevel]) if propAbsSwitch == 'proportional': t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) else: # absolute t = t + _stepFilter(timeUnitDenorm[3]) # sustain envelope.append([t, nadir]) t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) return envelope
def durToUnit(tStart, dur, center, width, min=0, max=1): """ this unit envelope is based on a csound model here iAttack = ((1 - iSusPcent) * iSusCenterPcent) * iDur iRelease = ((1 - iSusPcent) * (1-iSusCenterPcent)) * iDur kAmp linen iAmp, iAttack, iDur, iRelease >>> durToUnit(0, 10, .5, .5) [[0, 0.0], [2.5, 1.0], [7.5, 1.0], [9.999..., 0.0]] """ # will automatically sort min, max peak = unit.denorm(1, min, max) nadir = unit.denorm(0, min, max) # normalize w/n unit interval center = unit.limit(center) width = unit.limit(width) # must be greater or smaller than 0/1 to avoid double points at same x # or, worse, the alst event not being the last if center >= 1: center = center - OFFSET if center <= 0: center = center + OFFSET if width >= 1: width = width - OFFSET if width <= 0: width = width + OFFSET rampUp = ((1 - width) * center) * dur rampDown = ((1 - width) * (1 - center)) * dur center = width * dur timeUnitDenorm = [rampUp, center, rampDown] tEnd = tStart + dur t = tStart envelope = [] envelope.append([t, nadir]) t = t + timeUnitDenorm[0] # ramp envelope.append([t, peak]) t = t + timeUnitDenorm[1] # width envelope.append([t, peak]) t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) return envelope
def unitSynthesizer(self, xList, method=None): """scale values to the bit depth pack into a list, convert to string data assumes that values are normalized b/n 0 and 1 direct; scales value in range of 0 to 1 between -max and amx """ # for i in range(len(xList)): # xList[i] = unit.limit(xList[i]) zList = [] max = byteToInt(self.bytes) #print _MOD, max if method in [None, 'direct']: for x in xList: valSigned = int(round(unit.denorm(x, -max, max))) # add a value for each channel for ch in range(self.ch): zList.append(valSigned) # thee use zero crossings to effect sig of the wave form elif method in ['reflect']: sign = 1 # 1 is positive for x in xList: val = unit.denorm(x, 0, max) if val == 0: # only change sign at zero crossing if sign == 1: sign = -1 else: sign = 1 valSigned = val*sign # add a value for each channel for ch in range(self.ch): zList.append(valSigned) elif method == 'fold': sign = 1 # 1 is positive for x in xList: val = abs(unit.denorm(x, -max, max)) # abs of full range if val == 0: # only change sign at zero crossing if sign == 1: sign = -1 else: sign = 1 valSigned = val*sign # add a value for each channel for ch in range(self.ch): zList.append(valSigned) #print zList return array.array("h", zList).tostring()
def durToTrapezoid(tStart, propAbsSwitch, dur, rampUp, widthMax, rampDown, widthMin, min=0, max=1): """assume dir of peal is widthOn will automatically convert to proportion if abs sum extends past dur this is an trapezoid with only one ramp; may not have complete duration time; always leads on >>> durToTrapezoid(0, 'absolute', 10, 3, 3, 3, .5) [[0, 0.0], [3, 1.0], [6, 1.0], [9, 0.0], [9.999..., 0.0]] """ # will automatically sort min, max peak = unit.denorm(1, min, max) nadir = unit.denorm(0, min, max) if propAbsSwitch not in ['absolute', 'proportional']: raise error.ParameterObjectSyntaxError, 'incorrect switch' if propAbsSwitch == 'absolute': timeUnitDenorm = [rampUp, widthMax, rampDown, widthMin] if sum(timeUnitDenorm) > dur: # force proportional propAbsSwitch = 'proportional' if propAbsSwitch == 'proportional': timeUnit = unit.unitNormProportion([rampUp, widthMax, rampDown, widthMin]) timeUnitDenorm = [x*dur for x in timeUnit] tEnd = tStart + dur t = tStart envelope = [] envelope.append([t, nadir]) t = t + _stepFilter(timeUnitDenorm[0]) # ramp envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[1]) # width envelope.append([t, peak]) t = t + _stepFilter(timeUnitDenorm[2]) # ramp envelope.append([t, nadir]) t = tEnd - OFFSET # always measure to end envelope.append([t, nadir]) return envelope
def _scrubList(self, data, min=None, max=None): """for presenting list data used to apply scalar to uncalculated values""" msg = [] for element in data: if min != None and max != None: element = unit.denorm(element, min, max) msg.append(typeset.anyDataToStr(element)) dataStr = ','.join(msg) return '(%s)' % dataStr
def __call__(self, valArray, tArray, refDictArray): # vale and time should always be the same length assert (len(valArray) == len(tArray) and len(tArray) == len(refDictArray)) # process each value self.currentValue = [] # normalize all values and add to selector w/ pre-defiend normSeries = unit.unitNormRange(valArray) selector = basePmtr.Selector(normSeries, self.control) for i in range(len(valArray)): val = valArray[i] # original value t = tArray[i] refDict = refDictArray[i] # get normalized val from selector, remap b/n min and max postVal = unit.denorm(selector(), self.minObj(t, refDict), self.maxObj(t, refDict)) self.currentValue.append(postVal) # return list of values return self.currentValue
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 _scoreMain(self): """creates score >>> from athenaCL.libATH.libTM import texture >>> ti = texture.factory('InterpolateFill') >>> ti.tmName == 'InterpolateFill' True >>> ti.loadDefault() >>> ti.score() == True True """ # texture-wide time elements inst = self.getInst() tStart, tEnd = self.getTimeRange() tCurrent = tStart # get field, octave selection method value textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textEventCount = self.getTextStatic('tec', 'count') textEventPartition = self.getTextStatic('lep', 'level') textDensityPartition = self.getTextStatic('edp', 'level') textInterpolationMethodControl = self.getTextStatic('imc', 'method') textLevelFrameDuration = self.getTextStatic('lfd', 'level') textParameterInterpolationControl = self.getTextStatic('pic', 'onOff') textSnapSustainTime = self.getTextStatic('sst', 'onOff') # cannot snap event time in this context #textSnapEventTime = self.getTextStatic('set', 'onOff') if textDensityPartition == 'set': # get a list of values pLen = self.getPathLen() eventPerSet = [int(round(textEventCount / pLen))] * pLen else: # duration fraction scalars = self.getPathDurationPercent() eventPerSet = [int(round(x*textEventCount)) for x in scalars] eventIndex = 0 # a list of frame data: tStart, dur, eventFlag, interpMethod,interpExponet tFrameArray = [] # create a list of chords from the appropriate pitch mode for pathPos in self.getPathPos(): chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # start and end of this set is in real-time, not local to path # if not by set, boundaries here are always tt of entire texture if textEventPartition == 'set': tStartSet, tEndSet = self.clockPoints() # value relative to start else: # its a path based, treat tiem as one set tStartSet, tEndSet = self.getTimeRange() # value relative to start # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector(range(len(chordCurrent)), textPitchSelectorControl) # real set start is always the formal start time here tCurrent = copy.deepcopy(tStartSet) tStartSetReal = copy.deepcopy(tStartSet) self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None) if textFieldLevel == 'set': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'set': octCurrent = self.getOct(tCurrent) # choose OCTAVE # get event count from list of eventPerSet list by pathPos for i in range(eventPerSet[pathPos]): # pitch in chord eventIndex = eventIndex + 1 # cumulative count # even when rounded, dont exceed maximum; last set may have less if eventIndex > textEventCount: break # tCurrent here is assumed as start of set initiall, although # this is not exactly correct tUnit = unit.limit(self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSet, tEndSet) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None) if textFieldLevel == 'event': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent) self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal) bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) # silence mode has to be ignored 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 # always store event time in array, w/ interp type and exponent tFrameArray.append((tCurrent, dur, 1, textInterpolationMethodControl, self.getTextDynamic('exponent', tCurrent))) # tFrame = copy.deepcopy(tCurrent) self.clockForward() # advances path positon # sort frames and events; should both be the same size and in order self.esObj.sort() tFrameArray.sort() # sort stored events # process frame start times # store first event, as well as interp exponet if needed # tFrame is set to tCurrent tFrameArrayPost = [] for i in range(len(tFrameArray)-1): # dont do last event eventDict = self.esObj[i] tCurrent = eventDict['time'] tFrame = copy.deepcopy(tCurrent) # get relative duration to next event durRel = self.esObj[i+1]['time'] - eventDict['time'] # transfer old tFrame to new tFrameArrayPost.append(tFrameArray[i]) if textLevelFrameDuration == 'event': # one frame dur / event frameDur = self.getTextDynamic('frameDuration', tCurrent) if frameDur < durRel: # can eval in loop b/c frameDur is constant while (tFrame + frameDur) < (tCurrent + durRel): tFrame = tFrame + frameDur tFrameArrayPost.append((tFrame, frameDur, 0)) # frame updates / frame elif textLevelFrameDuration == 'frame': while 1: # must calc frameDur to see if it is over e next event frameDur = self.getTextDynamic('frameDuration', tFrame) if (tFrame + frameDur) > (tCurrent + durRel): break # cannot fit another frame w/o passing next event tFrame = tFrame + frameDur tFrameArrayPost.append((tFrame, frameDur, 0)) # cannot snap event time here; woudl require repositioning # next event # restore the last tFrame to the new tFrame tFrameArrayPost.append(tFrameArray[-1]) # configure which parameters, in EventSequence object, are interpolated if textParameterInterpolationControl == 'on': active = ['time', 'acc', 'bpm', 'amp', 'ps', 'pan', 'aux'] # elif textParameterInterpolationControl == 'off': active = ['time', 'bpm'] # interpolate events self.interpolate(tFrameArrayPost, textSnapSustainTime, active) return 1
def _scoreMain(self): """creates score >>> from athenaCL.libATH.libTM import texture >>> ti = texture.factory('InterpolateFill') >>> ti.tmName == 'InterpolateFill' True >>> ti.loadDefault() >>> ti.score() == True True """ # texture-wide time elements inst = self.getInst() tStart, tEnd = self.getTimeRange() tCurrent = tStart # get field, octave selection method value textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textEventCount = self.getTextStatic('tec', 'count') textEventPartition = self.getTextStatic('lep', 'level') textDensityPartition = self.getTextStatic('edp', 'level') textInterpolationMethodControl = self.getTextStatic('imc', 'method') textLevelFrameDuration = self.getTextStatic('lfd', 'level') textParameterInterpolationControl = self.getTextStatic('pic', 'onOff') textSnapSustainTime = self.getTextStatic('sst', 'onOff') # cannot snap event time in this context #textSnapEventTime = self.getTextStatic('set', 'onOff') if textDensityPartition == 'set': # get a list of values pLen = self.getPathLen() eventPerSet = [int(round(textEventCount / pLen))] * pLen else: # duration fraction scalars = self.getPathDurationPercent() eventPerSet = [int(round(x * textEventCount)) for x in scalars] eventIndex = 0 # a list of frame data: tStart, dur, eventFlag, interpMethod,interpExponet tFrameArray = [] # create a list of chords from the appropriate pitch mode for pathPos in self.getPathPos(): chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # start and end of this set is in real-time, not local to path # if not by set, boundaries here are always tt of entire texture if textEventPartition == 'set': tStartSet, tEndSet = self.clockPoints( ) # value relative to start else: # its a path based, treat tiem as one set tStartSet, tEndSet = self.getTimeRange( ) # value relative to start # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector( list(range(len(chordCurrent))), textPitchSelectorControl) # real set start is always the formal start time here tCurrent = copy.deepcopy(tStartSet) tStartSetReal = copy.deepcopy(tStartSet) self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None) if textFieldLevel == 'set': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'set': octCurrent = self.getOct(tCurrent) # choose OCTAVE # get event count from list of eventPerSet list by pathPos for i in range(eventPerSet[pathPos]): # pitch in chord eventIndex = eventIndex + 1 # cumulative count # even when rounded, dont exceed maximum; last set may have less if eventIndex > textEventCount: break # tCurrent here is assumed as start of set initiall, although # this is not exactly correct tUnit = unit.limit( self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSet, tEndSet) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None) if textFieldLevel == 'event': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE psReal = pitchTools.psToTempered(ps, octCurrent, self.temperamentObj, transCurrent) self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, psReal) bpm, pulse, dur, sus, acc = self.getRhythm(tCurrent) # silence mode has to be ignored 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 # always store event time in array, w/ interp type and exponent tFrameArray.append( (tCurrent, dur, 1, textInterpolationMethodControl, self.getTextDynamic('exponent', tCurrent))) # tFrame = copy.deepcopy(tCurrent) self.clockForward() # advances path positon # sort frames and events; should both be the same size and in order self.esObj.sort() tFrameArray.sort() # sort stored events # process frame start times # store first event, as well as interp exponet if needed # tFrame is set to tCurrent tFrameArrayPost = [] for i in range(len(tFrameArray) - 1): # dont do last event eventDict = self.esObj[i] tCurrent = eventDict['time'] tFrame = copy.deepcopy(tCurrent) # get relative duration to next event durRel = self.esObj[i + 1]['time'] - eventDict['time'] # transfer old tFrame to new tFrameArrayPost.append(tFrameArray[i]) if textLevelFrameDuration == 'event': # one frame dur / event frameDur = self.getTextDynamic('frameDuration', tCurrent) if frameDur < durRel: # can eval in loop b/c frameDur is constant while (tFrame + frameDur) < (tCurrent + durRel): tFrame = tFrame + frameDur tFrameArrayPost.append((tFrame, frameDur, 0)) # frame updates / frame elif textLevelFrameDuration == 'frame': while 1: # must calc frameDur to see if it is over e next event frameDur = self.getTextDynamic('frameDuration', tFrame) if (tFrame + frameDur) > (tCurrent + durRel): break # cannot fit another frame w/o passing next event tFrame = tFrame + frameDur tFrameArrayPost.append((tFrame, frameDur, 0)) # cannot snap event time here; woudl require repositioning # next event # restore the last tFrame to the new tFrame tFrameArrayPost.append(tFrameArray[-1]) # configure which parameters, in EventSequence object, are interpolated if textParameterInterpolationControl == 'on': active = ['time', 'acc', 'bpm', 'amp', 'ps', 'pan', 'aux'] # elif textParameterInterpolationControl == 'off': active = ['time', 'bpm'] # interpolate events self.interpolate(tFrameArrayPost, textSnapSustainTime, active) return 1
def _scoreMain(self): """creates score note: octave choose for every note >>> from athenaCL.libATH.libTM import texture >>> ti = texture.factory('TimeFill') >>> ti.tmName == 'TimeFill' 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 textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textEventCount = self.getTextStatic('tec', 'count') textEventPartition = self.getTextStatic('lep', 'level') textDensityPartition = self.getTextStatic('edp', 'level') if textDensityPartition == 'set': # get a list of values pLen = self.getPathLen() eventPerSet = [int(round(textEventCount / pLen))] * pLen else: # duration fraction scalars = self.getPathDurationPercent() eventPerSet = [int(round(x * textEventCount)) for x in scalars] eventIndex = 0 # create a list of chords from the appropriate pitch mode for pathPos in self.getPathPos(): chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # start and end of this set is in real-time, not local to path # if not by set, boundaries here are always tt of entire texture if textEventPartition == 'set': tStartSet, tEndSet = self.clockPoints( ) # value relative to start else: # its a path based, treat tiem as one set tStartSet, tEndSet = self.getTimeRange( ) # value relative to path # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector(range(len(chordCurrent)), textPitchSelectorControl) # real set start is always the formal start time here tCurrent = copy.deepcopy(tStartSet) tStartSetReal = copy.deepcopy(tStartSet) self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None) if textFieldLevel == 'set': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'set': octCurrent = self.getOct(tCurrent) # choose OCTAVE # get event count from list of eventPerSet list by pathPos for i in range(eventPerSet[pathPos]): # pitch in chord eventIndex = eventIndex + 1 # cumulative count # even when rounded, dont exceed maximum; last set may have less if eventIndex > textEventCount: break # tCurrent here is assumed as start of set initiall, although # this is not exactly correct tUnit = unit.limit( self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSet, tEndSet) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None) if textFieldLevel == 'event': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE 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('TimeFill') >>> ti.tmName == 'TimeFill' 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 textFieldLevel = self.getTextStatic('lfm', 'level') textOctaveLevel = self.getTextStatic('lom', 'level') textPitchSelectorControl = self.getTextStatic('psc', 'selectionString') textEventCount = self.getTextStatic('tec', 'count') textEventPartition = self.getTextStatic('lep', 'level') textDensityPartition = self.getTextStatic('edp', 'level') if textDensityPartition == 'set': # get a list of values pLen = self.getPathLen() eventPerSet = [int(round(textEventCount / pLen))] * pLen else: # duration fraction scalars = self.getPathDurationPercent() eventPerSet = [int(round(x*textEventCount)) for x in scalars] eventIndex = 0 # create a list of chords from the appropriate pitch mode for pathPos in self.getPathPos(): chordCurrent = self.getPitchGroup(pathPos) multisetCurrent = self.getMultiset(pathPos) # start and end of this set is in real-time, not local to path # if not by set, boundaries here are always tt of entire texture if textEventPartition == 'set': tStartSet, tEndSet = self.clockPoints() # value relative to start else: # its a path based, treat tiem as one set tStartSet, tEndSet = self.getTimeRange() # value relative to path # create a generator to get pitches from chord as index values selectorChordPos = basePmtr.Selector(range(len(chordCurrent)), textPitchSelectorControl) # real set start is always the formal start time here tCurrent = copy.deepcopy(tStartSet) tStartSetReal = copy.deepcopy(tStartSet) self.stateUpdate(tCurrent, chordCurrent, None, multisetCurrent, None, None) if textFieldLevel == 'set': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'set': octCurrent = self.getOct(tCurrent) # choose OCTAVE # get event count from list of eventPerSet list by pathPos for i in range(eventPerSet[pathPos]): # pitch in chord eventIndex = eventIndex + 1 # cumulative count # even when rounded, dont exceed maximum; last set may have less if eventIndex > textEventCount: break # tCurrent here is assumed as start of set initiall, although # this is not exactly correct tUnit = unit.limit(self.getTextDynamic('fillGenerator', tCurrent)) tCurrent = unit.denorm(tUnit, tStartSet, tEndSet) # choose pc from chord ps = chordCurrent[selectorChordPos()] # get position w/n chord self.stateUpdate(tCurrent, chordCurrent, ps, multisetCurrent, None, None) if textFieldLevel == 'event': transCurrent = self.getField(tCurrent) # choose PITCHFIELD if textOctaveLevel == 'event': octCurrent = self.getOct(tCurrent) # choose OCTAVE 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