changeset 2341:4f610ef6768d

write graph values of current fader page back out over midi
author drewp@bigasterisk.com
date Fri, 02 Jun 2023 18:27:03 -0700
parents 45975e8f16f0
children 81d5b6d97ed3
files light9/midifade/midifade.py show/dance2023/fade.n3
diffstat 2 files changed, 100 insertions(+), 277 deletions(-) [+]
line wrap: on
line diff
--- a/light9/midifade/midifade.py	Fri Jun 02 17:35:08 2023 -0700
+++ b/light9/midifade/midifade.py	Fri Jun 02 18:27:03 2023 -0700
@@ -5,11 +5,11 @@
 import asyncio
 import logging
 import traceback
-from typing import Dict
+from typing import Dict, List
 
 import mido
 from rdfdb.syncedgraph.syncedgraph import SyncedGraph
-from rdflib import URIRef
+from rdflib import Literal, URIRef
 
 from light9 import networking
 from light9.namespaces import L9
@@ -20,13 +20,18 @@
 mido.set_backend('alsa_midi.mido_backend')
 MAX_SEND_RATE = 20
 
+_lastSet = {}  #Fader:value
+
 
 def setFader(graph: SyncedGraph, ctx, fader: URIRef, strength: float):
     log.info(f'setFader(fader={fader}, strength={strength:.03f}')
     valueLit = decimalLiteral(round(strength, 3))
     with graph.currentState() as g:
         fadeSet = g.value(fader, L9['setting'])
+    if fadeSet is None:
+        raise ValueError(f'fader {fader} has no :setting')
     graph.patchObject(ctx, fadeSet, L9['value'], valueLit)
+    _lastSet[fader] = strength
 
 
 def onMessage(graph: SyncedGraph, ctx: URIRef, m: Dict):
@@ -42,24 +47,77 @@
                     46: L9['show/dance2023/fadePage1f0'],
                 },
                 'bcf2000': {
-                    81: L9['show/dance2023/fadePage1f0'],
-                    82: L9['show/dance2023/fadePage1f1'],
-                    83: L9['show/dance2023/fadePage1f2'],
-                    84: L9['show/dance2023/fadePage1f3'],
-                    85: L9['show/dance2023/fadePage1f4'],
-                    86: L9['show/dance2023/fadePage1f5'],
-                    87: L9['show/dance2023/fadePage1f6'],
-                    88: L9['show/dance2023/fadePage1f7'],
+                    81: L9['show/dance2023/fader0'],
+                    82: L9['show/dance2023/fader1'],
+                    83: L9['show/dance2023/fader2'],
+                    84: L9['show/dance2023/fader3'],
+                    85: L9['show/dance2023/fader4'],
+                    86: L9['show/dance2023/fader5'],
+                    87: L9['show/dance2023/fader6'],
+                    88: L9['show/dance2023/fader7'],
                 }
             }[m['dev']][m['control']]
         except KeyError:
             log.info(f'unknown control {m}')
             return
-        setFader(graph, ctx, fader, m['value'] / 127)
+        try:
+            setFader(graph, ctx, fader, m['value'] / 127)
+        except ValueError as e:
+            log.warning(f'{e!r} - ignoring')
     else:
         log.info(f'unhandled message {m}')
 
 
