A.11 Тик-так

# Трекинг ритма

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

## Счетчик тактов

При создании музыки мы часто хотим делать разные вещи с учетом текущего такта. Sonic Pi имеет специальную систему подсчета тактов, которая называется `tick`, чтобы дать вам контроль над тем, какой в точности сейчас такт, и даже поддерживает работу нескольких тактов одновременно с их собственными темпами.

Давайте поиграем - чтобы сдвинуть такт во времени, нам просто нужно вызвать `tick`. Откройте свободный буфер, введите следующий текст и нажмите Выполнить:

```
puts tick #=> 0
```

Это вернет нам текущий такт: `0`. Обратите внимание, что даже если вы нажмете кнопку Выполнить несколько раз, вам всегда вернется `0`. Это связано с тем, что каждый цикл начинает новый отсчет тактов с 0. Однако, пока цикл все еще активен, мы можем сдвигать такт во времени столько раз, сколько захотим:

```
puts tick #=> 0
puts tick #=> 1
puts tick #=> 2
```

Всякий раз, когда вы видите символ `# =>` в конце строки кода, это означает, что эта строка будет записывать в журнал текст, расположенный справа от этого символа. Например, `put foo # => 0` означает, что код `puts foo`, напечатает `0` в журнале.

## Проверка такта

Мы видели, что `tick` делает две вещи. Он увеличивает (+1) и возвращает нам значение текущего такта. Иногда мы просто хотим посмотреть текущий такт, не увеличивая его. Мы можем сделать это с помощью `look`:

```
puts tick #=> 0
puts tick #=> 1
puts look #=> 1
puts look #=> 1
```

В этом коде мы делаем два хода такта во времени, а затем дважды вызываем `look`. В журнале мы увидим следующие значения: `0`,` 1`, `1`,` 1`. Первые два `tick` вернули` 0` и `1`, как и ожидалось, затем два` look` просто дважды вернули значение последнего такта, которое было равно `1`.


## Кольцевые списки

Теперь мы можем сдвигать такт во времени с помощью `tick` и узнавать его текущее значение с помощью` look`. Что дальше? Нам пригодится кое-что еще. Sonic Pi использует кольца, чтобы представлять через них рифы, мелодии и ритмы, а система тиков была специально разработана для тесного взаимодействия с ними. На самом деле у колец есть собственная версия такой системы, это `tick` с добавленной точкой. Он делает две вещи: во-первых, он действует как обычный `tick` и увеличивает значение такта. Во-вторых, он ищет значение кольца, используя такт в качестве индекса. Давайте взглянем:

```
puts (ring :a, :b, :c).tick #=> :a
```

`.tick` - это специальная версия` tick` с точкой, которая будет возвращать первое значение кольца `: a`. Мы можем получить каждое значение в кольце, вызвав `.tick` несколько раз:

```
puts (ring :a, :b, :c).tick #=> :a
puts (ring :a, :b, :c).tick #=> :b
puts (ring :a, :b, :c).tick #=> :c
puts (ring :a, :b, :c).tick #=> :a
puts look                   #=> 3
```

Взгляните в журнал, и вы увидите `: a`,`: b`, `: c`, а затем снова`: a`. Обратите внимание, что `look` возвращает` 3`. Вызовы `.tick` действуют так же, как и вызовы привычного `tick` - они увеличивают локальный такт во времени.


## Арпеджиатор живого цикла

Настоящая мощь проявляется, когда вы смешиваете `tick` с кольцами и` live_loop`. В совокупности у нас есть все инструменты, необходимые для создания простого арпеджиатора. Нам нужно всего четыре вещи:

1. Кольцо, содержащее ноты, которые мы хотим зациклить.
2. Средства увеличения и получения значения такта.
3. Возможность воспроизведения ноты  с учетом текущего такта.
4. Структура цикла для повторения арпеджиатора.

Все эти вещи можно найти в следующем коде:

```
notes = (ring 57, 62, 55, 59, 64)
live_loop :arp do
  use_synth :dpulse
  play notes.tick, release: 0.2
  sleep 0.125
end
```

Давайте посмотрим на каждую из этих строк. Сначала мы определяем кольцо нот, которые мы будем  играть. Затем мы создаем `live_loop` с именем`: arp`, который обеспечит нам цикл. Каждый раз проходя цикл `live_loop`, мы устанавливаем наш синтезатор в`: dpulse`, а затем проигрываем следующую ноту в нашем кольце, используя `.tick`. Помните, что это увеличивает наш счетчик тактов и использует последнее значение тактов в качестве индекса в нашем кольце из нот. Наконец, мы ждем восьмой такт, прежде чем снова начать цикл.

## Работа нескольких тактов одновременно

Очень важно знать, что `tick` связан с live_loop локальными отношениями. Это означает, что каждый `live_loop` имеет свой независимый счетчик тактов. Это намного мощнее, чем глобальный метроном. Давайте посмотрим на это в действии:

```
notes = (ring 57, 62, 55, 59, 64)
with_fx :reverb do
  live_loop :arp do
    use_synth :dpulse
    play notes.tick + 12, release: 0.1
    sleep 0.125
  end
end
live_loop :arp2 do
  use_synth :dsaw
  play notes.tick - 12, release: 0.2
  sleep 0.75
end
```

## Столкновение тактов

Основная причина путаницы с системой тиков Sonic Pi заключается в том, что люди используют сразу несколько счетчиков наименованных тактов для несколько колец в одном и том же `live_loop`:

```
use_bpm 300
use_synth :blade
live_loop :foo do
  play (ring :e1, :e2, :e3).tick
  play (scale :e3, :minor_pentatonic).tick
  sleep 1
end
```

Несмотря на то, что каждый `live_loop` имеет свой собственный независимый счетчик ударов, мы вызываем` .tick` дважды в одном и том же `live_loop`. Это означает, что такт будет увеличиваться дважды на каждый шаг времени. Это может привести к некоторым интересным полиритмам, но часто это не то, что вы хотите. Есть два решения этой проблемы. Один из вариантов - вручную вызвать `tick` в начале` live_loop`, а затем использовать `.look` для поиска текущего такта в каждом` live_loop`. Второе решение заключается в передаче уникального имени каждому вызову `.tick`, например,` .tick (: foo) `. Sonic Pi создаст и отследит отдельный счетчик тактов для каждого поименованного тика. Таким образом, вы можете работать с таким количеством тактов, которое вам нужно! См. Раздел 9.4 о поименованных тиках встроенного руководства для получения дополнительной информации.

## Соединим всё вместе

Давайте соберем все эти знания о`tick`,` ring` и `live_loop` вместе для одного забавного финального примера. Как обычно, не относитесь к этому как к готовому произведению. Начните менять значения, поиграйте с этим и посмотрите, во что вы можете превратить это. Увидимся в следующий раз...

```
use_bpm 240
notes = (scale :e3, :minor_pentatonic).shuffle
live_loop :foo do
  use_synth :blade
  with_fx :reverb, reps: 8, room: 1 do
    tick
    co = (line 70, 130, steps: 32).tick(:cutoff)
    play (octs :e3, 3).look, cutoff: co, amp: 2
    play notes.look, amp: 4
    sleep 1
  end
end
live_loop :bar do
  tick
  sample :bd_ada if (spread 1, 4).look
  use_synth :tb303
  co = (line 70, 130, steps: 16).look
  r = (line 0.1, 0.5, steps: 64).mirror.look
  play notes.look, release: r, cutoff: co
  sleep 0.5
end
```
