spatilabs.co · OsciDraw · аудит v310
Кисть как осциллятор
Черновик концепта, не код в OsciDraw. Android Jones в Corel Painter ведёт след как живую материю; Microdose VR разбрасывает партикли в 3D. Здесь то же желание, но кисть — это синтакт: семпл в слоте, транспорт = рука, DSP позже вешается на звук, а не рисует сам.
Что уже есть в 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 вдоль той же нормали, в панораму.
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 |
Рисуй лес
Холст в ширину двух окон сверху. Новые штрихи копятся, партикли летят по нормали ленты и запекаются на месте. Очистка только кнопкой.
Опора: OsciDraw v311, аудит архитектуры, BrushEngine/LFO, coverage MAX. Это лаборатория идеи, пайплайн краски не менялся.
← spatilabs.co · made with love by laditeo.art