+def reduceToLatestValue(ms: List[Dict]) -> List[Dict]:
+    merge = {}
+    for m in ms:
+        normal_key = tuple(sorted(dict((k, v) for k, v in m.items() if k != 'value')))
+        merge[normal_key] = m
+    return merge.values()
+
+
+class WriteBackFaders:
+
+    def __init__(self, graph: SyncedGraph, bcf_out, getCurrentValue):
+        self.graph = graph
+        self.bcf_out = bcf_out
+        self.getCurrentValue = getCurrentValue
+
+    def update(self):
+        try:
+            self._update()
+        except ValueError as e:
+            log.warning(repr(e))
+
+    def _update(self):
+        g = self.graph
+        mapping = g.value(L9['midiControl'], L9['map'])
+        if mapping is None:
+            raise ValueError('no :midiControl :map ?mapping')
+        midiDev = g.value(mapping, L9['midiDev'])
+        ourDev = 'bcf2000'
+        if midiDev != Literal(ourDev):
+            raise NotImplementedError(f'need {mapping} to have :midiDev {ourDev!r}')
+        fadePage = g.value(mapping, L9['outputs'])
+        nupdated=0
+        faders = list(g.objects(fadePage, L9.fader))
+        for f in faders:
+            column = int(g.value(f, L9.column).toPython())
+            fset = g.value(f, L9.setting)
+            # could split this to a separate handler per fader
+            value = g.value(fset, L9.value).toPython()
+            hwcurrent = int(self.getCurrentValue(f) * 127)
+            hwgoal = int(value * 127)
+            if abs(hwcurrent - hwgoal) > 5:
+                midi_ctl_addr = column + 80
+                self.sendToBcf(midi_ctl_addr, hwgoal)
+                nupdated+=1
+        log.info(f'updated {nupdated} of {len(faders)} connected faders')
+    def sendToBcf(self, control, value):
+        msg = mido.Message('control_change', control=control, value=value)
+        self.bcf_out.send(msg)
+
+
 async def main():
     logging.getLogger('autodepgraphapi').setLevel(logging.INFO)
     logging.getLogger('syncedgraph').setLevel(logging.INFO)
@@ -80,7 +138,8 @@
             while not msgs.empty():
                 recents.append(msgs.get_nowait())
             try:
-                onMessage(graph, ctx, recents[-1])
+                for msg in reduceToLatestValue(recents):
+                    onMessage(graph, ctx, msg)
             except Exception as e:
                 traceback.print_exc()
                 log.warning("error in onMessage- continuing anyway")
@@ -98,11 +157,13 @@
         else:
             continue
         log.info(f'listening on input {inputName} {dev=}')
-        openPorts.append(
-            mido.open_input(#
-            inputName,#
-             callback=lambda message, dev=dev: onMessageMidoThread(dev, message))
-        )
+        openPorts.append(mido.open_input(  #
+            inputName,  #
+            callback=lambda message, dev=dev: onMessageMidoThread(dev, message)))
+
+    bcf_out = mido.open_output('BCF2000:BCF2000 MIDI 1 28:0')
+    wb = WriteBackFaders(graph, bcf_out, getCurrentValue=lambda f: _lastSet.get(f, 0))
+    graph.addHandler(wb.update)
 
     while True:
         await asyncio.sleep(1)
--- a/show/dance2023/fade.n3	Fri Jun 02 17:35:08 2023 -0700
+++ b/show/dance2023/fade.n3	Fri Jun 02 18:27:03 2023 -0700
@@ -5,276 +5,38 @@
 @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 :midiControl :map :midiControl0 .
+show:faderset8 :effectAttr :strength; :value 0.00 .
+show:faderset9 :effectAttr :strength; :value 0.00 .
+:fadeset0 :value 0.520 .
+:fadeset1 :value 0.571 .
+:fadeset2 :value 0.580 .
+:fadeset3 :value 0.589 .
+:fadeset4 :value 0.597 .
+:fadeset5 :value 0.606 .
+:midiControl0 :inputs "mainSliders"; :midiDev "bcf2000"; :outputs show:fadePage0 .
 
 show:fadePage0 a :FadePage; rdfs:label "first"; :fader show:fader0, show:fader1, show:fader2, show:fader3, show:fader4, show:fader5, show:fader6, show:fader7 .
 
