Overtone始めたらClojureのシーケンス操作の哲学にマッチしすぎててスゲー!ってなった話
とうとうライブができるプログラマーになることにしたので、Overtoneを始めた。
目標
- (SHOULD)音作りを雰囲気だけかじる(ここは今回重要でない)
- ドラムで軽やかなリズムを奏でる
- ドラムに合わせてメロディが流れるようにする
- だんだん音を足していく
- (SHOULD)フィルターをかける
これくらいできればなんかそれっぽい感じになるでしょ。
始め方
を読んで頑張ろう。変化に耐えられる心を持てってwikiに書いてあったから、変化に耐えられない日記はポインタと化します。
使い方メモ
definst
楽器(というか音色)を定義できるっぽい。デフォルトでもいろいろあるけど。
ctl
今鳴っている音に対して変更をかけられる。なんかライブっぽくてかっこいい。 フィルターをだんだんかけていく、みたいなのもこれを使えるのかな。
(definst quux [freq 440] (* 0.3 (saw freq))) (quux) (ctl quux :freq 660) ;; => 1オクターブ上がる (stop)
sample
サンプリング音源を鳴らす。 freesoundっていう無料音源サイト?からダウンロードすることもできるみたい。 コマンド叩いたらブラウザが開いて、ログインを求められた。面白い。
(def water-drops (freesound 50623)) (water-drops) ;; => 水音が鳴る (stop)
この音を加工したりもできるんだろうな。
play-chord
コードを鳴らす。
(defn play-chord [a-chord] (doseq [note a-chord] (saw2 note))) (play-chord (chord :C4 :major))
すごい。
chordはdoseqできるみたいだから、多分 chord
関数はシーケンス生成してるんだな。
実装見たら実際そうだった。すごい。こんなところでClojure likeなシーケンス操作が出てくるなんて!
ってことは、chordはシーケンスだから複数のコードを合成する、みたいなこともできるのか。 たとえばCmM7を鳴らしたい時は、
(let [minor7 (chord :C4 :m7) major7 (chord :C4 :M7)] (-> (concat minor7 major7) distinct play-chord)) ;; => 不穏な音
play-chordされる前の Set
シーケンスの中身を見てみたら合ってそう。
こんなに簡単に複雑なコードを鳴らせるなら、ジャズが捗りますな(雑な偏見)。
metronome
ビートを定義する。
(defonce metro (metronome 120))
(metro)
すると今のビートが取れるようになる。これを渡して、at関数で任意のタイミングでビートが鳴らせるようになる。
(defn chord-progression-beat [m beat-num] (at (m (+ 0 beat-num)) (play-chord (chord :C4 :major))) (at (m (+ 4 beat-num)) (play-chord (chord :G3 :major))) (at (m (+ 8 beat-num)) (play-chord (chord :A3 :minor))) (at (m (+ 14 beat-num)) (play-chord (chord :F3 :major))) (apply-at (m (+ 16 beat-num)) chord-progression-beat m (+ 16 beat-num) []))
けっこう冗長だから、もっとシンプルに書けそうだな。
とはいえ、これを実行すると延々けっこうきれいなコード進行が鳴り続ける。プログラミングで実現してるなんて。すごい。 しかもこれはシーケンスを解釈してるだけ。なんてこった!シーケンスすげぇな。
これの実行中は、関数を再定義すると apply-at
された時に定義が書き換えられて新しいコード進行が始まる。
さらに別の、たとえばドラムトラックを書いて評価すれば、それがメトロノームに合わせて演奏される。
metro-npm
metronomeの内容を書き換える。つまりテンポを変えられる。
そういえば小節の概念がないな。 多分、ループを作った時のapply-atするタイミング次第で変拍子でもなんでもいいんだろうな。
わからないこと
sc-ugenっていうオブジェクトを足し算したり掛け算したりするサンプルコードの意味がわからない。 SuperCollider Unit Generatorのことらしいから、SuperColliderをちょっとさわってみないといけないのかな。
あとは、そもそもオシレーターってなんだっけ??SAWって波の形だよね?みたいなレベルで音楽用語がわからない。 DAWさわっててもギター弾いてても曲書いてても、わからないことだらけだぁ。
https://github.com/overtone/overtone/blob/master/docs/ugens.mdを見てる限りは、サンプルコードに出てきて宣言元を辿れないやつはこのsc-ugenオブジェクトだったから、ugensのページに対応するものがありそう。