4 Рандомизация (Внесение случайностей)

# Рандомизация

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

## Повторяемость

Очень полезная случайная функция называется `rrand`. Она вернет случайное значение в диапазоне двух чисел - *минимума* и *максимума* (`rrand` это сокращение от "ранжированный генератор случайных чисел"). Попробуем проиграть какую-нибудь случайную ноту:

```
play rrand(50, 95)
```

Ого, получился неожиданный звук. Он воспроизвел ноту `83.7527`. Прекрасная случайная нота в промежутке между 50 и 95. Постойте-ка, я только что точно предсказал случайную ноту, которая и у вас получилась? Что-то тут нечисто. Попробуем снова. Что? Он снова выбрал `83.7527`? Это явно не случайно!

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

Конечно же, в конкретном музыкальном произведении, если бы `83.7527` "случайно" выбиралась каждый раз, это было бы не очень интересно. Но все-таки этого не происходит. Попробуйте следующее:

```
loop do
  play rrand(50, 95)
  sleep 0.5
end 
```

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

## Колокола с привидениями

Прекрасной иллюстрацией случайности в действии является пример колоколов, в которые как будто вселились призраки. Он повторяет пример `:perc_bell` , выбирая случайную скорость и задержку между звуками:

```
loop do
  sample :perc_bell, rate: (rrand 0.125, 1.5)
  sleep rrand(0.2, 2)
end
```

## Случайная частота среза фильтра нижних частот

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

```
use_synth :tb303
loop do
  play 50, release: 0.1, cutoff: rrand(60, 120)
  sleep 0.125
end
```

## Начальные точки для генерации случайных чисел

Что, если вам не нравится последовательность случайных чисел, сгенерированная Sonic Pi? Ну, очень легко выбрать другую начальную точку, если использовать `use_random_seed`.Начальная точка по умолчанию равна 0, так что для другого случайного результата выбирайте другую точку!

Рассмотрите следующее:

```
5.times do
  play rrand(50, 100)
  sleep 0.5
end
```

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

```
use_random_seed 40
5.times do
  play rrand(50, 100)
  sleep 0.5
end
```

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

Давайте познакомимся с некоторыми другими случайными функциями.


## choose

Время поиграться. Поменяйте частоту - что происходит, когда вы используете высокие, малые, или отрицательные значения? Посмотрите, что произойдет, когда вы поменяете значение `rate:` для сэмпла `:ambi_choir` на незначительную величину (например, до `0.29`). Что произойдет, если вы выберите очень маленькое значение для `sleep`? Проверьте, получится ли заставить его играть так быстро, что все упадёт с ошибкой из-за того, что компьютер не справится с этим (если это всё же произошло, то просто выберите для `sleep` значение побольше и снова нажмите `Выполнить`).

```
choose([60, 65, 72])
```

Послушаем, как это звучит:

```
loop do
  play choose([60, 65, 72])
  sleep 1
end
```

## rrand

Мы уже видели `rrand`, но пробежимся по ней вновь. Она возвращает случайную величину в промежутке двух чисел, не включая границы. Это значит, что никогда не будет выбрано самое большое или самое маленькое значение - всегда нечто между ними. Число всегда будет дробным, то есть не целым. Примеры дробных чисел, возвращаемых `rrand(20, 110)`:

* 87.5054931640625
* 86.05255126953125
* 61.77825927734375

## rrand_i

Время от времени вам может понадобится получить целое случайное число, а не дробное. Тут-то и придёт на помощь `rrand_i`. Она работает так же, как `rrand`, но включает граничные значения (то есть она может выбирать минимальные и максимальные числа). Примеры, полученные из `rrand_i(20, 110)`:

* 88
* 86
* 62

## случайный

Вернет случайное дробное число от 0 (включительно), до максимального указанного вами. По умолчанию числа лежат в промежутке от 0 до 1. Такая функция полезна для выбора случайного усиления:

```
loop do
  play 60, amp: rand
  sleep 0.25
end
```

## rand_i

Относится к `rrand_i`, как `rrand_i` к `rrand`. То есть она выбирает случайное целое число в диапазоне от 0 до максимального значение, которое вы укажете.

## игральная кость

Иногда нужно изобразить бросание игральных костей - это частный случай `rrand_i`, когда минимальное значение всегда 1. В вызов `dice` требуется передать количество сторон кости. Стандартная игральная кость имеет 6 сторон, так что `dice(6)` будет работать очень похожим образом - возвращать 1, 2, 3, 4, 5 или 6. Однако, прямо как в ролевых играх в стиле фэнтези, пользу может принести и кость с 4 сторонами, и с 12 сторонами или с 20 сторонами. Может даже потребуется кость со 120 гранями!

## one_in

Наконец, может потребоваться сымитировать вероятность выпадания наибольшей из граней игральной кости, например, 6 для обычной кости. Функция `one_in` возвращает истину с вероятностью один к числу сторон кости. Следовательно, для `one_in(6)` шанс получить истину составит 1 к 5. В остальных 5 из 6 случаев вернётся ложь. Истинные и ложные значения очень полезны для логических выражений `if`, которые мы рассмотрим в одной из следующих глав нашего учебника.

А теперь, пришла пора добавить немного неразберихи в вашу музыку за счет случайностей!