-show:fadePage2 a :FadePage; rdfs:label "unnamed"; :fader show:fader40, show:fader41, show:fader42, show:fader43, show:fader44, show:fader45, show:fader46, show:fader47 .
-
-show:fadePage3 a :FadePage; rdfs:label "unnamed"; :fader show:fader48, show:fader49, show:fader50, show:fader51, show:fader52, show:fader53, show:fader54, show:fader55 .
-
-show:fadePage4 a :FadePage; rdfs:label "unnamed"; :fader show:fader56, show:fader57, show:fader58, show:fader59, show:fader60, show:fader61, show:fader62, show:fader63 .
-
-show:fadePage5 a :FadePage; rdfs:label "unnamed"; :fader show:fader64, show:fader65, show:fader66, show:fader67, show:fader68, show:fader69, show:fader70, show:fader71 .
-
-show:fadePage6 a :FadePage; rdfs:label "unnamed"; :fader show:fader72, show:fader73, show:fader74, show:fader75, show:fader76, show:fader77, show:fader78, show:fader79 .
-
-show:fadePage7 a :FadePage; rdfs:label "unnamed"; :fader show:fader80, show:fader81, show:fader82, show:fader83, show:fader84, show:fader85, show:fader86, show:fader87 .
-
-show:fader10 a :Fader; :column "3"; :setting show:faderset18 .
-
-show:fader11 a :Fader; :column "4"; :setting show:faderset19 .
-
-show:fader12 a :Fader; :column "5"; :setting show:faderset20 .
-
-show:fader13 a :Fader; :column "6"; :setting show:faderset21 .
-
-show:fader14 a :Fader; :column "7"; :setting show:faderset22 .
-
-show:fader15 a :Fader; :column "8"; :setting show:faderset23 .
-show:fader16 :column "1"; :setting show:faderset8 .
-show:fader17 :column "2"; :setting show:faderset9 .
-show:fader18 :column "3"; :setting show:faderset10 .
-show:fader19 :column "4"; :setting show:faderset11 .
-show:fader20 :column "5"; :setting show:faderset12 .
-show:fader21 :column "6"; :setting show:faderset13 .
-show:fader22 :column "7"; :setting show:faderset14 .
-show:fader23 :column "8"; :setting show:faderset15 .
-
-show:fader24 a :Fader; :column "1"; :setting show:faderset24 .
-
-show:fader25 a :Fader; :column "2"; :setting show:faderset25 .
-
-show:fader26 a :Fader; :column "3"; :setting show:faderset26 .
-
-show:fader27 a :Fader; :column "4"; :setting show:faderset27 .
-
-show:fader28 a :Fader; :column "5"; :setting show:faderset28 .
-
-show:fader29 a :Fader; :column "6"; :setting show:faderset29 .
-
-show:fader30 a :Fader; :column "7"; :setting show:faderset30 .
-
-show:fader31 a :Fader; :column "8"; :setting show:faderset31 .
-
-show:fader8 a :Fader; :column "1"; :setting show:faderset16 .
-
-show:fader9 a :Fader; :column "2"; :setting show:faderset17 .
-:midiControl0 :inputs "mainSliders"; :midiDev "bcf2000"; :outputs show:fadePage1 .
-
-show:fadePage1 a :FadePage; rdfs:label "second"; :fader show:fader32, show:fader33, show:fader34, show:fader35, show:fader36, show:fader37, show:fader38, show:fader39 .
-
 show:fader0 a :Fader; :column "1"; :effect effect:effect1; :setting show:faderset0 .
 
 show:fader1 a :Fader; :column "2"; :effect effect:effect6; :setting show:faderset1 .
 
-show:fader2 a :Fader; :column "3"; :effect effect:effect7; :setting show:faderset2 .
-
-show:fader3 a :Fader; :column "4"; :setting show:faderset3 .
-
-show:fader32 a :Fader; :column "1"; :setting show:faderset32 .
-
-show:fader33 a :Fader; :column "2"; :setting show:faderset33 .
-
-show:fader34 a :Fader; :column "3"; :setting show:faderset34 .
-
-show:fader35 a :Fader; :column "4"; :setting show:faderset35 .
-
-show:fader36 a :Fader; :column "5"; :setting show:faderset36 .
-
-show:fader37 a :Fader; :column "6"; :setting show:faderset37 .
-
-show:fader38 a :Fader; :column "7"; :setting show:faderset38 .
-
-show:fader39 a :Fader; :column "8"; :setting show:faderset39 .
+show:fader2 a :Fader; :column "3"; :effect effect:effect4; :setting show:faderset2 .
 
