Создание звукового движка с нуля — это обряд посвящения. Вы хотите понять тактовый генератор. Тайминг. Сырую логику, которая превращает тишину в ритм. Секвенсор — это и есть эта логика. Это сетка. Вы размещаете ноты. Вы продвигаетесь вперед.
Большинство руководств пропускают сложную часть. Они показывают вам библиотеку. Они показывают вам графический интерфейс. Они не показывают, как обрабатывать дрейф. Ошибки тайминга, которые накапливаются, когда вы вручную отслеживаете время.
Давайте исправим это.
Мы создаем базовый пошаговый секвенсор. Он будет работать в простом цикле. Он будет запускать звуки. Он будет держать ритм, не заглядывая вперед. Этот подход предотвращает «дерганое» ощущение, которое возникает при использовании setTimeout для длинных циклов.
Основная концепция: Пошаговый тайминг
Секвенсор работает на шагах. Не на секундах. На шагах.
Если ваш темп составляет 120 ударов в минуту (BPM), каждая доля длится 0,5 секунды. Если у вас 16 шагов, каждый шаг длится 0,125 секунды. Магия происходит, когда вы синхронизируетесь с этими интервалами.
«Время в секвенсоре не является непрерывным потоком. Это серия дискретных событий. Синхронизация с этими событиями — это всё».
Нам нужен способ вычислять, когда происходит каждый шаг. Не путем угадывания. Путем математики.
Настройка тактового генератора
Вам нужна точка отсчета. Время начала.
В JavaScript Date.now() или performance.now() возвращают миллисекунды. Вы используете это для расчета дрейфа.
- Определите темп.
- Рассчитайте длительность шага.
- Запустите цикл.
Вот скелет кода. Он не очень красивый. Но он работает.
Этот код базовый. Он использует setTimeout. Он не идеален. Но это начало.
Почему это важно
Зачем создавать его самостоятельно?
Библиотеки, такие как Tone.js или обертки для Web Audio API, великолепны. Они обрабатывают сложное планирование. Они компенсируют задержки.
Но вы не узнаете, как они работают, просто используя их. Вы учитесь, видя, где они дают сбой.
Когда setTimeout дрейфует, ваш бит колеблется. Это звучит по-человечески. Это звучит неправильно.
Обработка дрейфа
Проверка if (nextStepTime < Date.now()) имеет критическое значение.
Она























