From 2568249c9b95d91ac64216f0c11e855499adb798 Mon Sep 17 00:00:00 2001 From: lambda Date: Tue, 15 Sep 2026 13:50:28 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B8=20=D0=BF=D0=BB=D0=B0=D0=BD=20=D1=84=D1=83=D0=BD?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keyboard-controller/plan.org | 141 ++++++++++++++++++++++++++++++ keyboard-controller/questions.org | 66 ++++++++++++++ keyboard-controller/readme.org | 23 +++++ 3 files changed, 230 insertions(+) create mode 100644 keyboard-controller/plan.org create mode 100644 keyboard-controller/questions.org create mode 100644 keyboard-controller/readme.org diff --git a/keyboard-controller/plan.org b/keyboard-controller/plan.org new file mode 100644 index 0000000..99acb94 --- /dev/null +++ b/keyboard-controller/plan.org @@ -0,0 +1,141 @@ +#+TITLE: Keyboard Controller — план реализации + +План для приложения из readme.org: HID-контроллер (клавиатура, мышь, +тачпад) поверх SuperCollider, управление Ndef/Tdef, минимальный +визуальный фидбек. Целевая платформа — Linux, ноутбуки ThinkPad. + +* Решения (зафиксированы из questions.org) + +- Приоритет устройств: клавиатура + тачпад. TrackPoint не приоритет. +- Кнопки мыши/тачпада: минимум две, по возможности захватить максимум. +- Оси тачпада: для начала абсолютные. +- Скетч самодостаточный — демо-Ndef внутри, не тянет готовые + NodeDictionary-инструменты. +- Отдельный инструмент, но будет применён в перформансе + (24_09_2026_gig). +- Минимальный набор действий достаточен: toggle / inc / dec / + play/stop / free. +- «Держать-пока-нажата» (gate) — требование, KeyUp обязателен. +- Фидбек: GUI-окно с текстовым содержимым (не пост-окно). +- Форма: несколько файлов с одной точкой входа. + +* Принцип + +Не «демо», а рабочий шаблон-каркас: одна точка входа, декларативная +привязка HID-событий к действиям, слои разделены. Основа — HIDdef +(аналог MIDIdef) плюс словари привязок. Всё состояние — в глобалах +~ (прокси-пространстве), чтобы быстро править из REPL. + +* Этапы + +** 1. Доступ к HID-устройствам из-под Linux +Основная и часто незаметная проблема: sclang без привилегий не видит +/dev/hidraw*. Нужно решить ДО кода: +- проверить, что устройства видны: ~HID.findAvailable~ и + ~HID.postAvailable~ из REPL; +- если пусто — udev-правило, разрешающее чтение hidraw для нужной + группы (или запуск от рута для прототипа); +- зафиксировать точные ID устройств (vendor/product) ThinkPad, чтобы + не открывать «всё подряд». + +** 2. Слой открытия устройств +- Сканирование ~HID.findAvailable~; +- выбор целевого устройства по vendor/product, а не по индексу; +- ~HID.open(id)~ → держим объект устройства в ~~device~; +- graceful-fallback: если устройства нет, скетч не падает, а печатает + предупреждение и ждёт. + +** 3. Слой привязок (словарь обработчиков) +Декларативная таблица: ключ → действие. Значение — либо event-словарь +(структурированное действие над Ndef/Tdef), либо напрямую функция +(произвольный обработчик). Примерная форма: + +#+begin_src sclang +~bindings = IdentityDictionary[ + // клавиша -> Ndef-цель + параметр (event-словарь) + \q -> (type: \toggle, ndef: \d, param: \gate), + \w -> (type: \inc, ndef: \d, param: \freq, step: 10), + \e -> (type: \dec, ndef: \d, param: \freq, step: 10), + \r -> (type: \playTdef, tdef: \loop), + // клавиша -> произвольная функция (просто выполняется) + \space -> { "space hit".postln; ~something.value }, +]; +#+end_src + +Разделяем сами обработчики (механику) и карту привязок (настройку), +чтобы менять раскладку не трогая логику. Диспетчер действия различает +значение по типу: `isFunction` → вызвать напрямую; иначе — разобрать +по `type` (event-словарь). Это даёт «сырой» побег: можно вешать на +клавишу любую функцию без добавления нового типа действия. + +** 4. HIDdef: KeyDown / KeyUp +- клавиатура: value == 1 (нажатие) / value == 0 (отпускание); +- поддержка обеих фаз — это требование из readme (KeyUp нужен, + например, для gate=0 у нот / для «держать-пока-нажата»); +- HIDdef c фильтром по usagePage/usage клавиатуры. + +** 5. Мышь / тачпад +- кнопки мыши/тачпада — как клавиши (нажатие/отпускание); +- движение тачпада: оси X/Y (Generic Desktop usage 0x30/0x31), + маппинг на параметры (например, pan, freq, амплитуда); +- прочие события тачпада (wheel, multitouch) — опционально, по + наличию в device.elements конкретного устройства. + +** 6. Действия над Ndef/Tdef (плюс «сырые» функции) +Типы действий из карты привязок (event-словари): +- toggle параметра (gate, bypass); +- inc/dec значения параметра с шагом и clamp по ControlSpec; +- play/stop Tdef; +- free Ndef; +- переключение пресетов. +Используем ~Ndef().set(...)~ и ~Tdef().play/stop~. + +Помимо структурированных действий, значение привязки может быть +произвольной Function — диспетчер её просто вызывает (`~action.value`). +Это «побег» для любых обработчиков, не влезающих в типы выше: запуск +отдельных функций, посыл OSC, манипуляции с ~env, что угодно. Разбор +в диспетчере: `if (action.isFunction) { action.value } { ~dispatch[action.type].(action) }`. + +** 7. Минимальный визуальный фидбек +GUI-окно с текстовым содержимым (Window + StaticText): одна строка = +один активный Ndef/Tdef и его текущие параметры; подсветка изменённого +параметра. Без полноценных слайдеров — только текстовый фидбек +состояния. + +** 8. Структура файлов (внутри keyboard-controller/) +#+begin_src text +readme.org — описание (уже есть) +plan.org — этот план +controller.scd — точка входа, скелет скетча +bindings.scd — карта привязок (словарь) +actions.scd — реализация действий (toggle/inc/dec/...) +#+end_src + +Либо всё в одном .scd на старте — разделить позже, когда вырастет. + +* Порядок работ +1. Поднять доступ к HID (udev), подтвердить видимость устройств. +2. Минимальный скетч: открыть устройство, повесить один HIDdef на + одну клавишу, печатать нажатия. +3. Добавить карту привязок + действия toggle/inc/dec. +4. Подключить Ndef (например, из NodeDictionary) как управляемую цель. +5. Добавить KeyUp-семантику (gate / держать-пока-нажата). +6. Добавить оси тачпада и кнопки мыши. +7. Визуальный фидбек. +8. Отполировать fallback-пути (устройство отвалилось, нет HID). + +* Риски / на что смотреть +- TrackPoint на ThinkPad часто НЕ HID-тачпад, а PS/2-мышь через evdev — + его HID-слой может не видеть. По решениям — не приоритет, можно + не покрывать. +- Имена классов: в SC это HIDdef / HIDFunc (строчная d), HIDDeviceService, + GeneralHID. В readme написано «HIDDef» — сверять с документацией + конкретной версии SC 3.14. +- usagePage/usage клавиш могут отличаться от ожидаемых — печатать + сырые event-поля при отладке (page, usage, value) прежде чем + зашивать их в привязки. +- Несколько одинаковых устройств (внешняя клавиатура + встроенная) — + отличать по vendor/product/id, не по индексу списка. +- Абсолютные оси тачпада на разных устройствах дают разные диапазоны — + нормировать (делить на логический максимум) прежде чем маппить на + ControlSpec параметра. diff --git a/keyboard-controller/questions.org b/keyboard-controller/questions.org new file mode 100644 index 0000000..8438432 --- /dev/null +++ b/keyboard-controller/questions.org @@ -0,0 +1,66 @@ +#+TITLE: Keyboard Controller — вопросы + +Вопросы, на которые не ответить чтением репозитория. Ответы помогут +зафиксировать план точнее. Нумерую для удобства ответа. + +* Устройство и события + +1. Какое устройство — приоритет? Тачпад (HID), клавиатура (HID) или + TrackPoint? На ThinkPad TrackPoint обычно PS/2-мышь через evdev и + НЕ виден в HID-слое — если он важен, нужен отдельный обходной + путь (не HIDdef). Тачпад и клавиатура в HID есть. + +В приоритете клавиатура + тачпад, так как это софт скорее для +живых выступлений. + +2. Кнопки мыши/тачпада — нужны все (left/right/middle) или хватит + одной-двух под конкретные действия? + +Хватит двух. Если возможно, конечно, стоит захватить максимум. + +3. Оси тачпада: абсолютные координаты (как pad) или относительное + смещение (как трекпад-жесты)? От этого зависит маппинг на + параметры (pan по X, что по Y?). + +Для начала абсолютные. + +* Цели управления (Ndef/Tdef) + +4. Какие конкретно Ndef/Tdef должны управляться? Это готовые + NodeDictionary-инструменты из bmSClib (какие .scd?), или скетч + должен быть самодостаточным с парой демо-Ndef внутри? + +Скетч должен быть самодостаточным + +5. Есть ли связь с 24_09_2026_gig (печатная машинка + live-electronics), + или это отдельный инструмент? Влияет на набор действий + (например, нужен ли freeze/hold, пресеты, «держать-пока-нажата»). + +Это отдельный инмтрумент, но будет применён в этом перформансе + +* Набор действий + +6. Минимальный достаточный набор действий для первого работающего + скетча: toggle, inc/dec, play/stop, free — хватит? Или сразу + нужны пресеты/переключение сцен? + +Хватит + +7. «Держать-пока-нажата» (gate) — это требование (KeyUp важен для нот) + или KeyUp достаточно для анти-дребезга/фиксации состояния? + +Требование + +* Фидбек и форма + +8. Фидбек: пост-окно (просто), текстовое окно со строками по + Ndef/Tdef, или GUI со слайдерами сразу? Readme говорит «минимальный + визуальный фидбек» — уточнить, где нижняя граница. + +Это может быть gui окно с текстовым фидбеком + +9. Форма результата: отдельный .scd-скелет (несколько файлов) или + один самодостаточный .scd? Или встроить как класс/расширение в + bmSClib (рядом с NodeDictionary)? + +Несколько файлов с одной точкой входа diff --git a/keyboard-controller/readme.org b/keyboard-controller/readme.org new file mode 100644 index 0000000..3217fd1 --- /dev/null +++ b/keyboard-controller/readme.org @@ -0,0 +1,23 @@ +Приложение для управления SuperCollider скетчами +с использованием HID (клавиатура, мышь, тачпад) + +Минимальная версия SC 3.14.0 +Целевая платформа Linux + +Это может быть простой шаблон на sclang, +основаный на HIDDef и Dictionaries +для навешивания обработчиков на события +HID устройств. + +Оcновная задача - иметь возможность быстро +управлять NDef и Tdef и видеть минимальный +визуальный фидбек состояния. + +Нужна поддержка событий KeyUp и KeyDown для +клавиатур и кнопок мыши/тачпада, а также +движение тачпада по осям. + +Если тачпад поддерживает другие события, их тоже +можно поддержать. + +Основные рабочие машины - ноутбуки ThinkPad.