-show:fader4 a :Fader; :column "5"; :setting show:faderset4 .
-
-show:fader40 a :Fader; :column "1"; :setting show:faderset40 .
-
-show:fader41 a :Fader; :column "2"; :setting show:faderset41 .
-
-show:fader42 a :Fader; :column "3"; :setting show:faderset42 .
-
-show:fader43 a :Fader; :column "4"; :setting show:faderset43 .
-
-show:fader44 a :Fader; :column "5"; :setting show:faderset44 .
-
-show:fader45 a :Fader; :column "6"; :setting show:faderset45 .
-
-show:fader46 a :Fader; :column "7"; :setting show:faderset46 .
-
-show:fader47 a :Fader; :column "8"; :setting show:faderset47 .
-
-show:fader48 a :Fader; :column "1"; :setting show:faderset48 .
-
-show:fader49 a :Fader; :column "2"; :setting show:faderset49 .
+show:fader3 a :Fader; :column "4"; :effect effect:effect9; :setting show:faderset3 .
 
-show:fader5 a :Fader; :column "6"; :setting show:faderset5 .
-
-show:fader50 a :Fader; :column "3"; :setting show:faderset50 .
-
-show:fader51 a :Fader; :column "4"; :setting show:faderset51 .
-
-show:fader52 a :Fader; :column "5"; :setting show:faderset52 .
-
-show:fader53 a :Fader; :column "6"; :setting show:faderset53 .
-
-show:fader54 a :Fader; :column "7"; :setting show:faderset54 .
-
-show:fader55 a :Fader; :column "8"; :setting show:faderset55 .
-
-show:fader56 a :Fader; :column "1"; :setting show:faderset56 .
-
-show:fader57 a :Fader; :column "2"; :setting show:faderset57 .
-
-show:fader58 a :Fader; :column "3"; :setting show:faderset58 .
-
-show:fader59 a :Fader; :column "4"; :setting show:faderset59 .
+show:fader4 a :Fader; :column "5"; :effect effect:effect2; :setting show:faderset4 .
 
-show:fader6 a :Fader; :column "7"; :setting show:faderset6 .
-
-show:fader60 a :Fader; :column "5"; :setting show:faderset60 .
-
-show:fader61 a :Fader; :column "6"; :setting show:faderset61 .
-
-show:fader62 a :Fader; :column "7"; :setting show:faderset62 .
-
-show:fader63 a :Fader; :column "8"; :setting show:faderset63 .
+show:fader5 a :Fader; :column "6"; :effect effect:effect3; :setting show:faderset5 .
 
-show:fader64 a :Fader; :column "1"; :setting show:faderset64 .
-
-show:fader65 a :Fader; :column "2"; :setting show:faderset65 .
-
-show:fader66 a :Fader; :column "3"; :setting show:faderset66 .
-
-show:fader67 a :Fader; :column "4"; :setting show:faderset67 .
-
-show:fader68 a :Fader; :column "5"; :setting show:faderset68 .
-
-show:fader69 a :Fader; :column "6"; :setting show:faderset69 .
+show:fader6 a :Fader; :column "7"; :effect effect:effect8; :setting :fadeset0, :fadeset1, :fadeset2, :fadeset3, :fadeset4, :fadeset5, show:faderset6 .
 
 show:fader7 a :Fader; :column "8"; :setting show:faderset7 .
