Changeset - 6c4981f61bf8
[Not reviewed]
default
0 3 0
Drew Perttula - 11 years ago 2014-06-15 08:41:02
drewp@bigasterisk.com
subserver inserts effects with envelope curves
Ignore-this: 2209ad8a0b93b78719bb5347aea5557e
3 files changed with 76 insertions and 17 deletions:
0 comments (0 inline, 0 general)
bin/effecteval
Show inline comments
 
@@ -7,12 +7,13 @@ import cyclone.web, cyclone.websocket, c
 
import sys, optparse, logging, subprocess, json, time, traceback, itertools
 
from rdflib import URIRef, Literal
 

	
 
sys.path.append('/usr/lib/pymodules/python2.7/') # for numpy, on rpi
 
sys.path.append('/usr/lib/python2.7/dist-packages') # For numpy
 
from light9 import networking, showconfig, Submaster, dmxclient
 
from light9.curvecalc import musicaccess
 
from light9.curvecalc.curve import CurveResource
 
from light9.effecteval.effect import EffectNode
 
from light9.effecteval.effectloop import makeEffectLoop
 
from light9.greplin_cyclone import StatsForCyclone
 
from light9.namespaces import L9, RDF, RDFS
 
from light9.rdfdb.patch import Patch
 
@@ -30,51 +31,96 @@ class EffectEdit(PrettyErrorHandler, cyc
 
        with graph.currentState(tripleFilter=(None, L9['effect'], uri)) as g:
 
            song = ctx = list(g.subjects(L9['effect'], uri))[0]
 
        self.settings.graph.patch(Patch(delQuads=[
 
            (song, L9['effect'], uri, ctx),
 
            ]))
 
        
 
def clamp(x, lo, hi):
 
    return max(lo, min(hi, x))
 
    
 
@inlineCallbacks
 
def newEnvelopeCurve(graph, ctx, uri, label):
 
    """this does its own patch to the graph"""
 
    
 
    musicStatus = json.loads((yield cyclone.httpclient.fetch(
 
        networking.musicPlayer.path('time'), timeout=.5)).body)
 
    songTime=musicStatus['t']
 
    songDuration=musicStatus['duration']
 
    
 
    cr = CurveResource(graph, uri)
 
    cr.newCurve(ctx, label=Literal(label))
 
    fade = 2
 
    t1 = clamp(songTime - fade, .1, songDuration - .1 * 2) + fade
 
    t2 = clamp(songTime + 20, t1 + .1, songDuration)
 
    print vars()
 
    
 
    cr.curve.insert_pt((t1 - fade, 0))
 
    cr.curve.insert_pt((t1, 1))
 
    cr.curve.insert_pt((t2, 1))
 
    cr.curve.insert_pt((t2 + fade, 0))
 
    cr.saveCurve()
 

	
 
def newEffect(graph, song, ctx):
 
    effect = graph.sequentialUri(song + "/effect-")
 
    quads = [
 
        (song, L9['effect'], effect, ctx),
 
        (effect, RDF.type, L9['Effect'], ctx),
 
    ]
 
    return effect, quads
 
    
 
def musicCurveForSong(uri):
 
    return URIRef(uri + 'music')
 
    
 
class SongEffects(PrettyErrorHandler, cyclone.web.RequestHandler):
 
    @inlineCallbacks
 
    def post(self):
 
        song = URIRef(self.get_argument('uri'))
 
        dropped = URIRef(self.get_argument('drop'))
 
        ctx = song
 
        graph = self.settings.graph
 
        effect = graph.sequentialUri(song + "/effect-")
 
        quads = [
 
            (song, L9['effect'], effect, ctx),
 
            (effect, RDF.type, L9['Effect'], ctx),
 
        ]
 

	
 
        
 
        with graph.currentState(
 
                tripleFilter=(dropped, None, None)) as g:
 
            droppedTypes = list(g.objects(dropped, RDF.type))
 
            droppedLabel = g.label(dropped)
 
            droppedCodes = list(g.objects(dropped, L9['code']))
 

	
 
        quads = []
 
            
 
        effect, q = newEffect(graph, song, ctx)
 
        quads.extend(q)
 

	
 
        curve = graph.sequentialUri(song + "/curve-")
 
        yield newEnvelopeCurve(graph, ctx, curve, droppedLabel)
 
        quads.extend([
 
            (song, L9['curve'], curve, ctx),
 
            (effect, RDFS.label, droppedLabel, ctx),
 
            (effect, L9['code'], Literal('env = %s' % curve.n3()), ctx),
 
            ])
 
        
 
        if L9['EffectClass'] in droppedTypes:
 
            quads.extend([
 
                (effect, RDFS.label, droppedLabel, ctx),
 
                (effect, RDF.type, dropped, ctx),
 
                ] + [(effect, L9['code'], c, ctx) for c in droppedCodes])
 
        elif L9['Submaster'] in droppedTypes:
 
            curve = graph.sequentialUri(song + "/curve-")
 
            cr = CurveResource(graph, curve)
 
            cr.newCurve(ctx, label=Literal('sub %s' % droppedLabel))
 
            cr.saveCurve()
 
            quads.extend([
 
                (song, L9['curve'], curve, ctx),
 
                (effect, RDFS.label, Literal('sub %s' % droppedLabel), ctx),
 
                (effect, L9['code'],
 
                 Literal('out = %s * %s' % (dropped.n3(), curve.n3())),
 
                (effect, L9['code'], Literal('out = %s * env' % dropped.n3()),
 
                 ctx),
 
                ])
 
        else:
 
            raise NotImplementedError(
 
                "don't know how to add an effect from %r (types=%r)" %
 
                (dropped, droppedTypes))
 

	
 
        for spoc in quads:
 
            if 'music' in spoc[2]:
 
                quads.extend([
 
                    (effect, L9['code'],
 
                     Literal('music = %s' % musicCurveForSong(song).n3()), ctx)
 
                    ])
 
                break
 
            
 
        graph.patch(Patch(addQuads=quads))
 
        
 
class SongEffectsUpdates(cyclone.websocket.WebSocketHandler):
 
    def connectionMade(self, *args, **kwargs):
 
        self.graph = self.settings.graph
 
@@ -214,13 +260,16 @@ class App(object):
 
            (r'/songEffectsUpdates', SongEffectsUpdates),
 
            (r'/static/(.*)', SFH, {'path': 'static/'}),
 
            (r'/effect/eval', EffectEval),
 
            (r'/songEffects', SongEffects),
 
            (r'/songEffects/eval', SongEffectsEval),
 
            (r'/stats', StatsForCyclone),
 
        ], debug=True, graph=self.graph, stats=self.stats)
 
        ],
 
                                                  debug=True,
 
                                                  graph=self.graph,
 
                                                  stats=self.stats)
 
        reactor.listenTCP(networking.effectEval.port, self.cycloneApp)
 
        log.info("listening on %s" % networking.effectEval.port)
 
        
 
