ランダム化

音楽にすこし面白さを加えるために、ランダムという素晴らしい方法があります。Sonic Piは音楽にランダム性を追加するためにいくつかの素晴らしい機能を持っていますが、Sonic Piのランダムは、真のランダムではありません。これは一体何を意味しているのでしょう? 勉強を開始する前に、この衝撃的な真実を見ていきましょう。

再現性

たいへん便利なランダム関数に、2つの数字の間(最小値と最大値)で乱数(ランダムな値)が得られる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 

そう! 最終的には、ランダムに聞こえますね。ランダム関数へ続いて呼び出されるその後の実行結果はランダムな値を返します。ただし、また再生する場合は正確に乱数値の同じシーケンスを生成し、まったく同じ音が鳴ります。Runボタンが押されるたびに、まるですべてのSonic Piコードが毎回、同じ時間に戻るかように蘇ります。それはまさに映画「恋はデジャ・ブ」のようにシンセの音が繰り返されるのです!

ホーンテッド・ベル

ランダム動作を取り入れたゾクッとするようなベルの音を使った楽しい作例です。繰り返しサンプルのベル音:perc_bellをループさせ、ベル音の再生速度と音の間のsleepにランダムな数値を用いています。

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

ランダムなカットオフ

ランダム化のもう1つの楽しみ方の例は、ランダムにシンセのカットオフを加えることです。これを試してみるのに絶好のシンセは、: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:選択

あらかじめ用意した数値をリストの中からランダムに選択することは、一般的に行われていることでしょう。例えば、60、65または72の中から1音を演奏することができます。chooseを用いれば、リストから1つの項目をで選択することができます。まず、カンマで区切った番号のリストを角括弧でラップ(包んで)し、配置する必要があります:[60, 65, 72]。次にそれらをchooseに渡す必要があります。

choose([60, 65, 72])

どんな音になるか聞いてみましょう。

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

rrand

すでにrrandについて触れてきましたが、再び実行してみましょう。これは、2つの値の間の乱数(排他的)を返します。この意味するところは上部または下部の番号いずれの値も含まれません。常に両者の間にある値です。そして、その番号は常に浮動小数点になります - それは整数ではなく、分数です。rrand(20, 110)で返される浮動小数点数の例は次のとおりです。

rrand_i

時々、あなたは小数点ではなく、整数の乱数を望むこともあるでしょう。これはrrand_iを用いることで解決できます。それは小数点を除いてrrandと同様に最小値および最大値の範囲(この場合、最長値と最大値も含まれます)に潜在するランダム値を返す動作をします。下記は、rrand_i(20, 110)によって返される数値の例です。

rand

randは、0を含む最小値と、引数として指定した最大値未満の間のランダムな浮動小数点数を返します。デフォルトでは01の間の値を返します。このため、amp:値をランダム化する際に便利です。

loop do
  play 60, amp: rand
  sleep 0.25
end

rand_i

rrand_irrandの関係と同様に、rand_i0と引数として指定した最大値の間の整数値を返します。

dice:サイコロ

ランダムな数字を出す際に、サイコロ投げをまねてみたくなることもあるでしょう。これは、常に下の値が1であるrrand_iの特殊なケースです。diceを呼び出す時は、サイコロの面の数を指定する必要があります。標準的なサイコロは6面で、dice(6)では、1, 2, 3, 4, 5または6を返すサイコロと同様の作用をします。しかし、空想のボードゲームのように、4面、12面または20面サイコロ、さらには120面のサイコロで値を見つけたいこともあるでしょう。

one_in

最後に、一般的なサイコロを振って、例えば6を出すということをやってみたくなることもあるでしょう。one_inはサイコロの面の数分の1の確率でtrueを返します。したがってone_in(6)では6分1の確率でtrue、それ以外の場合はfalseを返します。truefalseの値は、このチュートリアルの次のセクションで説明するif文で非常に有用です。

さあ、ランダム性を使いこなしてコードをまぜこぜにしていきましょう!