Практика использования эффектов

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

Помните, ошибок нет, есть только возможности. Однако, каждый из этих подходов даст разный звук и разные показатели производительности. Поэтому попрактикуйтесь, а затем использте тот способ, который звучит лучше всего для вас, и в то же время укладывается в ограничения быстродействия вашей платформы.