Лайв-кодинг

Лазерные лучи прорезали дым так же глубоко, как сабвуфер прокачивал низами танцующие тела. В атмосфере царила пьянящая смесь синтезаторов и танца. Однако, что-то в этом ночном клубе было не так… Яркими красками над кабиной диджея светился футуристический текст, движущийся, танцующий, вспыхивающий. Но это не были фантастические визуальные эффекты, это была лишь проекция Sonic Pi, запущенного на Raspberry Pi. Обитатель кабины диджея не крутил дисков, он писал, редактировал и запускал код. В реальном времени. Это был лайвкодинг.

Sam Aaron Live Coding

Это может звучать как притянутая за уши история из футуристичного ночного клуба, но кодирование музыки - это развивающийся тренд, часто называемый Лайвкодинг (http://toplap.org). Одним из новых направлений этого способа создания музыки является Алгорэйв (http://algorave.com) - мероприятие, где такие артисты как я, кодируют музыку для танцующих людей. Однако, вам не надо быть в ночном клубе, чтобы кодировать в реальном времени - с Sonic Pi v2.6+ вы можете делать это в любом месте, в которое сможете взять ваш Raspberry Pi и пару наушников или колонок. Как только вы дойдёте до конца этой статьи, вы будете программировать свой собственный бит и изменять его вживую. То, где вы окажетесь после этого, может быть ограничено только вашим воображением.

Живой Цикл

Ключ к лайвкодингу с Sonic Pi - овладение циклами live_loop. Давайте посмотрим на один из них:

live_loop :beats do
  sample :bd_haus
  sleep 0.5
end

Есть 4 основные составляющие циклов live_loop. Первая - это имя. Наш live_loop называется :beats. Вы вольны называть свой live_loop так, как вам угодно. С ума сойти. Подойдите к этому творчески. Обычно я использую имена циклов, что-то говорящие о музыке, которую они делают. Вторая состовляющая - это слово do, которое отмечает, где цикл начинается. Третья состовляющая - слово end, которое отмечает, где цикл заканчивается, и, наконец, есть тело цикла live_loop, которое описывает, что цикл повторяет - это часть кода между do и end. В данном случае мы многократно воспроизводим сэмпл бас бочки и ждём пол тактовой доли. Это производит приятный ровный ритм. Скопируйте этот код в пустой Sonic Pi буфер и нажмите “Выполнить”. Бум, Бум, Бум!.

Изменения На Лету

Итак, что такого особенного в цикле live_loop? Он отдалённо напоминает усовершенствованный цикл loop. Преимущество live_loop в том, что вы можете изменять его на лету. Это значит, что пока выполняется цикл, вы можете изменить то, что он делает. Это и есть секрет лайвкодинга с Sonic Pi. Давайте играть:

live_loop :choral_drone do
  sample :ambi_choir, rate: 0.4
  sleep 1
end

Теперь, нажмите кнопку “Выполнить” или Alt-r. Вы услышите великолепный звук хора. Теперь, пока он ещё играет, измените скорость с 0.4 на 0.38. Нажмите “Выполнить” снова. Ого! Вы слышите, как хор сменил ноту? Измените скорость обратно на 0.4, чтобы вернуться к тому, что было раньше. Теперь, снизьте скорость до 0.2, потом до 0.19, а затем обратно до 0.4. Видите, как изменение на лету одного лишь параметра, даёт вам реальный контроль над музыкой? Теперь поиграйте со скоростью самостоятельно - выберите свои собственные значения. Попробуйте отрицательные числа, попробуйте очень маленькие и очень большие числа. Повеселитесь!

Сон Важен

Один из самых важных аспектов цикла live_loop в том, что в нём должна быть задержка. Рассмотрим следующий код:

live_loop :infinite_impossibilities do
  sample :ambi_choir
end

Если вы попробуете запустить этот код, вы сразу увидите жалобу Sonic Pi на то, что в live_loop нет sleep. Это ругается система безопасности! Воспользуйтесь моментом, чтобы подумать о том, что этот код просит сделать компьютер. Правильно, он просит компьютер играть бесконечное количество хоровых сэмплов за нулевое время. Без системы безопасности бедный компьютер будет пытаться сделать это, что приведёт к аварии. Поэтому помните, ваш live_loop должен содержать sleep.

Сочетание Звуков

Музыка полна вещей, происходящих одновременно. Барабаны звучат в то же самое время, что и бас, вокал, гитары… В информатике это называется параллелизм и Sonic Pi обеспечивает нам удивительно простой способ играть разные вещи в одно и то же время. Просто используйте больше, чем один live_loop!

live_loop :beats do
  sample :bd_tek
  with_fx :echo, phase: 0.125, mix: 0.4 do
    sample  :drum_cymbal_soft, sustain: 0, release: 0.1
    sleep 0.5
  end
end
  
live_loop :bass do
  use_synth :tb303
  synth :tb303, note: :e1, release: 4, cutoff: 120, cutoff_attack: 1
  sleep 4
end

Здесь у нас есть два цикла live_loop, один цикл делает быстрый ритм, а другой - медленный сумасшедший басовый звук.

Одна из особенностей использования нескольких циклов live_loop состоит в том, что каждый из них обладает своим собственным независимым временем. Это значит, что с помощью этого легко создавать интересные полиритмические структуры и даже поиграть с фазировкой в стиле Стива Рейха (Steve Reich). Зацени:

# Steve Reich's Piano Phase
  
notes = (ring :E4, :Fs4, :B4, :Cs5, :D5, :Fs4, :E4, :Cs5, :B4, :Fs4, :D5, :Cs5)
  
live_loop :slow do
  play notes.tick, release: 0.1
  sleep 0.3
end
  
live_loop :faster do
  play notes.tick, release: 0.1
  sleep 0.295
end

Соединим Всё Вместе

Каждую из этих статей мы будем заканчивать примером в виде фрагмента музыкального произведения, который вырисовывается из всех представленных в статье идей. Прочтите этот код и посмотрите, сможете ли вы понять, что он делает. Затем скопируйте его в свежий буфер Sonic Pi, нажмите “Выполнить” и послушайте, как он самом деле звучит. Наконец, измените одно из чисел или закомментируйте/раскомментируйте какие-нибудь строки. Посмотрите, сможете ли вы использовать этот пример в качестве отправной точки для нового выступления, и самое главное, веселитесь! До встречи в следующий раз…

with_fx :reverb, room: 1 do
  live_loop :time do
    synth :prophet, release: 8, note: :e1, cutoff: 90, amp: 3
    sleep 8
  end
end
  
live_loop :machine do
  sample :loop_garzul, rate: 0.5, finish: 0.25
  sample :loop_industrial, beat_stretch: 4, amp: 1
  sleep 4
end
  
live_loop :kik do
  sample :bd_haus, amp: 2
  sleep 0.5
end
  
with_fx :echo do
  live_loop :vortex do
    # use_random_seed 800
    notes = (scale :e3, :minor_pentatonic, num_octaves: 3)
    16.times do
      play notes.choose, release: 0.1, amp: 1.5
      sleep 0.125
    end
  end
end