class StaticCoffee(PrettyErrorHandler, cyclone.web.RequestHandler):
 
    def initialize(self, src):
 
        super(StaticCoffee, self).initialize()
show/dance2014/effectClass.n3
Show inline comments
 
@@ -2,16 +2,26 @@
 
@prefix effect: <http://light9.bigasterisk.com/effect/> .
 
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
 
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 

	
 

	
 
# when these are inserted, a curve called 'env' will be added to this
 
# code, so multiply by that. Also if you mention 'music' anywhere, an
 
# output 'music' will be set to the current song.
 

	
 

	
 
effect:cycFlash a :EffectClass;
 
  rdfs:label "cycFlash";
 
  :code "out = <http://light9.bigasterisk.com/show/dance2013/sub/cyc> * nsin(t*2)" .
 

	
 
  
 
effect:cycToMusic a :EffectClass; rdfs:label "cyc to music";
 
:code "out = <http://light9.bigasterisk.com/show/dance2013/sub/cyc> * music * env" .
 

	
 
effect:blacklight a :EffectClass;
 
  rdfs:label "blacklight";
 
  :code 
 
    "env = <http://light9.bigasterisk.com/show/dance2014/song1/curve-1>",
 
    "out = [env * p1, env * p2, env * p3, env * p4]",
 
    "p1 = env * <http://light9.bigasterisk.com/show/dance2013/sub/blue> * .5",