-
-show:fader70 a :Fader; :column "7"; :setting show:faderset70 .
-
-show:fader71 a :Fader; :column "8"; :setting show:faderset71 .
-
-show:fader72 a :Fader; :column "1"; :setting show:faderset72 .
-
-show:fader73 a :Fader; :column "2"; :setting show:faderset73 .
-
-show:fader74 a :Fader; :column "3"; :setting show:faderset74 .
-
-show:fader75 a :Fader; :column "4"; :setting show:faderset75 .
-
-show:fader76 a :Fader; :column "5"; :setting show:faderset76 .
-
-show:fader77 a :Fader; :column "6"; :setting show:faderset77 .
-
-show:fader78 a :Fader; :column "7"; :setting show:faderset78 .
-
-show:fader79 a :Fader; :column "8"; :setting show:faderset79 .
-
-show:fader80 a :Fader; :column "1"; :setting show:faderset80 .
-
-show:fader81 a :Fader; :column "2"; :setting show:faderset81 .
-
-show:fader82 a :Fader; :column "3"; :setting show:faderset82 .
-
-show:fader83 a :Fader; :column "4"; :setting show:faderset83 .
-
-show:fader84 a :Fader; :column "5"; :setting show:faderset84 .
-
-show:fader85 a :Fader; :column "6"; :setting show:faderset85 .
-
-show:fader86 a :Fader; :column "7"; :setting show:faderset86 .
-
-show:fader87 a :Fader; :column "8"; :setting show:faderset87 .
-show:faderset0 :effectAttr :strength; :value 1.00 .
-show:faderset1 :effectAttr :strength; :value 0.208 .
-show:faderset10 :effectAttr :strength; :value 0.00 .
-show:faderset11 :effectAttr :strength; :value 0.00 .
-show:faderset12 :effectAttr :strength; :value 0.00 .
-show:faderset13 :effectAttr :strength; :value 0.00 .
-show:faderset14 :effectAttr :strength; :value 0.00 .
-show:faderset15 :effectAttr :strength; :value 0.00 .
-show:faderset16 :effectAttr :strength; :value 0.00 .
-show:faderset17 :effectAttr :strength; :value 0.00 .
-show:faderset18 :effectAttr :strength; :value 0.00 .
-show:faderset19 :effectAttr :strength; :value 0.00 .
-show:faderset2 :effectAttr :strength; :value 0.357 .
-show:faderset20 :effectAttr :strength; :value 0.00 .
-show:faderset21 :effectAttr :strength; :value 0.00 .
-show:faderset22 :effectAttr :strength; :value 0.00 .
-show:faderset23 :effectAttr :strength; :value 0.00 .
-show:faderset24 :effectAttr :strength; :value 0.00 .
-show:faderset25 :effectAttr :strength; :value 0.00 .
-show:faderset26 :effectAttr :strength; :value 0.00 .
-show:faderset27 :effectAttr :strength; :value 0.00 .
-show:faderset28 :effectAttr :strength; :value 0.00 .
-show:faderset29 :effectAttr :strength; :value 0.00 .
-show:faderset3 :effectAttr :strength; :value 0.250 .
-show:faderset30 :effectAttr :strength; :value 0.00 .
-show:faderset31 :effectAttr :strength; :value 0.00 .
-show:faderset32 :effectAttr :strength; :value 0.00 .
-show:faderset33 :effectAttr :strength; :value 0.00 .
-show:faderset34 :effectAttr :strength; :value 0.00 .
-show:faderset35 :effectAttr :strength; :value 0.00 .
-show:faderset36 :effectAttr :strength; :value 0.00 .
-show:faderset37 :effectAttr :strength; :value 0.00 .
-show:faderset38 :effectAttr :strength; :value 0.530 .
-show:faderset39 :effectAttr :strength; :value 0.00 .
-show:faderset4 :effectAttr :strength; :value 0.00 .
-show:faderset40 :effectAttr :strength; :value 0.00 .
-show:faderset41 :effectAttr :strength; :value 0.00 .
-show:faderset42 :effectAttr :strength; :value 0.00 .
-show:faderset43 :effectAttr :strength; :value 0.00 .
-show:faderset44 :effectAttr :strength; :value 0.00 .
-show:faderset45 :effectAttr :strength; :value 0.00 .
-show:faderset46 :effectAttr :strength; :value 0.00 .
-show:faderset47 :effectAttr :strength; :value 0.00 .
-show:faderset48 :effectAttr :strength; :value 0.00 .
-show:faderset49 :effectAttr :strength; :value 0.00 .
-show:faderset5 :effectAttr :strength; :value 0.403 .
-show:faderset50 :effectAttr :strength; :value 0.00 .
-show:faderset51 :effectAttr :strength; :value 0.00 .
-show:faderset52 :effectAttr :strength; :value 0.00 .
-show:faderset53 :effectAttr :strength; :value 0.00 .
-show:faderset54 :effectAttr :strength; :value 0.413 .
-show:faderset55 :effectAttr :strength; :value 0.200 .
-show:faderset56 :effectAttr :strength; :value 0.00 .
-show:faderset57 :effectAttr :strength; :value 0.00 .
-show:faderset58 :effectAttr :strength; :value 0.00 .
-show:faderset59 :effectAttr :strength; :value 0.00 .
-show:faderset6 :effectAttr :strength; :value 0.00 .
-show:faderset60 :effectAttr :strength; :value 0.00 .
-show:faderset61 :effectAttr :strength; :value 0.00 .
-show:faderset62 :effectAttr :strength; :value 0.00 .
-show:faderset63 :effectAttr :strength; :value 0.00 .
-show:faderset64 :effectAttr :strength; :value 0.00 .
-show:faderset65 :effectAttr :strength; :value 0.00 .
-show:faderset66 :effectAttr :strength; :value 0.00 .
-show:faderset67 :effectAttr :strength; :value 0.00 .
-show:faderset68 :effectAttr :strength; :value 0.00 .
-show:faderset69 :effectAttr :strength; :value 0.00 .
-show:faderset7 :effectAttr :strength; :value 0.00 .
-show:faderset70 :effectAttr :strength; :value 0.00 .
-show:faderset71 :effectAttr :strength; :value 0.00 .
-show:faderset72 :effectAttr :strength; :value 0.00 .
-show:faderset73 :effectAttr :strength; :value 0.00 .
-show:faderset74 :effectAttr :strength; :value 0.00 .
-show:faderset75 :effectAttr :strength; :value 0.00 .
-show:faderset76 :effectAttr :strength; :value 0.00 .
-show:faderset77 :effectAttr :strength; :value 0.00 .
-show:faderset78 :effectAttr :strength; :value 0.00 .
-show:faderset79 :effectAttr :strength; :value 0.00 .
-show:faderset8 :effectAttr :strength; :value 0.00 .
-show:faderset80 :effectAttr :strength; :value 0.00 .
-show:faderset81 :effectAttr :strength; :value 0.00 .
-show:faderset82 :effectAttr :strength; :value 0.00 .
-show:faderset83 :effectAttr :strength; :value 0.00 .
-show:faderset84 :effectAttr :strength; :value 0.00 .
-show:faderset85 :effectAttr :strength; :value 0.00 .
-show:faderset86 :effectAttr :strength; :value 0.00 .
-show:faderset87 :effectAttr :strength; :value 0.00 .
-show:faderset9 :effectAttr :strength; :value 0.00 .
+show:faderset0 :effectAttr :strength; :value 0.425 .
+show:faderset1 :effectAttr :strength; :value 0.126 .
+show:faderset2 :effectAttr :strength; :value 0.126 .
+show:faderset3 :effectAttr :strength; :value 1.00 .
+show:faderset4 :effectAttr :strength; :value 0.094 .
+show:faderset5 :effectAttr :strength; :value 0.386 .
+show:faderset6 :effectAttr :strength; :value 0.287 .
+show:faderset7 :effectAttr :strength; :value 0.173 .