# HG changeset patch # User Drew Perttula # Date 2014-06-02 07:04:40 # Node ID c756638275d6f99adec53c76e0a98fb3d0d3f151 # Parent 0fb89da08e6619af41c0e193cb2b7ce27116ff8f quneo input demo. optimize curve display a little. Ignore-this: 4cf5b4b5853a94842c9fa8e2916bc6f4 diff --git a/bin/inputdemo b/bin/inputdemo --- a/bin/inputdemo +++ b/bin/inputdemo @@ -12,6 +12,7 @@ from light9 import showconfig, networkin from light9.rdfdb import clientsession from light9.rdfdb.syncedgraph import SyncedGraph import cyclone.httpclient +from light9.curvecalc.client import sendLiveInputPoint class App(object): def __init__(self): @@ -49,20 +50,10 @@ class App(object): win.show_all() def onChanged(self, scale): - f = cyclone.httpclient.fetch( - networking.curveCalc.path('liveInputPoint'), - method='POST', timeout=1, - postdata=urllib.urlencode({ - 'curve': self.curve, - 'value': str(scale.get_value()), - })) - @f.addCallback - def cb(result): - if result.code // 100 != 2: - log.error("curveCalc said %s: %s", result.code, result.body) + t1 = time.time() + d = sendLiveInputPoint(self.curve, scale.get_value()) + @d.addCallback + def done(result): print "posted in %.1f ms" % (1000 * (time.time() - t1)) - @f.addErrback - def eb(err): - print "err", err App() diff --git a/bin/inputquneo b/bin/inputquneo new file mode 100644 --- /dev/null +++ b/bin/inputquneo @@ -0,0 +1,65 @@ +#!bin/python +""" +read Quneo midi events, write to curvecalc and maybe to effects +""" +from __future__ import division +from run_local import log +import cyclone.web, cyclone.httpclient +from rdflib import URIRef +from twisted.internet import reactor, task +from light9.curvecalc.client import sendLiveInputPoint + +import sys +sys.path.append('/usr/lib/python2.7/dist-packages') # For pygame +import pygame.midi + +curves = { + 23: URIRef('http://light9.bigasterisk.com/show/dance2014/song1/curve/c-2'), + 24: URIRef('http://light9.bigasterisk.com/show/dance2014/song1/curve/c-3'), + 25: URIRef('http://light9.bigasterisk.com/show/dance2014/song1/curve/c-4'), + 6:URIRef('http://light9.bigasterisk.com/show/dance2014/song1/curve/c-5'), + 18: URIRef('http://light9.bigasterisk.com/show/dance2014/song1/curve/c-6'), +} + +class WatchMidi(object): + def __init__(self): + pygame.midi.init() + + dev = self.findQuneo() + self.inp = pygame.midi.Input(dev) + task.LoopingCall(self.step).start(.05) + + self.noteOn = {} + + def findQuneo(self): + for dev in range(pygame.midi.get_count()): + interf, name, isInput, isOutput, opened = pygame.midi.get_device_info(dev) + if 'QUNEO' in name and isInput: + return dev + raise ValueError("didn't find quneo input device") + + def step(self): + if not self.inp.poll(): + return + for ev in self.inp.read(999): + (status, d1, d2, _), _ = ev + print status, d1, d2 + + for group in [(23,24,25), (6, 18)]: + if d1 in group: + if not self.noteOn.get(group): + print "start zero" + for d in group: + sendLiveInputPoint(curves[d], 0) + self.noteOn[group] = True + else: # miss first update + sendLiveInputPoint(curves[d1], d2 / 127) + + if status == 128: #noteoff + for d in group: + sendLiveInputPoint(curves[d], 0) + self.noteOn[group] = False + + +wm = WatchMidi() +reactor.run() diff --git a/light9/curvecalc/client.py b/light9/curvecalc/client.py new file mode 100644 --- /dev/null +++ b/light9/curvecalc/client.py @@ -0,0 +1,21 @@ +""" +client code for talking to curvecalc +""" +import cyclone.httpclient +from light9 import networking +import urllib +from run_local import log + +def sendLiveInputPoint(curve, value): + f = cyclone.httpclient.fetch( + networking.curveCalc.path('liveInputPoint'), + method='POST', timeout=1, + postdata=urllib.urlencode({ + 'curve': curve, + 'value': str(value), + })) + @f.addCallback + def cb(result): + if result.code // 100 != 2: + raise ValueError("curveCalc said %s: %s", result.code, result.body) + return f diff --git a/light9/curvecalc/curve.py b/light9/curvecalc/curve.py --- a/light9/curvecalc/curve.py +++ b/light9/curvecalc/curve.py @@ -100,9 +100,9 @@ class Curve(object): # missing a check that this isn't the same X as the neighbor point return i - def live_input_point(self, new_pt): + def live_input_point(self, new_pt, clear_ahead_secs=.01): x, y = new_pt - exist = self.points_between(x, x + .01) + exist = self.points_between(x, x + clear_ahead_secs) for pt in exist: self.remove_point(pt) self.insert_pt(new_pt) diff --git a/light9/curvecalc/curveedit.py b/light9/curvecalc/curveedit.py --- a/light9/curvecalc/curveedit.py +++ b/light9/curvecalc/curveedit.py @@ -44,5 +44,5 @@ class CurveEdit(object): def liveInputPoint(self, curveUri, value): curve = self.curveset.curveFromUri(curveUri) - curve.live_input_point((self.currentTime, value)) + curve.live_input_point((self.currentTime, value), clear_ahead_secs=.5) diff --git a/light9/curvecalc/curveview.py b/light9/curvecalc/curveview.py --- a/light9/curvecalc/curveview.py +++ b/light9/curvecalc/curveview.py @@ -735,14 +735,12 @@ class Curveview(object): "gray20" if self.curve.muted else "black") self.update_time_bar(self._time) - if self.canvas.props.y2 < 40: - self._draw_line(visible_points, area=True) - else: + self._draw_line(visible_points, area=True) + self._draw_markers( + self.markers.points[i] for i in + self.markers.indices_between(visible_x[0], visible_x[1])) + if self.canvas.props.y2 > 80: self._draw_time_tics(visible_x) - self._draw_line(visible_points) - self._draw_markers( - self.markers.points[i] for i in - self.markers.indices_between(visible_x[0], visible_x[1])) self.dots = {} # idx : canvas rectangle @@ -1071,7 +1069,7 @@ class CurveRow(object): self.box.add(self.cols) controls = Gtk.Frame() - controls.set_size_request(115, -1) + controls.set_size_request(160, -1) controls.set_shadow_type(Gtk.ShadowType.OUT) self.cols.pack_start(controls, expand=False, fill=True, padding=0) self.setupControls(controls, name, curve, slider) @@ -1104,6 +1102,8 @@ class CurveRow(object): def setHeight(self, h): self.curveView.widget.set_size_request(-1, h) + # the event watcher wasn't catching these + reactor.callLater(.5, self.curveView.update_curve) def setupControls(self, controls, name, curve, slider): box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0) diff --git a/makefile b/makefile --- a/makefile +++ b/makefile @@ -52,4 +52,4 @@ gst_packages: sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio gir1.2-goocanvas-2.0-9 packages: - sudo aptitude install coffeescript freemind normalize-audio audacity python-pygoocanvas + sudo aptitude install coffeescript freemind normalize-audio audacity python-pygoocanvas python-pygame