view src/light9/midifade/writeback.py @ 2388:3cd80b266561

refactor midiFade a lot; try to catch all midi events even better, even if rdfdb runs slow
author drewp@bigasterisk.com
date Mon, 13 May 2024 21:39:53 -0700
parents
children 485148ef5686
line wrap: on
line source

import asyncio
import logging
from dataclasses import dataclass
from typing import cast

import mido
from light9.midifade.pages import Pages
from light9.namespaces import L9
from rdfdb.syncedgraph.syncedgraph import SyncedGraph
from rdflib import Literal
from debouncer import DebounceOptions, debounce

log = logging.getLogger()


@dataclass
class WriteBackFaders:
    graph: SyncedGraph
    pages: Pages
    bcf_out: mido.ports.BaseOutput
    _lastSet: dict[int, int]

    def getCurrentValue(self, f):
        return self._lastSet.get(f, 0)

    def update(self):
        try:
            asyncio.create_task(self._update())
        except ValueError as e:
            log.warning(repr(e))

    async def _update(self):
        # to make this work again:
        #  - track the goal of all sliders
        #  - in a debounced handler, sendToBcf
        return
        g = self.graph
        nupdated = 0
        m = self.pages.getChansToFaders()
        for midi_ctl_addr, f in m.items():
            fset = g.value(f, L9.setting)
            # could split this to a separate handler per fader
            value = cast(Literal, g.value(fset, L9.value)).toPython()
            hwcurrent = self.getCurrentValue(midi_ctl_addr)
            hwgoal = int(value * 127)
            maxValueDiff = 3
            # todo: 3 is no good; we should correct after a short time of no
            # movement
            if abs(hwcurrent - hwgoal) > maxValueDiff:
                log.info(f'writing back to {f} {hwcurrent=} {hwgoal=}')
                self.sendToBcf(midi_ctl_addr, hwgoal)
                nupdated += 1
        if nupdated > 0:
            log.info(f'wrote to {nupdated} of {len(m)} mapped faders')

    def sendToBcf(self, control: int, value: int):
        self._lastSet[control] = value
        msg = mido.Message('control_change', control=control, value=value)
        self.bcf_out.send(msg)