Лайв-кодинг

Лазерные лучи пронзают клубы дыма, одновременно с тем, как сабвуфер проталкивает бас глубоко в толпу людей. Атмосфера наполнена пьянящей смесью синтезаторов и танцев. Однако что-то не совсем привычное происходит в этом ночном клубе. Над диджейской будкой, двигаясь, танцуя, и перемигиваясь в ярких цветах, проецируется футуристический текст. Но это не какие-то причудливые визуальные эффекты, — это проекция 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