Программирование вероятностного секвенсора

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

Вероятность

Прежде чем мы сможем начать делать новые биты и синтезаторные ритмы, нам нужно быстро обратиться к основам вероятности. Это может показаться пугающим и сложным, но на самом деле это так же просто, как бросать кости - честно! Когда вы берете обычные 6-ти сторонние кости для настольных игр и бросаете их, что на самом деле происходит? Ну, во-первых, вы с одинаковой вероятностью получите 1, 2, 3, 4, 5 или 6. Фактически, учитывая, что это 6-ти сторонние кости, в среднем (если вы бросаете множество раз) вы будете получать 1 каждые 6 бросков. Это означает, что у вас есть шанс 1 к 6 бросить 1. Мы можем эмулировать броски костей в Sonic Pi с помощью функции dice. Давайте бросим с ее помощью кости 8 раз:

8.times do
  puts dice
  sleep 1
end

Обратите внимание, что журнал отображает значения от 1 до 6 так же, как если бы мы сами бросали реальные кости.

Случайные барабанные ритмы

Теперь представьте, что у вас есть барабан, и каждый раз, когда вы собирались в него ударить, вы бросали кости. Если вы получили 1, вы били в барабан, и не били всякий раз, когда выпадало другое число. Теперь у вас есть вероятностная драм-машина, работающая с вероятностью 1/6! Давайте послушаем, как это звучит:

live_loop :random_beat do
  sample :drum_snare_hard if dice == 1
  sleep 0.125
end

Давайте пробежим по каждой строке, чтобы убедиться, что нам с этим все ясно. Итак, сначала мы создаем новый live_loop с именем: random_beat, который будет постоянно повторять две строки между do и end. Первая из этих строк - это вызов sample, который будет воспроизводить предварительно записанный звук (в данном случае звук: drum_snare_hard). Однако эта строка имеет специальное условное окончание if. Это означает, что строка будет выполнена только в том случае, если оператор в правой части if равен true. В нашем случае, если «dice == 1». Это вызывает нашу функцию dice, которая, как мы видели, возвращает значение от 1 до 6. Затем мы используем оператор равенства == , чтобы проверить, равно ли это значение 1. Если это 1, то оператор сообщает true и звучит наш малый барабан. Если это не 1, тогда оператор сообщает false и малый барабан не звучит. Вторая строка просто ждет 0,125 секунды, прежде чем снова бросить кости.

Изменение вероятности

Те из вас, кто играл в ролевые игры, будут знакомы с множеством кубиков странной формы с различными диапазонами. Например, есть кости в форме тетраэдра, которые имеют 4 стороны и даже 20 сторонних кубиков в форме икосаэдра. Количество сторон на кости меняет шанс или вероятность получить 1. Чем меньше сторон, тем больше вероятность, что вы получите 1, и чем больше сторон, тем меньше вероятность. Например, с 4-х сторонними кубиками, есть один шанс к 4 получить 1, а с 20-ти сторонними кубиками есть шанс один к 20. К счастью, в Sonic Pi для этого есть удобная функция one_in. Давай поиграем:

live_loop :different_probabilities do
  sample :drum_snare_hard if one_in(6)
  sleep 0.125
end

Запустите живой цикл выше, и вы услышите уже знакомый случайный ритм. Но не останавливайте выполнение кода. Вместо этого измените 6 на другое значение, например ` 2 или 20`, и снова нажмите кнопку Выполнить. Обратите внимание, что более низкие числа означают, что малый барабан звучит чаще, а более высокие числа означают, что реже. Вы делаете музыку с вероятностью!

Комбинирование вероятности

Все становится действительно захватывающим, когда вы комбинируете несколько сэмплов, запускаемых с разными вероятностями. Например:

live_loop :multi_beat do
  sample :elec_hi_snare if one_in(6)
  sample :drum_cymbal_closed if one_in(2)
  sample :drum_cymbal_pedal if one_in(3)
  sample :bd_haus if one_in(4)
  sleep 0.125
end

Снова запустите код выше и затем начните изменять вероятности, чтобы повлиять на ритм. Кроме того, попробуйте изменить сэмплы, чтобы создать совершенно новое звучание кода. Например, попробуйте изменить : drum_cymbal_closed на: bass_hit_c, чтобы добавить баса!

Повторяющийся ритм

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

live_loop :multi_beat do
  use_random_seed 1000
  8.times do
    sample :elec_hi_snare if one_in(6)
    sample :drum_cymbal_closed if one_in(2)
    sample :drum_cymbal_pedal if one_in(3)
    sample :bd_haus if one_in(4)
    sleep 0.125
  end
end

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

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

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

live_loop :multi_beat do
  use_random_seed 2000
  8.times do
    c = rrand(70, 130)
    n = (scale :e1, :minor_pentatonic).take(3).choose
    synth :tb303, note: n, release: 0.1, cutoff: c if rand < 0.9
    sample :elec_hi_snare if one_in(6)
    sample :drum_cymbal_closed if one_in(2)
    sample :drum_cymbal_pedal if one_in(3)
    sample :bd_haus, amp: 1.5 if one_in(4)
    sleep 0.125
  end
end