Итерации и циклы

До этого момента мы потратили немало времени, пробуя разные звуки, которые можно производить внутри блоков play и sample. Мы также изучили как разносить эти звуки во времени, используя sleep.

Как мы уже смогли выяснить, даже с этими простейшими блоками кода можно долго забавляться. Однако, совершенно новое измерение веселья откроется для вас, когда вы начнёте использовать мощь блоков кода для структурирования вашей музыки. В нескольких последующих главах мы рассмотрим некоторые из этих новых инструментов. Вначале идут итерации и циклы.

Повторение

Доводилось ли вам писать код, который вы бы хотели повторить несколько раз? Например, у вас могло получиться нечто подобное:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

Что, если мы захотим повторить это три раза? Что ж, можно было бы выбрать простейший путь и попросту продублировать код трижды:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25
play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25
play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

Этот код просто огромен! Как быть, если нам захочется поменять сэмпл на :elec_plip? Придется найти все места с изначальным :elec_blup и переписать их. Что ещё важнее, каким образом повторить кусок кода 50 раз или 1000? Это было бы и впрямь целая куча кода. Гигантское число строк пришлось бы изменять для каждой правки.

Итерации

На самом деле сделать повторение кода должно быть не сложнее, чем сказать сделай это три раза. В общем-то, так оно и есть. Помните ли вы о нашем старом знакомом, блоке кода? Его можно использовать для отметки начала и конца кода, который необходимо повторить три раза. Мы добавим специальную конструкцию 3.times. Так что, вместо записи делай это три раза, мы напишем 3.times do. Это не очень сложно. Просто не забывайте указать end в конце кода, который надо повторить:

3.times do
  play 50
  sleep 0.5
  sample :elec_blup
  sleep 0.5
  play 62
  sleep 0.25
end

Ну, разве это не лучше дублирования? Много красивых структур может быть создано с использованием этой инструкции:

4.times do
  play 50
  sleep 0.5
end
8.times do
  play 55, release: 0.2
  sleep 0.25
end
4.times do
  play 50
  sleep 0.5
end

Вложенные Итерации

Еще можно поместить итерации внутрь других итераций и получить интересный рисунок. Например:

4.times do
  sample :drum_heavy_kick
  2.times do
    sample :elec_blip2, rate: 2
    sleep 0.25
  end
  sample :elec_snare
  4.times do
    sample :drum_tom_mid_soft
    sleep 0.125
  end
end

Цикличность

Если потребуется повторить что-то много раз, придётся указывать очень большие значения, такие как 1000.times do. В этом случае, наверное, лучше попросить Sonic Pi повторять код до бесконечности (или, как минимум, до того момента, пока вы не нажмёте кнопку “Остановить”!). Давайте зациклим амен-брейк:

loop do
  sample :loop_amen
  sleep sample_duration :loop_amen
end

О циклах важно знать то, что они работают как чёрные дыры внутри кода. Как только исполнение кода попадает в цикл, оно не cможет покинуть его до тех пор, пока вы не остановите его. Код просто будет повторяться по кругу снова и снова вечно. Это значит, что вы никогда не услышите код, написанный после цикла. К примеру, тарелка после этого цикла никогда не прозвучит:

loop do
  play 50
  sleep 1
end
sample :drum_cymbal_open

Теперь, пришла пора создать интересные структуры из вашего кода при помощи итераций и циклов!