Раздел
Под капотом
Точные подробности: время и память, устройство звука, приём нот и схема тракта. То, что на страницах разделов сказано просто, здесь сказано точно.
Время и память
- Бюджет реального времени — 2,67 мс на блок; в типичном режиме блок считается за 1,27–1,33 мс, то есть с двойным запасом.
- Кривая мастера-компрессора считается раз в 16 сэмплов с интерполяцией между ними. Расчёт на каждый сэмпл стоил 1,1 мс из 2,67:
log2fиexp2fна этом чипе программные. - Все длинные буферы эффектов лежат в PSRAM: хорус, дилей-пинг-понг на 72000 сэмплов и хвосты реверба.
- Приложение занимает 1 008 560 байт, склеенный образ для прошивки — 1 139 632; в разделе приложения свободно 76%.
- ESP-IDF 6.1, LVGL 9.6.
- Целостность таблиц страниц и раскладок обода проверяется статическими утверждениями в коде и скриптом перед сборкой.
Дрон и его волны
SIN и TRI — генераторы движка. SAW и PLS — таблицы PolyBLEP с антиалиасингом: встроенная пила движка наивная и алиасит заметно, а дрон держат минутами. SPR — те же три пилы с расстройкой, раздвинутой втрое. NOI — шум движка, по независимому потоку на голос, поэтому девять голосов дрона дают плотный шум вместо одного шипа; он тоже идёт через фильтр и огибающую своей части.
Заводская волна — SAW. Смена волны ничего не перезапускает, поэтому выбирать её можно на звучащем дроне.
Модуляция
Приёмников девять: FILTER, PAN, FILT+PAN, четыре связки перкуссии и две для высоты шага лида. Форм семь: пять волн и пара экспоненциальных. Глубина идёт до ста процентов, скорость считается по шагам перкуссии, а перезапуск бывает свободным, по ноте лида и с удержанием на ноте.
Генератор модуляции живёт в приложении: до фазы LFO в движке из приложения не дотянуться. Экспоненциальные формы принадлежат ему же, фильтровый LFO движка знает первые пять и на экспоненте играет RANDOM. Сдвиги относительные: значение ручки плюс сдвиг, а высота шага лида — умножение частоты ноты на интервал в полутонах.
Перкуссия
Пик удара выравнивается по длине дикея, поэтому длинные хвосты держатся ниже потолка. Высоту удара, ENV и DECAY может двигать модуляция со страницы MOD.
Эффекты
Хорус — квадратурный LFO, своя ширина и скорость.
Дилей — пинг-понг, до четырёх секунд на сторону, синхронизация с темпом. Вход суммируется в моно и идёт только в левую линию, левый повтор питает правую, поэтому повторы идут по стерео полю, а не стоят в середине.
Реверб — пять алгоритмов: ROOM, HALL, CATH, HOLD, PLAT. Первые четыре — четыре набора настроек одного Freeverb: длины линий, обратная связь, демпфирование и вход. PLAT — плита Dattorro: другая топология, свой блок в памяти и своя устойчивость, при тринадцати обращениях к линиям против двадцати четырёх у Freeverb.
MIX у реверба работает как баланс. Сухой сигнал идёт раз (1 − mix), влажный раз mix, поэтому на половине они равны, а на ста процентах остаётся только реверб. Микс применяется в одном месте, на выходе рэка, а оба движка отдают чистый влажный сигнал. Хорус и дилей попадают в реверб: на полном миксе реверб и есть выход, поэтому повторы дилея и ширину хоруса слышно только через него.
Мастер-компрессор
Одна ручка ведёт порог и степень вместе. Атака и релиз фиксированы — 25 и 250 мс, мягкое колено 6 дБ, сайдчейн-фильтр 150 Гц. Внизу ручки компрессор выключен, и выходной каскад остаётся прежним.
Приём нот по USB
Включение на ходу делает USB-разъём на компьютере MIDI-устройством — появляется порт «OBOD MIDI IN», а отладочный порт (COM) с компьютера пропадает, и перезагрузка для этого не нужна. Выключение на ходу убирает MIDI-устройство, снимает драйвер и освобождает USB-контроллер, но отладочный порт на ходу не возвращает: он снова на месте только после перезагрузки прибора с выключенным приёмом нот. Прошивка без кнопок идёт так: выключить приём нот, передёрнуть USB — после загрузки порт на месте, и esptool входит в загрузчик сам.
Приём нот приносит и транспорт с часами: 0xFA — старт, 0xFB — продолжение, 0xFC — стоп, 0xF8 — часы, двадцать четыре тика на четверть, остальные байты отбрасываются. Транспорт открывает и закрывает входной гейт, на старте ставит секвенсоры в начало фразы, на стопе не даёт им открывать ноты; арпеджиатор по удержанным MIDI-клавишам звучит и на стопе. Часы задают темп двум евклидовым секвенсорам, арпеджиатору и генератору модуляции: темп оценивается по окну в один бит со сглаживанием, ограничен 30..300 BPM, подменяет значение ручки, в параметр патча не пишется и примерно через секунду без тиков возвращается к ручке. Новых настроек и параметров патча у этого нет.
Память и хранилище
Хранилище больше не очищается по отпечатку образа. Версия формата хранится отдельной записью; слот, записанный несовместимым форматом, не читается и остаётся на месте — прибор пишет об этом в журнал, а не стирает его.
Область NVS, где лежат настройки и пресеты, закрывается склеенным образом при браузерной прошивке: галочка стирания в диалоге на это не влияет — область настроек закрывается образом и без неё.
Схема тракта
Схема не отрисовалась: библиотека mermaid.min.js не загрузилась или текст схемы не разобран. Текст схемы лежит ниже, в блоке с исходником.
%% OBOD — сигнальный тракт и триггеры. Канонический вид схемы — этот файл; страница
%% obod-signal-chain.html собирается из него командой python docs/signal-chain/gen_html.py.
%% Сплошная стрелка — сигнал; пунктирная — управление и модуляция.
%% SEND BUS и VERB SEND — один буфер s_send_bus (synth_rack.cpp:154, 231, 541-546, 570, 613, 625-628); GATE стоит между ними.
%% Макросы UI звук не запускают: они только пишут параметры (synth_ui.c:6181-6186).
%% Темп от часов подменяет ручку в seq_tempo_now() и в параметр патча не пишется (synth_app.cpp:3337-3343, 3357-3370).
flowchart LR
subgraph SRC["Источники"]
LOW["LOW"]
MID["MID"]
HIGH["HIGH"]
LEAD["LEAD"]
PERC["PERC"]
MIC["MIC"]
end
subgraph PRE["Пре-процессинг"]
DRONE_FLTR["DRONE FLTR"]
LEAD_TONE["LEAD TONE"]
MIC_IN["MIC IN"]
PAN_CAPTURE["PAN CAPTURE"]
end
subgraph CTL["Управление и триггеры"]
UI_TRANSPORT["UI · ТРАНСПОРТ"]
TRANSPORT["ТРАНСПОРТ"]
TEMPO["ТЕМП"]
MIDI_IN["MIDI IN"]
MIDI_TRANSPORT["MIDI TRANSPORT"]
MIDI_CLOCK["MIDI CLOCK"]
EUCLID_LEAD["EUCLID LEAD"]
SEQ_TRIGGER["SEQ TRIGGER"]
ARP["АРПЕДЖИАТОР"]
PERC_SEQ["ПЕРК-СЕКВЕНСОР"]
DRONE_TUNE["DRONE TUNE"]
SCALE["КВАНТОВАНИЕ ПО ЛАДУ"]
MOD_LFO["MOD LFO"]
UI_IND["UI · ИНДИКАЦИЯ"]
end
subgraph MIXG["Микширование и Шины"]
SUM["SUM"]
SEND_BUS["SEND BUS"]
GATE["GATE"]
end
subgraph FX["Эффекты"]
CHORUS["CHORUS"]
DELAY["DELAY"]
end
subgraph RVB["Реверберация"]
VERB_SEND["VERB SEND"]
VERB["VERB"]
VERB_MIX["VERB MIX"]
end
subgraph MST["Мастер-цепочка"]
COMP["COMP"]
VOL["VOL"]
SOFT_CLIP["SOFT CLIP"]
PCM5100A["PCM5100A"]
end
%% сигнал: источники в пре-процессинг
LOW --> DRONE_FLTR
MID --> DRONE_FLTR
HIGH --> DRONE_FLTR
LEAD --> LEAD_TONE
MIC --> MIC_IN
%% пре-процессинг: панорама и уровни
DRONE_FLTR --> PAN_CAPTURE
LEAD_TONE --> PAN_CAPTURE
%% микширование: сухая сумма и шина отправок
PAN_CAPTURE --> SUM
PAN_CAPTURE -->|"pre-fader"| SEND_BUS
PERC -->|"post-fader"| SUM
PERC -->|"post-fader"| SEND_BUS
MIC_IN -->|"AUX level 0"| SEND_BUS
%% гейт входа, затем эффекты и посылка
SUM --> GATE
SEND_BUS --> GATE
GATE --> CHORUS
GATE -->|"посылка"| VERB_SEND
CHORUS --> DELAY
CHORUS -->|"wet"| VERB_SEND
DELAY -->|"wet"| VERB_SEND
%% реверберация: посылка/возврат и баланс
VERB_SEND -->|"ALGO: ROOM · HALL · CATHEDRAL · PLATE · HOLD"| VERB
VERB -->|"wet"| VERB_MIX
DELAY -->|"сухой"| VERB_MIX
%% мастер-цепочка
VERB_MIX --> COMP
COMP --> VOL
VOL --> SOFT_CLIP
SOFT_CLIP -->|"INT16 · I2S"| PCM5100A
%% управление: транспорт
UI_TRANSPORT -.->|"пуск/стоп"| TRANSPORT
UI_TRANSPORT -.->|"темп вручную"| TEMPO
TRANSPORT -.->|"гейт входа"| GATE
TRANSPORT -.->|"стоп: нот нет"| EUCLID_LEAD
TRANSPORT -.->|"стоп: нот нет"| ARP
TRANSPORT -.->|"стоп: удара нет"| PERC_SEQ
TRANSPORT -.->|"индикация"| UI_IND
%% управление: MIDI по каналам
MIDI_IN -.->|"канал 1: нота"| LEAD
MIDI_IN -.->|"канал 1: аккорд"| ARP
MIDI_IN -.->|"канал 2: удар"| PERC
MIDI_IN -.->|"удержание/хвост"| GATE
MIDI_IN -.->|"самая новая нота"| DRONE_TUNE
%% управление: транспорт и часы с провода
MIDI_IN -.->|"0xFA/0xFB/0xFC"| MIDI_TRANSPORT
MIDI_IN -.->|"0xF8: 24 тика на четверть"| MIDI_CLOCK
MIDI_TRANSPORT -.->|"пуск/продолжение: открыт · стоп: закрыт"| GATE
MIDI_TRANSPORT -.->|"пуск: с начала фразы · стоп: нот нет"| EUCLID_LEAD & PERC_SEQ
MIDI_TRANSPORT -.->|"стоп: своя фигура молчит · удержанные клавиши звучат"| ARP
MIDI_CLOCK -.->|"темп подменяет ручку · в параметр патча не пишется"| EUCLID_LEAD & PERC_SEQ & ARP & MOD_LFO
MIDI_CLOCK -.->|"арка и подпись BPM: фактический темп"| UI_TRANSPORT
%% управление: генераторы и их ноты
TEMPO -.-> EUCLID_LEAD & PERC_SEQ & ARP & DELAY & MOD_LFO
EUCLID_LEAD -.->|"шаги (onset)"| SEQ_TRIGGER
SEQ_TRIGGER -.->|"нота"| LEAD
ARP -.->|"своя группа голосов"| LEAD
PERC_SEQ -.->|"удар"| PERC
%% управление: лад, настройка дрона, модуляция
SCALE -.->|"лад"| LEAD
SCALE -.->|"лад"| ARP
SCALE -.->|"лад"| DRONE_TUNE
DRONE_TUNE -.->|"транспонирование"| LOW & MID & HIGH
LEAD -.->|"перезапуск по ноте"| MOD_LFO
MOD_LFO -.->|"срез"| DRONE_FLTR
MOD_LFO -.->|"дрейф"| PAN_CAPTURE
MOD_LFO -.->|"PITCH/ENV/DECAY"| PERC
MOD_LFO -.->|"высота"| LEAD
MIC_IN -.->|"огибающая: срез"| DRONE_FLTR
MIC_IN -.->|"огибающая: дрейф"| PAN_CAPTURE
%% управление: индикация трёх ритмических плиток
EUCLID_LEAD -.->|"шаги"| UI_IND
PERC_SEQ -.->|"шаги"| UI_IND
ARP -.->|"шаги"| UI_IND
classDef cSrc fill:#0a1030,stroke:#1976D2,color:#90CAF9
classDef cPre fill:#07130a,stroke:#2E7D32,color:#A5D6A7
classDef cCtl fill:#1a1300,stroke:#FFB300,color:#FFE082
classDef cMix fill:#160f0c,stroke:#8D6E63,color:#D7CCC8
classDef cFx fill:#1a0410,stroke:#E91E63,color:#F48FB1
classDef cVerb fill:#120a22,stroke:#7E57C2,color:#B39DDB
classDef cMaster fill:#04211a,stroke:#30DA98,color:#A7F3D0
class LOW,MID,HIGH,LEAD,PERC,MIC cSrc
class DRONE_FLTR,LEAD_TONE,MIC_IN,PAN_CAPTURE cPre
class UI_TRANSPORT,TRANSPORT,TEMPO,MIDI_IN,MIDI_TRANSPORT,MIDI_CLOCK,EUCLID_LEAD,SEQ_TRIGGER,ARP,PERC_SEQ,DRONE_TUNE,SCALE,MOD_LFO,UI_IND cCtl
class SUM,SEND_BUS,GATE cMix
class CHORUS,DELAY cFx
class VERB_SEND,VERB,VERB_MIX cVerb
class COMP,VOL,SOFT_CLIP,PCM5100A cMaster
Схема показывает путь сигнала от источников до выхода: дрон, лид, перкуссия и микрофон идут через фильтры и микшеры в эффекты, дальше в реверб и мастер-цепочку до ЦАП. Сплошная стрелка — сигнал, пунктирная — управление и модуляция. Схему можно приблизить колесом мыши и сдвинуть перетаскиванием, двойной щелчок возвращает исходный вид. Тот же рисунок есть отдельной страницей.