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

В прошлом месяце в этой серии мы углубились в систему рандомизации, на которой базируется 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