Mercurial > code > home > repos > light9
comparison bin/effecteval @ 1180:6c4981f61bf8
subserver inserts effects with envelope curves
Ignore-this: 2209ad8a0b93b78719bb5347aea5557e
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Sun, 15 Jun 2014 08:41:02 +0000 |
parents | a232bc895568 |
children | c677bf37a1b4 |
comparison
equal
deleted
inserted
replaced
1179:65405b3311f6 | 1180:6c4981f61bf8 |
---|---|
8 from rdflib import URIRef, Literal | 8 from rdflib import URIRef, Literal |
9 | 9 |
10 sys.path.append('/usr/lib/pymodules/python2.7/') # for numpy, on rpi | 10 sys.path.append('/usr/lib/pymodules/python2.7/') # for numpy, on rpi |
11 sys.path.append('/usr/lib/python2.7/dist-packages') # For numpy | 11 sys.path.append('/usr/lib/python2.7/dist-packages') # For numpy |
12 from light9 import networking, showconfig, Submaster, dmxclient | 12 from light9 import networking, showconfig, Submaster, dmxclient |
13 from light9.curvecalc import musicaccess | |
13 from light9.curvecalc.curve import CurveResource | 14 from light9.curvecalc.curve import CurveResource |
14 from light9.effecteval.effect import EffectNode | 15 from light9.effecteval.effect import EffectNode |
15 from light9.effecteval.effectloop import makeEffectLoop | 16 from light9.effecteval.effectloop import makeEffectLoop |
16 from light9.greplin_cyclone import StatsForCyclone | 17 from light9.greplin_cyclone import StatsForCyclone |
17 from light9.namespaces import L9, RDF, RDFS | 18 from light9.namespaces import L9, RDF, RDFS |
31 song = ctx = list(g.subjects(L9['effect'], uri))[0] | 32 song = ctx = list(g.subjects(L9['effect'], uri))[0] |
32 self.settings.graph.patch(Patch(delQuads=[ | 33 self.settings.graph.patch(Patch(delQuads=[ |
33 (song, L9['effect'], uri, ctx), | 34 (song, L9['effect'], uri, ctx), |
34 ])) | 35 ])) |
35 | 36 |
37 def clamp(x, lo, hi): | |
38 return max(lo, min(hi, x)) | |
39 | |
40 @inlineCallbacks | |
41 def newEnvelopeCurve(graph, ctx, uri, label): | |
42 """this does its own patch to the graph""" | |
43 | |
44 musicStatus = json.loads((yield cyclone.httpclient.fetch( | |
45 networking.musicPlayer.path('time'), timeout=.5)).body) | |
46 songTime=musicStatus['t'] | |
47 songDuration=musicStatus['duration'] | |
48 | |
49 cr = CurveResource(graph, uri) | |
50 cr.newCurve(ctx, label=Literal(label)) | |
51 fade = 2 | |
52 t1 = clamp(songTime - fade, .1, songDuration - .1 * 2) + fade | |
53 t2 = clamp(songTime + 20, t1 + .1, songDuration) | |
54 print vars() | |
55 | |
56 cr.curve.insert_pt((t1 - fade, 0)) | |
57 cr.curve.insert_pt((t1, 1)) | |
58 cr.curve.insert_pt((t2, 1)) | |
59 cr.curve.insert_pt((t2 + fade, 0)) | |
60 cr.saveCurve() | |
61 | |
62 def newEffect(graph, song, ctx): | |
63 effect = graph.sequentialUri(song + "/effect-") | |
64 quads = [ | |
65 (song, L9['effect'], effect, ctx), | |
66 (effect, RDF.type, L9['Effect'], ctx), | |
67 ] | |
68 return effect, quads | |
69 | |
70 def musicCurveForSong(uri): | |
71 return URIRef(uri + 'music') | |
72 | |
36 class SongEffects(PrettyErrorHandler, cyclone.web.RequestHandler): | 73 class SongEffects(PrettyErrorHandler, cyclone.web.RequestHandler): |
74 @inlineCallbacks | |
37 def post(self): | 75 def post(self): |
38 song = URIRef(self.get_argument('uri')) | 76 song = URIRef(self.get_argument('uri')) |
39 dropped = URIRef(self.get_argument('drop')) | 77 dropped = URIRef(self.get_argument('drop')) |
40 ctx = song | 78 ctx = song |
41 graph = self.settings.graph | 79 graph = self.settings.graph |
42 effect = graph.sequentialUri(song + "/effect-") | 80 |
43 quads = [ | |
44 (song, L9['effect'], effect, ctx), | |
45 (effect, RDF.type, L9['Effect'], ctx), | |
46 ] | |
47 | |
48 with graph.currentState( | 81 with graph.currentState( |
49 tripleFilter=(dropped, None, None)) as g: | 82 tripleFilter=(dropped, None, None)) as g: |
50 droppedTypes = list(g.objects(dropped, RDF.type)) | 83 droppedTypes = list(g.objects(dropped, RDF.type)) |
51 droppedLabel = g.label(dropped) | 84 droppedLabel = g.label(dropped) |
52 droppedCodes = list(g.objects(dropped, L9['code'])) | 85 droppedCodes = list(g.objects(dropped, L9['code'])) |
53 | 86 |
87 quads = [] | |
88 | |
89 effect, q = newEffect(graph, song, ctx) | |
90 quads.extend(q) | |
91 | |
92 curve = graph.sequentialUri(song + "/curve-") | |
93 yield newEnvelopeCurve(graph, ctx, curve, droppedLabel) | |
94 quads.extend([ | |
95 (song, L9['curve'], curve, ctx), | |
96 (effect, RDFS.label, droppedLabel, ctx), | |
97 (effect, L9['code'], Literal('env = %s' % curve.n3()), ctx), | |
98 ]) | |
99 | |
54 if L9['EffectClass'] in droppedTypes: | 100 if L9['EffectClass'] in droppedTypes: |
55 quads.extend([ | 101 quads.extend([ |
56 (effect, RDFS.label, droppedLabel, ctx), | |
57 (effect, RDF.type, dropped, ctx), | 102 (effect, RDF.type, dropped, ctx), |
58 ] + [(effect, L9['code'], c, ctx) for c in droppedCodes]) | 103 ] + [(effect, L9['code'], c, ctx) for c in droppedCodes]) |
59 elif L9['Submaster'] in droppedTypes: | 104 elif L9['Submaster'] in droppedTypes: |
60 curve = graph.sequentialUri(song + "/curve-") | |
61 cr = CurveResource(graph, curve) | |
62 cr.newCurve(ctx, label=Literal('sub %s' % droppedLabel)) | |
63 cr.saveCurve() | |
64 quads.extend([ | 105 quads.extend([ |
65 (song, L9['curve'], curve, ctx), | 106 (effect, L9['code'], Literal('out = %s * env' % dropped.n3()), |
66 (effect, RDFS.label, Literal('sub %s' % droppedLabel), ctx), | |
67 (effect, L9['code'], | |
68 Literal('out = %s * %s' % (dropped.n3(), curve.n3())), | |
69 ctx), | 107 ctx), |
70 ]) | 108 ]) |
71 else: | 109 else: |
72 raise NotImplementedError( | 110 raise NotImplementedError( |
73 "don't know how to add an effect from %r (types=%r)" % | 111 "don't know how to add an effect from %r (types=%r)" % |
74 (dropped, droppedTypes)) | 112 (dropped, droppedTypes)) |
113 | |
114 for spoc in quads: | |
115 if 'music' in spoc[2]: | |
116 quads.extend([ | |
117 (effect, L9['code'], | |
118 Literal('music = %s' % musicCurveForSong(song).n3()), ctx) | |
119 ]) | |
120 break | |
75 | 121 |
76 graph.patch(Patch(addQuads=quads)) | 122 graph.patch(Patch(addQuads=quads)) |
77 | 123 |
78 class SongEffectsUpdates(cyclone.websocket.WebSocketHandler): | 124 class SongEffectsUpdates(cyclone.websocket.WebSocketHandler): |
79 def connectionMade(self, *args, **kwargs): | 125 def connectionMade(self, *args, **kwargs): |
215 (r'/static/(.*)', SFH, {'path': 'static/'}), | 261 (r'/static/(.*)', SFH, {'path': 'static/'}), |
216 (r'/effect/eval', EffectEval), | 262 (r'/effect/eval', EffectEval), |
217 (r'/songEffects', SongEffects), | 263 (r'/songEffects', SongEffects), |
218 (r'/songEffects/eval', SongEffectsEval), | 264 (r'/songEffects/eval', SongEffectsEval), |
219 (r'/stats', StatsForCyclone), | 265 (r'/stats', StatsForCyclone), |
220 ], debug=True, graph=self.graph, stats=self.stats) | 266 ], |
267 debug=True, | |
268 graph=self.graph, | |
269 stats=self.stats) | |
221 reactor.listenTCP(networking.effectEval.port, self.cycloneApp) | 270 reactor.listenTCP(networking.effectEval.port, self.cycloneApp) |
222 log.info("listening on %s" % networking.effectEval.port) | 271 log.info("listening on %s" % networking.effectEval.port) |
223 | 272 |
224 class StaticCoffee(PrettyErrorHandler, cyclone.web.RequestHandler): | 273 class StaticCoffee(PrettyErrorHandler, cyclone.web.RequestHandler): |
225 def initialize(self, src): | 274 def initialize(self, src): |