# Серфинг случайных потоков

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

## Там нет случайного

Первое, что можно узнать, что может вас удивить, играя с функциями рандомизации в Sonic Pi, это то, что они на самом деле не случайны. Что это на самом деле означает? Что ж, давайте предпримем пару эксперементов. Во-первых, представьте число в вашей голове от 0 до 1. Держите его там и не говорите мне. Теперь позвольте мне догадаться … это было `0.321567`? Нет? Ба, да я явно не хорош в этом. Позвольте мне еще раз, но теперь давайте попросим Sonic Pi выбрать это число. Запустите Sonic Pi v2.7 + и укажите выбрать случайное число, но не говорите мне его:

    print rand

Вскроем карты … было ли это `0.75006103515625`? Да! Ха, я вижу, вы настроены немного скептически. Возможно, это была просто удачная догадка. Давай еще раз попробуем. Нажмите кнопку Выполнить еще раз и посмотрите, что мы получим … Что? `0.75006103515625` снова? Это явно не может быть случайным! Ты прав, это не так.

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

## Случайная мелодия

Когда Sonic Pi загружается, он фактически загружает в память последовательность из 441 000 предварительно сгенерированных случайных значений. Когда вы вызываете случайную функцию, такую как `rand` или`rrand`, этот случайный поток используется для генерации вашего результата. Каждый вызов случайной функции берет значение из этого потока. Поэтому 10-й вызов случайной функции будет использовать 10-е значение из потока. Кроме того, каждый раз, когда вы нажимаете кнопку Выполнить, для этого цикла исполнения кода, поток случайных значений сбрасывается к своему началу. Вот почему я мог предсказать результат `rand` и почему «случайная» мелодия всегда была одинаковой. В каждой версии Sonic Pi используется один и тот же случайный поток, что очень важно, когда мы начинаем делиться друг с другом своими произведениями.

Давайте используем эти знания для генерации повторяемой случайной мелодии:

    8.times do
     play rrand_i(50, 95)
     sleep 0.125
    end

Введите это в свободный буфер и нажмите Выполнить. Вы услышите мелодию, состоящую из «случайных» нот от 50 до 95. Когда она закончится, снова нажмите Выполнить, чтобы снова услышать точно такую же мелодию.

## Удобства функций рандомизации

Sonic Pi поставляется с рядом полезных функций для работы со случайным потоком. Вот список некоторых из самых полезных:

- `rand` - просто возвращает следующее значение в случайном потоке
- `rrand` - возвращает случайное значение в диапазоне
- `rrand_i` - возвращает случайное целое число в диапазоне
- `one_in` - возвращает true или false с заданной вероятностью
- `dice` - имитирует бросание костей и возвращает значение от 1 до 6
- `choose` - выбирает случайное значение из списка

Ознакомьтесь с документацией этих функций в справочной системе для получения подробной информации и примеров использования.

## Сброс потока

Хотя возможность повторять последовательность выбранных нот очень важна, чтобы позволить вам воспроизвести риф на танцполе, это может быть не тот рифф, который вы хотите. Разве не было бы здорово, если бы мы могли попробовать несколько разных риффов и выбрать тот, который нам больше всего понравился? Здесь начинается настоящее волшебство.

Мы можем вручную установить поток с помощью функции `use_random_seed`. В информатике случайное начальное число является отправной точкой, из которой может вырасти и расцвести новый поток случайных значений. Давай попробуем:

    use_random_seed 0
    3.times do
      play rrand_i(50, 95)
      sleep 0.125
    end

Отлично, так мы получаем первые три ноты нашей случайной мелодии: `84`,`83` и `71`. Однако теперь мы можем изменить семя для чего-то другого. Как насчет этого:

    use_random_seed 1
    3.times do
      play rrand_i(50, 95)
      sleep 0.125
    end

Интересно, что мы получили `83`,`71` и `61`. Вы можете заметить, что первые два числа здесь такие же, как и последние два числа из тех, что мы получили ранее. И это не совпадение.

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

Давайте вернемся к нашей случайной мелодии из 8 нот с этой новообретенной силой сброса случайного потока, но добавим также живой цикл, чтобы мы могли экспериментировать вживую, пока он играет:

    live_loop :random_riff do
      use_random_seed 0
      8.times do
        play rrand_i(50, 95), release: 0.1
        sleep 0.125
      end
    end

Теперь, пока он все еще играет, измените начальное значение с 0 на другое. Попробуйте `100`, или даже`999`. Попробуйте свои собственные значения, поэкспериментируйте с этим - посмотрите, какое семя создает риф, который вам больше нравится.

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

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

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

    live_loop :random_riff do
      use_random_seed 10300
      use_synth :prophet
      s = [0.125, 0.25, 0.5].choose
      8.times do
        r = [0.125, 0.25, 1, 2].choose
        n = (scale :e3, :minor).choose
        co = rrand(30, 100)
        play n, release: r, cutoff: co
        sleep s
      end
    end
    live_loop :drums do
      use_random_seed 2001
      16.times do
        r = rrand(0.5, 10)
        sample :drum_bass_hard, rate: r, amp: rand
        sleep 0.125
      end
    end