読者です 読者をやめる 読者になる 読者になる

レガシーコード生産ガイド

私に教えられることなら

Scheme(Gauche)で音名の列

プログラミング Scheme

最近また(9182391回目ぐらい)、ギターでいい加減そろそろ即興でソロ弾けるようになりたいんじゃ、と少しずつ練習してる。

ソロを一度作って弾いてパターンを指に覚えさせたりしてるんだけど、その前に未だに4〜2弦のフレットがあやふやなので、ランダムに12音の音名を生成してそれを弾いて練習してみることにした。

Clojureで一度書いてるんだけど、今日はScheme、というかGaucheな気分なのでGaucheで書いてみる。

コードはここ

https://github.com/phaendal/scm-sketchbook/blob/master/003.notes/main.scm

設計

Cloureのときの、遅延シーケンスを使ったやり方が気に入ったので、同じように無限の列を生成してそこから取り出して操作する。

よくわかってないけどジェネレータが速いらしいので、勉強も兼ねてジェネレータを使う。

例えばFの3(半)音上に動かしたA♭を取得する場合、

  • A, A+ ... G, G+ を無限に繰り返すジェネレータから、Fまで取り出す
  • Fまで取り出したジェネレータから、さらに3音目のA♭を取り出して返す
  • 毎回これをやると無駄なので、ベースの音(F)と度数(3)でメモ化しておく

効率的なやり方とは言えないけど、無限に続く音の列をイメージできるから気に入ってる。いろんな設計ありそうだし、他の人のやり方も見てみたい。

使用例

  (print (note-change 'C -1))

  (newline)
  (print "random sorted")
  (print (generator->list (random-sorted-list note-names) 12))

  (newline)
  (print "cycle of 4th")
  (print (generator->list (cycle-of 'C 5) 12))

  (newline)
  (print "cycle of 5th")
  (print (generator->list (cycle-of 'C 7) 12))

で、次のような結果になる。

B

random sorted
(B E A+ D+ F+ D C C+ F A G+ G)

cycle of 4th
(C F A+ D+ G+ C+ F+ B E A D G)

cycle of 5th
(C G D A E B F+ C+ G+ D+ A+ F)

以上のコードを使ってランダムな音の列を目標テンポに合わせて弾く練習をした感想

f:id:phaendal:20150713165311j:plain

もうやらない。

広告を非表示にする