show/dance2014/song1/curve-1.n3
Show inline comments
 
@prefix ns1: <http://light9.bigasterisk.com/> .
 
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
 
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 

	
 
<http://light9.bigasterisk.com/show/dance2014/song1/curve-1> ns1:points "0 0 0 0 0.2424 0.4681 0.2909 0.5426 0.3297 0.5957 0.3879 0.6915 0.4267 0.734 0.4848 0.7979 0.5818 0.8511 0.6497 0.8723 0.6982 0.8617 0.737 0.7872 0.7757 0.7553 0.8339 0.6915 0.8921 0.6277 0.9406 0.5638 0.9794 0.4468 1.018 0.3723 1.067 0.2766 1.105 0.234 1.144 0.2234 1.381 0.06327 1.61 0.2128 1.648 0.2553 1.726 0.3191 1.813 0.4468 1.871 0.5106 1.92 0.6064 1.988 0.734 2.027 0.8191 2.065 0.883 2.133 0.883 2.182 0.8191 2.23 0.734 2.279 0.617 2.376 0.4894 2.434 0.4468 2.473 0.2979 2.521 0.2021 2.579 0.1489 2.618 0.1383 2.667 0.1064 2.725 0.08511 2.793 0.1064 2.851 0.1383 2.938 0.1915 2.977 0.4362 3.035 0.2872 3.093 0.3511 3.142 0.4255 3.161 0.5532 3.181 0.4681 3.248 0.5532 3.248 0.6383 3.287 0.6383 3.316 0.7234 3.336 0.766 3.355 0.766 3.374 0.8191 3.413 0.8404 63.32 0.4149 65.41 0.5426 66.24 0.6489 66.8 0.6064 67.64 0.4681 68.33 0.3723 69.45 0.2979 70.28 0.3511 71.68 0.4787 72.23 0.5638 73.07 0.5426 73.76 0.4894 74.6 0.4043 75.16 0.3617 75.99 0.3085 76.97 0.2979 77.66 0.3511 149.8 1 206.3 0.9256 211.2 0" .
 
<http://light9.bigasterisk.com/show/dance2014/song1/curve-1> ns1:points "0 0 0 0 0.2424 0.4681 0.2909 0.5426 0.3297 0.5957 0.3879 0.6915 0.4267 0.734 0.4848 0.7979 0.5818 0.8511 0.6497 0.8723 0.6982 0.8617 0.737 0.7872 0.7757 0.7553 0.8339 0.6915 0.8921 0.6277 0.9406 0.5638 0.9794 0.4468 1.018 0.3723 1.067 0.2766 1.105 0.234 1.144 0.2234 1.381 0.06327 1.61 0.2128 1.648 0.2553 1.726 0.3191 1.813 0.4468 1.871 0.5106 1.92 0.6064 1.988 0.734 2.027 0.8191 2.065 0.883 2.133 0.883 2.182 0.8191 2.23 0.734 2.279 0.617 2.376 0.4894 2.434 0.4468 2.473 0.2979 2.521 0.2021 2.579 0.1489 2.618 0.1383 2.667 0.1064 2.725 0.08511 2.793 0.1064 2.851 0.1383 2.938 0.1915 2.977 0.4362 3.035 0.2872 3.093 0.3511 3.142 0.4255 3.161 0.5532 3.181 0.4681 3.248 0.5532 3.248 0.6383 3.287 0.6383 3.316 0.7234 3.336 0.766 3.355 0.766 3.374 0.8191 3.413 0.8404 38.06 0.2456 38.97 0.7998 63.32 0.4149 65.41 0.5426 66.24 0.6489 66.8 0.6064 67.64 0.4681 68.33 0.3723 69.45 0.2979 70.28 0.3511 71.68 0.4787 72.23 0.5638 73.07 0.5426 73.76 0.4894 74.6 0.4043 75.16 0.3617 75.99 0.3085 76.97 0.2979 77.66 0.3511 149.8 1 206.3 0.9256 211.2 0" .
 

	
0 comments (0 inline, 0 general)