Sonic Pi入門

Sonic Piで遊んでみた。

## Sonic Piとは
音楽を作りながらプログラミング（Ruby）を学べるシンセサイザー。
ライブコーディングで音楽を奏でたりできて楽しそう。

公式：https://sonic-pi.net/

## インストール
公式に飛んでportable版をダウンロード＆インストールしました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/285786/99b3fbe6-bc8b-9dd3-e37d-87b9f793f058.png)

こんな感じのワークステーションが起動した。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/285786/216c23db-4652-9a19-6823-eaf8169621d9.png)

## 使ってみる
エディタにplay 60と入れてalt + rを押下（macはcommand + r）。

```ruby:ruby
play 60
```

ちなみに再生を停止するにはalt + s。
60はmidiの規格でドの音程らしい。なのでドの音が鳴るはず。
次にドミソを順に鳴らしてみる。

```ruby:ruby
play 60
sleep 1 # 1拍休む
play 64
sleep 1
play 67
```
sleepで休む長さは use_bpmで変更できる。

```ruby:ruby
# defaultは60
use_bpm 120

play 60
sleep 1 # 1拍休む
play 64
sleep 1
play 67
```
音程はcなどのkeyで指定することもできる。

```ruby:ruby
# defaultは60
use_bpm 120

play :c4 # c4メジャー
sleep 1 # 1拍休む
play :e4
sleep 1
play :g4
```

細かいエフェクトを指定する。

```ruby:ruby
play :c4, amp: 0.1    # 音量を小さく
sleep 1 # 1拍休む
play :e4, release: 2  # fade-in
sleep 1
play :g4, attack: 2   # fade-out
```

エディタ上の命令（playとか）にカーソルがある状態で
alt + iを叩くとヘルプが表示されるので参考に。

コードで和音指定してみる。

```ruby:ruby
play chord(:c4, :major)
```

sleepを挟む。

```ruby:ruby
# 0.5はsleepの長さ
play_pattern_timed chord(:c4, :major), 0.5
```

スケールで音階を指定する。

```ruby:ruby
play_pattern_timed scale(:c4, :major), 0.5
```

音階の中で音をシャッフルする。

```ruby:ruby
play_pattern_timed scale(:c4, :major).shuffle, 0.5
```

シャッフルさせる時、Sonic Piでは疑似乱数を使っているので、
何度再生しても同じ順で再生される。
これを変えるにはシード値を変えてあげればいい。

```ruby:ruby
use_random_seed 10
play_pattern_timed scale(:c4, :major).shuffle, 0.5
```

ログに値を出力する。
ついでに乱数の使い方も。

```ruby:ruby
use_random_seed 10
# ログ出力にはputsを使う。
puts rand(10) # 0以上10未満のランダムな実数
puts rand_i(10) # 0以上10未満のランダムな整数
puts rrand(3, 6) # 3以上6未満のランダムな実数
puts rrand_i(3, 6) # 3以上6未満のランダムな整数
puts [60, 64, 67].choose # 指定範囲のランダムな値

# 10回ループする。
10.times do
  # 60～70の音を6割～9割の音量で再生。
  play rrand_i(60, 70), amp: rrand(0.6, 0.9)
  # 休みの長さは1/2か1/4のどちらか。
  sleep [0.5, 0.25].choose
end
```

eachとloop。

```ruby:ruby
# リストの要素を1つずつ取り出して再生。
notes = [60, 64, 67]
notes.each do |note|
  play note
  sleep 0.5
end

# ringを指定して最後まで行ったら先頭に戻る。
notes = (ring 60, 64, 67)
loop do
  # tickで次の要素に進める。
  play notes.tick
  sleep 0.5
end
```

シンセを使う。

```ruby:ruby
# 用意されている音色を1つずつ再生。
synth_names.each do |s|
  puts s
  use_synth s  # 音色を変えるにはuse_synthを使う。
  play 60
  sleep 1
end
```

サンプリング音源を使う。

```ruby:ruby
loop do
  # 例えばアーメンループ
  # sleepの長さよりサンプル音源の長さが長いと音が被る。
  # beat_stretchでサンプル音源の長さを2拍に変更。
  # もしくはbpm(Beats Per Minute)をサンプル音源に合わせる。
  # use_sample_bpm :loop_amen
  sample :loop_amen, beat_stretch: 2
  sleep 2
end
```

サンプル音源は画面下のエリアで確認できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/285786/24af4782-979d-8700-381e-a8ee84e043d4.png)

loop命令を複数記述しても1つ目のloopで回り続けてしまう。
ループを同時に実行したい。
→live_loopを使う。

```ruby:ruby
use_sample_bpm :loop_amen

live_loop :amen do
  sample :loop_amen, amp: 0.5
  sleep 1
end

live_loop :piano do
  sample :ambi_piano
  sleep 1
end
```

エフェクトを使う。
画面下のエリアで「エフェクト」を開くとオプションの説明が見られる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/285786/fbbdd878-b109-792c-9c68-a6a1c1566420.png)

```ruby:ruby
use_sample_bpm :loop_amen

live_loop :amen do
  with_fx :wobble, phase: 4 do
    sample :loop_amen, amp: 0
  end
  sleep 1
end

live_loop :piano do
  with_fx :echo, mix: 0.1 do
    sample :ambi_piano
  end
  sample :ambi_choir, amp: 0
  sleep 1
end
```

ドラムループを使う。

```ruby:ruby
# Ball Drum
# Snare Drum
# Hi-hat
# がドラムセットの基本らしい。

use_bpm 128

live_loop :drum do
  sample :bd_sone
  sleep 1
  sample :bd_sone
  sample :sn_dolf
  sleep 1
end

live_loop :hh do
  nil
  sleep 0.5
  sample :drum_cymbal_closed
  sleep 0.5
end
```

サンプルコード。
https://github.com/naman03malhotra/genesis/blob/master/edm_genesis.rb