SICPばかりでもなんなので、Clojureで音楽が作れるっぽいOvertoneライブラリと戯れてみる。

Overtoneプロジェクト：

github.com

参考にさせていただいたブログ：

Overtone: Clojureで音楽を書こう : サルノオボエガキ

とりあえずdependenciesを足して、イントロビデオを見て、lein replでコードをコピペして弄ってみる。

github.com

(use 'overtone.live) と (use 'overtone.inst.piano) で当面は十分そう。

ピアノ音を鳴らす関数がそのまんまのpiano。

(piano) あるいは (piano 50) などのように使う。

(piano) で出る音が (piano 60) と同一で、mid2Cのようだ。そこから数が上がる・下がるにつれ半音ずつずれていく。

「ドミソ」のコードは以下のようになる。

( doseq [ note [ 60 64 67 ]] ( piano note ))

時間を指定して鳴らすには (at XXX (piano 60)) といった構文を使う。

以下のコードで「ドレミ」と１秒ずつずれて鳴る。

(let [ time ( now )] ( doseq [ i ( range 3 )] ( at ( + time ( * i 1000 )) ( piano ( + 60 i )))))

基本的には通常のClojureの構文であらかたコントロールできてしまう印象。

とりあえず、音のリストを受け取り、順番に鳴らしていく関数。全ての音符が同じ長さで鳴る（というか等間隔で鳴る）。

( defn play-me [ notes ] (let [ time ( now )] ( doseq [[ i note ] ( map vector ( range ) notes )] ( at ( + ( * 1000 i ) time ) ( piano note )))))

あとは色々試すだけ。

( play-me [ 60 55 60 65 64 60 62 60 60 ])

とか

( play-me [ 60 55 60 65 64 60 62 64 64 ])

とか。

移調するのも (map #(- % 2) notes) などで出来てしまうのが楽しい。

やはり音符の長さは指定したい。ということでplay-meを微調整：

( defn play-me ([ notes ] ( play-me notes ( range ))) ([ notes length ] (let [ time ( now )] ( doseq [[ i note ] ( map vector length notes )] ( at ( + time ( * i 1000 )) ( piano note )))))) (def notes [ 60 55 60 65 64 60 62 60 60 ]) (def length [ 1 1 1 1 1 1 1.5 0.5 1 ]) (def cum-length ( reductions + 0 length )) ( play-me notes cum-length )

あとは休符をどうするかだなー。もっと遊びながら考えていきたい。