Mercurial > code > home > repos > light9
annotate flax/curvecalc @ 198:238eede02bf9
supports using twisted/deferreds for the xmlrpc connection
author | drewp |
---|---|
date | Wed, 16 Jun 2004 13:01:18 +0000 |
parents | ba2677823b35 |
children | f5d3492981ab |
rev | line source |
---|---|
0 | 1 #!/usr/bin/python |
2 | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
3 """ |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
4 todo: curveview should preserve more objects, for speed maybe |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
5 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
6 """ |
0 | 7 from __future__ import division |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
8 import xmlrpclib,time,socket,sys,textwrap,math |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
9 from bisect import bisect_left,bisect,bisect_right |
0 | 10 import Tkinter as tk |
11 from dispatch import dispatcher | |
12 from twisted.internet import reactor,tksupport | |
13 from twisted.web.xmlrpc import Proxy | |
14 | |
15 sys.path.append("../light8") | |
16 import dmxclient | |
17 import Submaster | |
18 from TLUtility import make_attributes_from_args | |
19 | |
20 | |
21 class Curve: | |
22 """curve does not know its name. see Curveset""" | |
23 points = None # x-sorted list of (x,y) | |
24 def __init__(self): | |
25 self.points = [] | |
26 | |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
27 self.points = [(0,0),(1,1),(9,1),(10,0)] |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
28 for x in range(11,500): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
29 self.points.append((x,.5)) |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
30 |
0 | 31 def eval(self,t): |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
32 i = bisect_left(self.points,(t,None))-1 |
0 | 33 |
34 if self.points[i][0]>t: | |
35 return self.points[i][1] | |
36 if i>=len(self.points)-1: | |
37 return self.points[i][1] | |
38 | |
39 p1,p2 = self.points[i],self.points[i+1] | |
40 frac = (t-p1[0])/(p2[0]-p1[0]) | |
41 y = p1[1]+(p2[1]-p1[1])*frac | |
42 return y | |
43 | |
44 __call__=eval | |
45 | |
46 class Curveview(tk.Canvas): | |
47 def __init__(self,master,curve,**kw): | |
48 self.curve=curve | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
49 tk.Canvas.__init__(self,master,width=10,height=10, |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
50 relief='sunken',bd=1, |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
51 closeenough=5,**kw) |
0 | 52 self.selected_points=[] # idx of points being dragged |
53 self.update() | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
54 self.bind("<Enter>",self.focus) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
55 dispatcher.connect(self.input_time,"input time") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
56 dispatcher.connect(self.update,"zoom changed") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
57 self.bind("<Configure>",self.update) |
0 | 58 def screen_from_world(self,p): |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
59 start,end = self.zoom |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
60 ht = self.winfo_height() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
61 return (p[0]-start)/(end-start)*self.winfo_width(), (ht-5)-p[1]*(ht-10) |
0 | 62 def world_from_screen(self,x,y): |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
63 start,end = self.zoom |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
64 ht = self.winfo_height() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
65 return x/self.winfo_width()*(end-start)+start, ((ht-5)-y)/(ht-10) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
66 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
67 def input_time(self,val): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
68 t=val |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
69 pts = self.screen_from_world((val,0))+self.screen_from_world((val,1)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
70 self.delete('timecursor') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
71 self.create_line(*pts,**dict(width=2,fill='red',tags=('timecursor',))) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
72 def update(self,*args): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
73 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
74 self.zoom = dispatcher.send("zoom area")[0][1] |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
75 cp = self.curve.points |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
76 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
77 visible_x = (self.world_from_screen(0,0)[0], |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
78 self.world_from_screen(self.winfo_width(),0)[0]) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
79 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
80 visleftidx = max(0,bisect_left(cp,(visible_x[0],None))-1) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
81 visrightidx = min(len(cp)-1,bisect_left(cp,(visible_x[1],None))+1) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
82 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
83 visible_points = cp[visleftidx:visrightidx] |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
84 |
0 | 85 self.delete('curve') |
86 linepts=[] | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
87 for p in visible_points: |
0 | 88 linepts.extend(self.screen_from_world(p)) |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
89 line = self.create_line(*linepts,**{'tags':'curve'}) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
90 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
91 # canvas doesnt have keyboard focus, so i can't easily change the |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
92 # cursor when ctrl is pressed |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
93 # def curs(ev): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
94 # print ev.state |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
95 # self.bind("<KeyPress>",curs) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
96 # self.bind("<KeyRelease-Control_L>",lambda ev: curs(0)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
97 self.tag_bind(line,"<Control-ButtonPress-1>",self.newpoint) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
98 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
99 self.dots = {} # idx : canvas rectangle |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
100 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
101 if len(visible_points)<50: ###self.zoom[1]-self.zoom[0]<30 or len(visible_points)<: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
102 for i,p in enumerate(visible_points): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
103 rad=3 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
104 p = self.screen_from_world(p) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
105 # if p[0]-prevx<10: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
106 # # too close- skip the dots |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
107 # continue |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
108 dot = self.create_rectangle(p[0]-rad,p[1]-rad,p[0]+rad,p[1]+rad, |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
109 outline='black',fill='blue', |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
110 tags=('curve','point')) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
111 self.tag_bind(dot,"<ButtonPress-1>", |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
112 lambda ev,i=i: self.dotpress(ev,i)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
113 self.bind("<Motion>", |
0 | 114 lambda ev,i=i: self.dotmotion(ev,i)) |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
115 self.bind("<ButtonRelease-1>", |
0 | 116 lambda ev,i=i: self.dotrelease(ev,i)) |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
117 self.dots[i]=dot |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
118 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
119 self.highlight_selected_dots() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
120 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
121 def newpoint(self,ev): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
122 cp = self.curve.points |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
123 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
124 p = self.world_from_screen(ev.x,ev.y) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
125 i = bisect(cp,(p[0],None)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
126 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
127 self.unselect() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
128 cp.insert(i,p) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
129 self.update() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
130 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
131 def highlight_selected_dots(self): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
132 for i,d in self.dots.items(): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
133 if i in self.selected_points: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
134 self.itemconfigure(d,fill='red') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
135 else: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
136 self.itemconfigure(d,fill='blue') |
0 | 137 |
138 def dotpress(self,ev,dotidx): | |
139 self.selected_points=[dotidx] | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
140 self.highlight_selected_dots() |
0 | 141 |
142 def dotmotion(self,ev,dotidx): | |
143 cp = self.curve.points | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
144 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
145 moved=0 |
0 | 146 for idx in self.selected_points: |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
147 newp = self.world_from_screen(ev.x,ev.y) |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
148 if idx>0 and newp[0]<=cp[idx-1][0]: |
0 | 149 continue |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
150 if idx<len(cp)-1 and newp[0]>=cp[idx+1][0]: |
0 | 151 continue |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
152 moved=1 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
153 cp[idx] = newp |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
154 if moved: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
155 self.update() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
156 def unselect(self): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
157 self.selected_points=[] |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
158 self.highlight_selected_dots() |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
159 |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
160 def dotrelease(self,ev,dotidx): |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
161 self.unselect() |
0 | 162 |
163 class Curveset: | |
164 curves = None # curvename : curve | |
165 def __init__(self): | |
166 self.curves = {} | |
167 def add_curve(self,name,curve): | |
168 self.curves[name] = curve | |
169 dispatcher.send("add_curve",sender=self,name=name) | |
170 def globalsdict(self): | |
171 return self.curves.copy() | |
172 | |
173 class Curvesetview(tk.Frame): | |
174 curves = None # curvename : Curveview | |
175 def __init__(self,master,curveset,**kw): | |
176 self.curves = {} | |
177 self.curveset = curveset | |
178 tk.Frame.__init__(self,master,**kw) | |
179 dispatcher.connect(self.add_curve,"add_curve",sender=self.curveset) | |
180 def add_curve(self,name): | |
181 f = tk.Frame(self,relief='raised',bd=1) | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
182 f.pack(side='top',fill='both',exp=1) |
0 | 183 tk.Label(f,text="curve %r"%name).pack(side='left') |
184 cv = Curveview(f,self.curveset.curves[name]) | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
185 cv.pack(side='right',fill='both',exp=1) |
0 | 186 self.curves[name] = cv |
187 | |
188 class Music: | |
189 def __init__(self): | |
190 self.player=None # xmlrpc Proxy to player | |
191 self.recenttime=0 | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
192 |
0 | 193 def current_time(self): |
194 """return deferred which gets called with the current time""" | |
195 if self.player is None: | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
196 self.player = Proxy("http://spot:8040") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
197 d = self.player.callRemote("songlength") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
198 def sendmax(l): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
199 dispatcher.send("max time",maxtime=l) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
200 d.addCallback(sendmax) |
0 | 201 d = self.player.callRemote('gettime') |
202 def sendtime(t): | |
203 dispatcher.send("input time",val=t) | |
204 return t # pass along to the real receiver | |
205 def error(e): | |
206 pass#self.player=None | |
207 d.addCallback(sendtime) | |
208 return d | |
209 | |
210 class Subexpr: | |
211 curveset = None | |
212 def __init__(self,curveset): | |
213 self.curveset = curveset | |
214 self.lasteval = None | |
215 self.expr="" | |
216 def eval(self,t): | |
217 if self.expr=="": | |
218 dispatcher.send("expr_error",sender=self,exc="no expr, using 0") | |
219 return 0 | |
220 glo = self.curveset.globalsdict() | |
221 glo['t'] = t | |
222 try: | |
223 self.lasteval = eval(self.expr,glo) | |
224 except Exception,e: | |
225 dispatcher.send("expr_error",sender=self,exc=e) | |
226 else: | |
227 dispatcher.send("expr_error",sender=self,exc="no errors") | |
228 return self.lasteval | |
229 | |
230 def expr(): | |
231 doc = "python expression for level as a function of t, using curves" | |
232 def fget(self): | |
233 return self._expr | |
234 def fset(self, value): | |
235 self._expr = value | |
236 dispatcher("expr_changed",sender=self) | |
237 return locals() | |
238 expr = property(**expr()) | |
239 | |
240 class Subexprview(tk.Frame): | |
241 def __init__(self,master,se,**kw): | |
242 self.subexpr=se | |
243 tk.Frame.__init__(self,master,**kw) | |
244 self.evar = tk.StringVar() | |
245 e = self.ent = tk.Entry(master,textvariable=self.evar) | |
246 e.pack(side='left',fill='both',exp=1) | |
247 self.expr_changed() | |
248 self.evar.trace_variable('w',self.evar_changed) | |
249 dispatcher.connect(self.expr_changed,"expr_changed", | |
250 sender=self.subexpr) | |
251 self.error = tk.Label(master) | |
252 self.error.pack(side='left') | |
253 dispatcher.connect(lambda exc: self.error.config(text=str(exc)), | |
254 "expr_error",sender=self.subexpr,weak=0) | |
255 def expr_changed(self): | |
256 if self.subexpr.expr!=self.evar.get(): | |
257 self.evar.set(self.subexpr.expr) | |
258 def evar_changed(self,*args): | |
259 self.subexpr.expr = self.evar.get() | |
260 | |
261 class Subterm: | |
262 """one Submaster and its Subexpr""" | |
263 def scaled(self,t): | |
264 return self.sub * self.subexpr.eval(t) | |
265 | |
266 class Subtermview(tk.Frame): | |
267 def __init__(self,master,st,**kw): | |
268 self.subterm = st | |
269 tk.Frame.__init__(self,master,bd=1,relief='raised',**kw) | |
270 tk.Label(self,text="sub %r" % self.subterm.sub.name).pack(side='left') | |
271 sev=Subexprview(self,self.subterm.subexpr) | |
272 sev.pack(side='left',fill='both',exp=1) | |
273 | |
274 class Output: | |
275 def __init__(self,subterms): | |
276 make_attributes_from_args('subterms') | |
277 def send_dmx(self,t): | |
278 | |
279 scaledsubs=[] | |
280 for st in self.subterms: | |
281 scl = st.scaled(t) | |
282 scaledsubs.append(scl) | |
283 out = Submaster.sub_maxes(*scaledsubs) | |
284 dispatcher.send("output levels",val=out.get_levels()) | |
285 dmxclient.outputlevels(out.get_dmx_list(),twisted=1) | |
286 | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
287 def statuslines(master): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
288 for signame,textfilter in [ |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
289 ('input time',lambda t: "%.2fs"%t), |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
290 ('output levels', |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
291 lambda levels: textwrap.fill("; ".join(["%s:%.2f"%(n,v) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
292 for n,v in |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
293 levels.items()]),70)), |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
294 ('update period',lambda t: "%.1fms"%(t*1000)), |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
295 ]: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
296 l = tk.Label(master,anchor='w',justify='left') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
297 l.pack(side='top',fill='x') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
298 dispatcher.connect(lambda val,l=l,sn=signame,tf=textfilter: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
299 l.config(text=sn+": "+tf(val)), |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
300 signame,weak=0) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
301 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
302 class Zoomcontrol(object,tk.Canvas): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
303 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
304 def maxtime(): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
305 doc = "seconds at the right edge of the bar" |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
306 def fget(self): return self._maxtime |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
307 def fset(self, value): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
308 self._maxtime = value |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
309 self.updatewidget() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
310 return locals() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
311 maxtime = property(**maxtime()) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
312 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
313 def start(): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
314 def fget(self): return self._start |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
315 def fset(self,v): self._start = max(0,v) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
316 return locals() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
317 start = property(**start()) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
318 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
319 def end(): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
320 def fget(self): return self._end |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
321 def fset(self,v): self._end = min(self.maxtime,v) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
322 return locals() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
323 end = property(**end()) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
324 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
325 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
326 def __init__(self,master,**kw): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
327 self.maxtime=370 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
328 self.start=0 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
329 self.end=20 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
330 tk.Canvas.__init__(self,master,width=250,height=30, |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
331 relief='raised',bd=1,bg='gray60',**kw) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
332 self.leftbrack = self.create_line(0,0,0,0,0,0,0,0,width=5) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
333 self.rightbrack = self.create_line(0,0,0,0,0,0,0,0,width=5) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
334 self.shade = self.create_rectangle(0,0,0,0,fill='gray70',outline=None) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
335 self.time = self.create_line(0,0,0,0,fill='red',width=2) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
336 self.updatewidget() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
337 self.bind("<Configure>",self.updatewidget) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
338 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
339 self.bind("<ButtonPress-1>",lambda ev: setattr(self,'lastx',ev.x)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
340 self.tag_bind(self.leftbrack,"<B1-Motion>", |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
341 lambda ev: self.adjust('start',ev)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
342 self.tag_bind(self.rightbrack,"<B1-Motion>", |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
343 lambda ev: self.adjust('end',ev)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
344 self.tag_bind(self.shade,"<B1-Motion>", |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
345 lambda ev: self.adjust('offset',ev)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
346 dispatcher.connect(lambda: (self.start,self.end),"zoom area",weak=0) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
347 dispatcher.connect(self.input_time,"input time") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
348 dispatcher.connect(lambda maxtime: (setattr(self,'maxtime',maxtime), |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
349 self.updatewidget()),"max time",weak=0) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
350 self.created=1 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
351 def input_time(self,val): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
352 t=val |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
353 x=self.can_for_t(t) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
354 self.coords(self.time,x,0,x,self.winfo_height()) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
355 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
356 def adjust(self,attr,ev): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
357 if not hasattr(self,'lastx'): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
358 return |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
359 new = self.can_for_t(getattr(self,attr)) + (ev.x - self.lastx) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
360 self.lastx = ev.x |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
361 setattr(self,attr,self.t_for_can(new)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
362 self.updatewidget() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
363 dispatcher.send("zoom changed") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
364 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
365 def offset(): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
366 doc = "virtual attr that adjusts start and end together" |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
367 def fget(self): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
368 return self.start |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
369 def fset(self, value): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
370 d = self.end-self.start |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
371 self.start = value |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
372 self.end = self.start+d |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
373 return locals() |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
374 offset = property(**offset()) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
375 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
376 def can_for_t(self,t): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
377 return t/self.maxtime*(self.winfo_width()-30)+20 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
378 def t_for_can(self,x): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
379 return (x-20)/(self.winfo_width()-30)*self.maxtime |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
380 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
381 def updatewidget(self,*args): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
382 """redraw pieces based on start/end""" |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
383 if not hasattr(self,'created'): return |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
384 y1,y2=3,self.winfo_height()-3 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
385 lip = 6 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
386 scan = self.can_for_t(self.start) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
387 ecan = self.can_for_t(self.end) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
388 self.coords(self.leftbrack,scan+lip,y1,scan,y1,scan,y2,scan+lip,y2) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
389 self.coords(self.rightbrack,ecan-lip,y1,ecan,y1,ecan,y2,ecan-lip,y2) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
390 self.coords(self.shade,scan+3,y1+lip,ecan-3,y2-lip) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
391 self.delete("tics") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
392 lastx=-1000 |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
393 for t in range(0,int(self.maxtime)): |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
394 x = self.can_for_t(t) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
395 if 0<x<self.winfo_width() and x-lastx>30: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
396 txt=str(t) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
397 if lastx==-1000: |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
398 txt=txt+"sec" |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
399 self.create_line(x,0,x,15, |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
400 tags=('tics',)) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
401 self.create_text(x,self.winfo_height()-1,anchor='s', |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
402 text=txt,tags=('tics',),font='6x13') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
403 lastx = x |
0 | 404 |
405 ####################################################################### | |
406 root=tk.Tk() | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
407 root.wm_geometry("790x930") |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
408 #root.tk_focusFollowsMouse() |
0 | 409 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
410 m=Music() |
0 | 411 |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
412 zc = Zoomcontrol(root) |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
413 zc.pack(side='top',fill='x') |
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
414 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
415 cs = Curveset() |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
416 csv = Curvesetview(root,cs) |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
417 csv.pack(side='top',fill='both',exp=1) |
0 | 418 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
419 for loop in range(6): |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
420 cs.add_curve('c'+str(loop+1),Curve()) |
0 | 421 |
422 subterms = [] | |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
423 for subname in "zip_orange","zip_red": |
0 | 424 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
425 se = Subexpr(cs) |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
426 if subname=='zip_orange': |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
427 se.expr="c1(t)+c2(t)+c3(t)+c4(t)+c5(t)" |
0 | 428 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
429 st=Subterm() |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
430 st.sub=Submaster.Submaster(subname) |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
431 st.subexpr=se |
0 | 432 |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
433 stv=Subtermview(root,st) |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
434 stv.pack(side='top',fill='x') |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
435 subterms.append(st) |
0 | 436 |
437 out = Output(subterms) | |
438 | |
197
ba2677823b35
zoom control and other cleanups. also reads song length now
drewp
parents:
196
diff
changeset
|
439 statuslines(root) |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
440 |
0 | 441 recent_t=[] |
442 def update(): | |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
443 d = m.current_time() |
0 | 444 d.addCallback(update2) |
445 d.addErrback(updateerr) | |
446 def updateerr(e): | |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
447 reactor.callLater(1,update) |
0 | 448 def update2(t): |
196
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
449 global recent_t |
07bac5061d69
evaluates curves based on input time from ascoltami; outputs dmx
drewp
parents:
0
diff
changeset
|
450 reactor.callLater(.001,update) |
0 | 451 |
452 recent_t = recent_t[-50:]+[t] | |
453 period = (recent_t[-1]-recent_t[0])/len(recent_t) | |
454 dispatcher.send("update period",val=period) | |
455 out.send_dmx(t) | |
456 update() | |
457 | |
458 tksupport.install(root,ms=10) | |
459 if 0: | |
460 sys.path.append("/home/drewp/projects/editor/pour") | |
461 from utils import runstats | |
462 runstats("reactor.run()") | |
463 else: | |
464 reactor.run() |