Хотя снаружи они выглядят обманчиво просто, внутри эффекты устроены довольно сложно. Их простота часто побуждает людей злоупотреблять их использованием. Это вполне нормально, если у вас мощный компьютер. Но если, как и я, вы импровизируете на Raspberry Pi, то нужно быть аккуратным с нагрузкой. Иначе ритм может начать прерываться.
Рассмотрим следующий код:
loop do
with_fx :reverb do
play 60, release: 0.1
sleep 0.125
end
end
В этом примере мы играем ноту 60 с очень коротким временем затухания. То есть это очень короткая нота. Нам нужна реверберация, поэтому мы обернули её в блок reverb. Пока что все хорошо. За исключением…
Посмотрим, что делает код. Во-первых, у нас есть цикл loop
. Это означает, что всё, что внутри него, повторяется бесконечно. Во-вторых, есть блок with_fx
. Его роль в том, чтобы создавать новый эффект реверберации каждый раз, когда он выполняется. Как будто для каждого щипка гитарной струны включается собственная педаль реверберации. Здорово, что так можно делать, но это не всегда то, что нам нужно. Например, такой код будет трудно выполнять на Raspberry Pi. Создание эффекта реверберации и ожидание момента, когда он должен быть остановлен и удален, - обо всем позаботится за тебя блок with_fx
. Но на это требуются ресурсы процессора, а они могут быть ограничены.
Как изменить код так, чтобы он больше походил на обычное подключение, где у нашего гитариста всего одна педаль реверберации, через которую и пропускаются все звуки? Легко:
with_fx :reverb do
loop do
play 60, release: 0.1
sleep 0.125
end
end
Мы помещаем наш цикл внутрь блока with_fx
. Таким образом создается всего один единственный эффект для всех нот, извлекаемых в цикле. Этот вариант намного более эффективен, и Raspberry Pi с ним хорошо справится.
В качестве компромисса можно предложить использовать with_fx
на протяжении нескольких повторений внутри цикла:
loop do
with_fx :reverb do
16.times do
play 60, release: 0.1
sleep 0.125
end
end
end
То есть новый эффект реверберации будет создаваться через каждые 16 нот.
Это настолько распространенный паттерн, что with_fx
поддерживает опцию для выполнения именно этого, но без необходимости писать блок 16.times
:
loop do
with_fx :reverb, reps: 16 do
play 60, release: 0.1
sleep 0.125
end
end
Обе записи: reps: 16
и 16.times do
будут вести себя одинаково. Reps: 16
по сути повторяет код в блоке do / end
16 раз, так что вы можете использовать их оба взаимозаменяемо и выбрать тот, который вам удобнее.
Помните, ошибок нет, есть только возможности. Однако, каждый из этих подходов даст разный звук и разные показатели производительности. Поэтому попрактикуйтесь, а затем использте тот способ, который звучит лучше всего для вас, и в то же время укладывается в ограничения быстродействия вашей платформы.