spatilabs.co · OsciDraw · аудит v310

Кисть как осциллятор

Черновик концепта, не код в OsciDraw. Android Jones в Corel Painter ведёт след как живую материю; Microdose VR разбрасывает партикли в 3D. Здесь то же желание, но кисть — это синтакт: семпл в слоте, транспорт = рука, DSP позже вешается на звук, а не рисует сам.

MAX coverage уже не темнеет на перекрытии
LFO BrushEngine уже тикает как синтакт
v_pen гранула наследует скорость пера

Что уже есть в OsciDraw

BrushPreset с самого первого чата задуман как осциллятор: size, opacity, hardness, flow + LFO + MIDI/OSC. Живой штрих идёт в coverage MAX. particle_*.wgsl уже хранят position, velocity, life и drag. Сейчас эмиттер кидает изотропный rand — отсюда мёртвые «ножки». Нужно наследовать вектор пера и stereo-нормаль.


Мини-игры формы

Семпл-кит: kick = треугольник, hat = плюс, snare = хлопок. Гранулы — мелкие копии той же формы. Штампы по восьмым.

Слот семплера

Вид

Свободный след

Резкий жест — выстрел вперёд и в стороны. Когда гранула останавливается, она печётся в холст.

Вертикальная лента

Y = время в семпле, ширина = амплитуда. Жест только скраббит playhead; гранулы вылетают с берегов волны и пекутся туда же.

Как это сделать по-настоящему

Да, и это как раз обычная частичная система, не магия. Перо каждый кадр даёт v_pen. Семплер/гранулятор на аудио-треде читает playback_rate = f(|v_pen|), а VST/AU крутятся на фиксированных 48 kHz от уже сгенерированного потока. Delay / Valhalla не «рисуют» — они порождают дополнительные зёрна с запозданием: те же v_pen, но decaying и с большим разлётом по нормали (mid/side диффузия).

GPU уже почти готов: Particle в шейдере имеет velocity, compute считает drag/gravity/life. Сейчас emit_at_stamp берёт случайный угол — поэтому пыль не чувствует жест. Наследовать 0.3..0.8 * v_pen, добавить ±normal * wet, рисовать инстансы вдоль своего вектора. Когда скорость падает ниже порога — MAX-stamp в слой: это bake следа, не bake звука.

Следующий реальный шаг в коде

Включить oscidraw-effects в live overlay: эмит от cursor_delta / dt, а не rand. Kick оставить редким clamped-треугольником на транзиенте. Звук — клик/WAV с rate от скорости пера, без VST. Плагины потом, как отдельные эмиттеры поверх того же grain scheduler.


След из одного wet-буфера

Свой DSP можно разметить зёрнами изнутри. Valhalla Shimmer и любой VST отдают только сэмплы. Гипотеза: не парсить плагин, а читать картинку спектра как поле частиц. Низ и плотное тело липнут к позвоночнику штриха (нормаль ≈ 0). Контрастные крошки верхнего спектра — отдельные entity со своим velocity вдоль той же нормали, в панораму.

0 блобов после CCL
0 тело, прилипает к spine
0 искры, летят по нормали
Wet
Contrast

STFT mag, log-freq вверх

Кликни по полю: вертикаль = частота, горизонталь = время хвоста. Источник: синтетический shimmer-буфер, не запись плагина.

STFT на ленте кисти

Та же сетка, что слева: время вдоль штриха, частота по нормали (низ у позвоночника, верх дальше). Playhead режет хвост.

Конвейер, который я бы ставил

шаг вход выход поток
VST process dry grains @ 48 kHz wet ring buffer audio
STFT / log-mel wet window 512–1024 mag[t, f] viz / compute
contrast percentile + unsharp графичный спектр viz
binarize порог / Otsu / hysteresis маска viz
CCL / peaks маска, min area 2–4 blob {mu, mass, f} viz
track ближайший centroid v в (t,f) → canvas viz
map arc-length + normal GPU Particle spawn render

Низкий спектр не обязан быть блобами. RMS / спектральный центроид бинов ниже ~300 Hz задаёт ширину ленты по нормали — плотный звук прилипает к центру. Верх — только entity. Velocity искры: v = a·v_pen + b·n̂·(f − f_split) + c·v_track, где v_track — сдвиг блоба между кадрами STFT (хвост shimmer ползёт вверх по частоте — частицы улетают дальше от кисти).

Дешёвый вариант без полного CCL: local-max peak picking на мел-сетке 64×24. Для Valhalla этого хватит — искры и так точечные. Дорогой: connected components + Hungarian tracking, если захочется стабильные червячки хвоста. FFT лучше не в audio callback: viz thread или compute-shader STFT в wgpu, spawn на CPU с 32×16 как в этой игрушке.

Свой DSP внутри аппы может метить зёрна id до реверба. Wet-only путь этого не знает — форму child берём из бина: низ = kick, середина = snare, верх = hat. Это эвристика, не правда о плагине, но читается.


Лес как спектрограмма

Тот же wet→картинка→entity пайплайн, но поле — звуковая сцена. Низкие слои (бас, гул) тяжёлые и почти на оси кисти. Вода уже ближе к партиклям, чем к позвоночнику. Птицы — отдельные сущности. Стрекот — летучий песок, самый дальний и лёгкий.

бас гул вода птицы кузнечики

Полосы леса, freq вверх

Кликни или тяни playhead. Цвет клетки — доминантная полоса, не радуга ради радуги: каждая полоса = слой сцены. Источник: синтетический лесной буфер.

Слои на нормали кисти

Красный и оранжевый жмутся к ленте. Голубая вода уже облако. Синие птицы — отдельные плюсы далеко. Фиолетовый стрекот — мелкий песок на краю панорамы.

слой цвет частоты к оси форма
бас red ~20–80 Hz прилипает крупный kick
гул orange ~80–250 Hz ещё на ленте хлопок / тело
вода cyan ~0.4–2 kHz уже облако мелкий hat
птицы blue ~2–6 kHz отдельные entity редкий плюс
кузнечики purple ~6–12 kHz песок на краю пыль 1–2 px

Рисуй лес

Холст в ширину двух окон сверху. Новые штрихи копятся, партикли летят по нормали ленты и запекаются на месте. Очистка только кнопкой.

0 штрихов · 0 запечённых

Опора: OsciDraw v311, аудит архитектуры, BrushEngine/LFO, coverage MAX. Это лаборатория идеи, пайплайн краски не менялся.

← spatilabs.co · made with love by laditeo.art