Крошечный генератор мелодий на JS — как он устроен

Рассказываем об инструменте ZzFXM, который пригодится разработчикам инди-игр или веб-приложений, вынужденных оперировать сильно ограниченным объемом памяти.

Также поговорим об аналогах — rFXGen, wafxr.

5c7kcskrsax_jwi7x4dkohgvoy0.jpeg
Фото chuttersnap / Unsplash

Подробнее о проекте


ZzFXM представил программист и автор блога о разработке игр Killed By a Pixel — Фрэнк Форс (Frank Force). В своих материалах он уделяет особое внимание вопросам экономии памяти. Однажды он написал симулятор пианино на JavaScript, занимающий всего один килобайт.

Генератор мелодий продолжает эту идею — Фрэнк разработал его специально, чтобы генерировать музыку для ультра-маленьких программ. Такие проекты реализуют в рамках открытых соревнований js13k Games, участники которых пишут игры на HTML5 и JavaScript, используя десятки Кбайт памяти.

ZzFXM можно применять в разработке полноценных инди-игр. Она распространяется по лицензии MIT, поэтому походит для коммерческих проектов.


Исходники и инструкция по настройке лежат в репозитории на GitHub.

Что под «капотом»


Утилита использует движок ZzFX для написания звуковых эффектов, напоминающих восьмибитные. Она позволяет контролировать девятнадцать параметров звучания: от громкости до частоты и формы волны. Примеры звуков, которые способна сгенерировать ZzFX, можно найти на сайте Фрэнка Форса. ZzFXM использует некоторые из них в качестве семплов.

Формат готовых файлов напоминает MOD, применявшийся для хранения и воспроизведения музыкальных композиций на персональном компьютере Amiga, поэтому все семплы со звучанием инструментов хранятся в разных файлах (принцип модульности).

Как это работает


Композитор составляет последовательность из нот с указанием того, какой инструмент и когда должен её сыграть. Эта последовательность называется треком. Несколько параллельно звучащих треков образуют блок (паттерн) со своим номером. Далее, композитор в программном коде указывает, какой паттерн и когда должен прозвучать.

Такой подход позволяет достаточно быстро сформировать желаемую композицию, однако итоговый код достаточно сложно читать без комментариев. В репозитории на GitHub автор генератора приводит следующий пример:

[                                     // Song
  [                                     // Instruments
    [.9, 0, 143, , , .35, 3],             // Instrument 0
    [1, 0, 216, , , .45, 1, 4, , ,50],    // Instrument 1
    [.75, 0, 196, , .08, .18, 3]          // Instrument 2
  ],
  [                                     // Patterns
    [                                     // Pattern 0
      [                                     // Channel 0
        0,                                    // Using instrument 0
        -1,                                   // From the left speaker
        1,                                    // play C-1
        0, 0, 0,                              // rest (x3)
        3.5,                                  // play E-1 with 50% attenuation
        0, 0, 0                               // rest (x3)
      ],
      [                                     // Channel 1
        1,                                    // Using instrument 1
        1,                                    // From the right speaker
        2,                                    // play D-1
        2.25,                                 // play D-1 with 25% attenuation
        3.5,                                  // Play E-1 with 50% attenuation
        4.75,                                 // Play F-1 with 75% attenuation
        -1,                                   // Release the note
        0, 0, 0                               // rest (x3)
      ]
    ]
  ],
  [                                     // Sequence
    0,                                    // Play pattern 0
    0,                                    // ...and again
  ],
  120,                                  // 120 BPM
  {                                     // Metadata
    title: "My Song",                      // Name of the song
    author: "Keith Clark"                  // Name of the author/composer
  }
]


Послушать, как звучат треки, сгенерированные при помощи утилиты, можно на GitHub. Размер композиций не превышает 550 байт.

Какие есть аналоги


Одним из аналогов ZzFXM является rFXGen. Он написан на Си и основан на проекте sfxr — в 2007 году его представил один из участников соревнования LD48. В его рамках каждый разработчик должен за 48 часов представить небольшую игру. Утилита rFXGen поддерживает работу с осцилляторами, вибрато и фильтрами низких и высоких частот.

z7lxmqlg5uv1hajd2ljnj_ezmhc.jpeg
Фото Ohmydearlife / Pixabay

Еще один компактный звукогенератор — wafxr. Он формирует аудио в прямом эфире с помощью WebAudio API и библиотеки wasgen. Wafxr также поддерживает осцилляторы, тремоло/вибрато и различные фильтры. Демо работы есть на GitHub — там вы можете самостоятельно оценить инструмент.


Чтение по теме из «Мира Hi-Fi»:

1osf72wkwrjhzpl2bwl5hcmwnbq.pngЧто такое музыкальное программирование — кто и почему им занимается
1osf72wkwrjhzpl2bwl5hcmwnbq.pngВзять и влиться в музыкальное программирование — языки, которые помогут это сделать
1osf72wkwrjhzpl2bwl5hcmwnbq.pngКак воспроизвести реалистичный звук в компьютерных играх и VR и почему это сложно
1osf72wkwrjhzpl2bwl5hcmwnbq.pngКак устроен Sporth — ЯП для музыкальных live-сессий
1osf72wkwrjhzpl2bwl5hcmwnbq.pngЗанимательная музыка: Число 5 и немного о том, как «видят» музыку юзабилист и программист

© Habrahabr.ru