@@ -61,13 +61,13 @@ def __init__(self, tween=tween.LINEAR, start=0, change=1.0, duration=1.0,
61
61
self .duration = float (duration )
62
62
self .label = label
63
63
64
- assert self .duration > 0 # only a duration > 0 makes sense
64
+ # assert self.duration > 0 # only a duration > 0 makes sense
65
65
66
66
def get_value (self , delta ):
67
67
if delta > self .duration :
68
68
delta = self .duration
69
69
# TODO save a self.value here for more consistency with envelopes?
70
- print "updating %s %s at %s" % (self .label , self , delta )
70
+ # print "updating %s %s at %s" % (self.label, self, delta)
71
71
return self .tween (delta , self .start , self .change , self .duration )
72
72
73
73
def get_jump_time (self , value ):
@@ -90,16 +90,22 @@ def __init__(self, tween=tween.LINEAR, start=0, change=1.0, duration=1.0,
90
90
self .elapsed = 0
91
91
self .value = 0
92
92
93
- assert self .duration > 0 # only a duration > 0 makes sense
93
+ # assert self.duration > 0 # only a duration > 0 makes sense
94
94
95
95
def reset (self ):
96
96
self .elapsed = 0
97
97
self .value = 0
98
98
99
+ def get_profile (self ):
100
+ return self .profile
101
+
99
102
def update (self , delta ):
100
- print "updating %s %s at delta %s" % (self .label , self , delta )
103
+ # print "updating %s %s at delta %s" % (self.label, self, delta)
101
104
self .elapsed += delta
102
- self .value = self .profile .get_value (self .elapsed )
105
+ if not self .duration :
106
+ self .value = self .profile .start + self .profile .change
107
+ else :
108
+ self .value = self .profile .get_value (self .elapsed )
103
109
return self .value
104
110
105
111
class StaticEnvelopeSegment (EnvelopeSegment ):
@@ -109,6 +115,9 @@ class StaticEnvelopeSegment(EnvelopeSegment):
109
115
def __init__ (self , * args , ** kwargs ):
110
116
super (StaticEnvelopeSegment , self ).__init__ (* args , ** kwargs )
111
117
self .duration = 0
118
+ # TODO - this is a hack so sustain doesn't get advanced over
119
+ # as part of an on envelope that has no attack
120
+ self .duration = 99999999999999999999999999999999
112
121
113
122
def update (self , delta ):
114
123
return self .profile .start
@@ -118,16 +127,27 @@ class Envelope(EnvelopeSegment):
118
127
def __init__ (self , loop = 0 , label = "envelope" ):
119
128
self .segments = []
120
129
self .label = label
130
+ self .index = 0
131
+ self .advancing = True
121
132
122
133
# Not sure I need this state
123
134
self .running = False
124
135
self .paused = 0
125
136
self .pause_duration = 0
126
137
127
138
self .loop = loop # negative loop is infinite looping
128
- self ._duration = None
139
+ self ._duration = 0
129
140
self .reset ()
130
141
142
+ def get_profile (self ):
143
+ print "Envelop profile property, index: " , self .index
144
+ print self , self .label
145
+ if self .segments :
146
+ return self .segments [self .index ].profile
147
+ elif hasattr (self , 'profile' ):
148
+ return self .profile
149
+ raise RuntimeError ("profile not available" )
150
+
131
151
def start (self ):
132
152
pass
133
153
@@ -146,50 +166,69 @@ def reset(self):
146
166
self .current_segment_time_delta = 0
147
167
for segment in self .segments :
148
168
segment .reset ()
169
+ self .advancing = True
149
170
150
171
def advance (self ):
151
172
# return True if advanced
152
- print "advancing"
153
- print self .index , len (self .segments )
173
+ # print "advancing ", self.label
174
+ # print self.index, len(self.segments)
154
175
if self .index + 1 == len (self .segments ): # last segment
155
176
if self .loop and self .loop_counter :
156
- print 'looping'
177
+ # print 'looping'
157
178
self .segments [self .index ].reset ()
158
179
self .index = 0
159
180
if self .loop > 0 : # this is a finite loop
160
181
self .loop_counter -= 1
161
- print 'loop counter now: ' , self .loop_counter
182
+ # print 'loop counter now: ', self.loop_counter
162
183
return True
163
- print 'infinite loop counter now: ' , self .loop_counter
184
+ # print 'infinite loop counter now: ', self.loop_counter
164
185
else :
165
- print "not looping on advance - staying at last segment"
186
+ # print "not looping on advance - staying at last segment"
166
187
# non-looping, or done with final loop
167
188
pass
168
189
else :
169
190
# proceed through sequence of segments
170
- self .segments [self .index ].reset ()
191
+ if self .segments [self .index ]:
192
+ # TODO - this is a reason to have always have a segment of some sort
193
+ # even if it is a null segment, rather than use none
194
+ self .segments [self .index ].reset ()
171
195
self .index += 1
172
196
self .current_segment_time_delta = 0
197
+ print "advanced to %s" % self .segments [self .index ].label
173
198
return True
199
+ self .advancing = False
174
200
return False
175
201
176
202
177
203
def update (self , delta ):
178
- print '---------------------'
179
- print "updating %s %s at delta %s" % (self .label , self , delta )
204
+ # print '---------------------'
205
+ # print "updating %s %s at delta %s" % (self.label, self, delta)
180
206
181
207
# delta is time passed since last update
182
208
if self .index + 1 > len (self .segments ):
183
209
# non looping or end of finite loop
184
210
# just reurn last value until something resets index
185
211
return self .value
186
212
segment = self .segments [self .index ]
213
+ if not segment .duration :
214
+ # for example, no attack value
215
+ # self.advance()
216
+ pass
187
217
self .current_segment_time_delta += delta
188
- print "self current elapsed %s" % self .current_segment_time_delta
189
- if (segment .duration and
190
- (self .current_segment_time_delta > segment .duration )):
218
+ print "%s-%s: self current elapsed %s, after delta %s" % (
219
+ id (self ),
220
+ self .label ,
221
+ self .current_segment_time_delta ,
222
+ delta ,
223
+ )
224
+ print "current segment " , segment , segment .label
225
+ # TODO this is advancing past end of on segemnt,
226
+ # when that on segment only contains a 0 duration attack, and no decay
227
+ # not going into any sustain
228
+ if (self .current_segment_time_delta > segment .duration and
229
+ not isinstance (segment , StaticEnvelopeSegment )):
191
230
overage = self .current_segment_time_delta - segment .duration
192
- # TODO don't handle case where overage > new segment
231
+ # TODO currently don't handle case where overage > new segment
193
232
# duration - could need recursion
194
233
195
234
if self .advance ():
@@ -198,6 +237,7 @@ def update(self, delta):
198
237
segment = self .segments [self .index ]
199
238
200
239
self .value = segment .update (delta )
240
+ print self .value
201
241
return self .value
202
242
203
243
@property
@@ -207,7 +247,14 @@ def duration(self):
207
247
return self ._duration
208
248
209
249
def set_duration (self ):
210
- self ._duration = sum ([segment .duration for segment in self .segments if segment .duration > 0 ])
250
+ # a duration of 0 means it is infinite
251
+ self ._duration = 0
252
+ for segment in self .segments :
253
+ if segment and segment .duration :
254
+ self ._duration += segment .duration
255
+ else :
256
+ self ._duration = 0
257
+ # self._duration = sum([segment.duration for segment in self.segments if segment.duration > 0])
211
258
212
259
213
260
class TriggeredEnvelope (Envelope ):
@@ -233,14 +280,46 @@ def trigger(self, state=1, value=1.0):
233
280
self .state = state
234
281
if state :
235
282
# on trigger
283
+ print "trigger on - resetting"
236
284
self .reset ()
285
+ print "%s-%s: self post reset current elapsed %s" % (
286
+ id (self ),
287
+ self .label ,
288
+ self .current_segment_time_delta ,
289
+ )
237
290
else :
238
291
# off trigger
239
- print 'advance'
292
+ # print 'advance'
240
293
self .advance ()
241
- if self .value != self .segments [1 ].profile .start :
294
+ # print self.segments
295
+ print "current value: %s" % self .value
296
+ print "current change for release: %s" % self .segments [1 ].get_profile ().change
297
+ if self .value < self .segments [1 ].get_profile ().start :
298
+ # TODO this shortcut works on release, but for attack?
299
+ # also need to sort out when in decay (say .9), and release
300
+ # start is .8 - now will be greater - want a way to change
301
+ # release start value for this time only
302
+ # perhaps start value should always just be current value - for when greater
303
+ # if dimmer, want shorter release
304
+ # if brigher (.9) then want standard release time but greater change
305
+
242
306
print "shortcutting time"
243
- self .current_segment_time_delta += self .segments [1 ].profile .get_jump_time (self .value )
307
+ jump_value = self .segments [1 ].get_profile ().get_jump_time (self .value )
308
+ print jump_value
309
+ self .update (jump_value )
310
+ # self.current_segment_time_delta += self.segments[1].profile.get_jump_time(self.value)
311
+ # self.segments[0].segments[0].current_segment_time_delta = self.current_segment_time_delta
312
+ # else:
313
+ # print "set change of release"
314
+ # TODO - this won't work for multisegment release
315
+ # if not hasattr(self.segments[1], 'segments'):
316
+ # self.segments[1].segments[0].profile.change = -1 * self.value
317
+ # self.segments[1].segments[0].profile.start = self.value
318
+ # else:
319
+ # print "has segments"
320
+ # print self.segments[1].segments
321
+
322
+ print "new current change for release: %s" % self .segments [1 ].get_profile ().change
244
323
self .state = state
245
324
246
325
def update (self , delta ):
@@ -265,10 +344,10 @@ def __init__(self, peak_value=1.0, sustain_value=0.8,
265
344
attack_shape = tween .LINEAR , attack_duration = 0.5 ,
266
345
decay_shape = tween .LINEAR , decay_duration = .2 ,
267
346
release_shape = tween .LINEAR , release_duration = .5 ,
268
- bell_mode = False , label = 'ADSR-envelope' ):
347
+ bell_mode = False , label = 'ADSR-envelope' , ** kwargs ):
269
348
270
349
super (ADSREnvelope , self ).__init__ (loop = 0 , label = label )
271
-
350
+ # print attack_duration
272
351
self .attack_envelope = EnvelopeSegment (
273
352
tween = attack_shape ,
274
353
change = peak_value ,
@@ -304,10 +383,12 @@ def __init__(self, peak_value=1.0, sustain_value=0.8,
304
383
label = "release" ,
305
384
)
306
385
self .off_envelope = Envelope (label = "off-envelope" )
307
- if self .release_envelope .profile .change and self .release_envelope .duration :
308
- self .off_envelope .segments .append (self .release_envelope )
386
+ # if self.release_envelope.profile.change and self.release_envelope.duration:
387
+ self .off_envelope .segments .append (self .release_envelope )
309
388
self .segments = [self .on_envelope , self .off_envelope ]
310
389
390
+ # def trigger(self, state=1, value=1.0):
391
+ # if trigger off during attack, skip decay
311
392
312
393
class EnvelopeGenerator (object ):
313
394
pass
0 commit comments