LoginSignup
3
3

More than 5 years have passed since last update.

Opusmodusで便利な関数たち

Last updated at Posted at 2018-09-02

はじめに

この記事でOpusmodusの基本的な使い方は説明したので、この記事では便利な機能を紹介します。
でも、そもそもCommon Lispのループやマクロで普通に書けるような物も含まれているので、lispつよい人は自分でゴリゴリ書いてもいいと思います。

乱数系

ジェネラティブなクリエイションにおいて、もはやランダムは絶対正義です。
手っ取り早くいろんな物をつくることができますね。

rnd-pick

リストの中からランダムに一つ要素を取り出すことができます。

(setf pitch-set '(c4 db4 f4 g4 bb4 c5))
(rnd-pick pitch-set)

何回か評価すると、

1 > rnd-pick
db4
1 > rnd-pick
bb4
1 > rnd-pick
g4

実行する度に違う要素を取り出していますね。

rnd-sample

一度に何個か要素を取り出したい時もあります。
そんな時は、

(setf pitch-set '(c4 db4 f4 g4 bb4 c5))
(rnd-sample 5 pitch-set)

何回か評価すると、

1 > rnd-sample
(c5 bb4 bb4 c5 c4)
1 > rnd-sample
(g4 bb4 f4 bb4 bb4)
1 > rnd-sample
(c4 f4 db4 f4 bb4)

欲しい個数まとめてリストにして返してくれます。

rnd-unique

rnd-sampleは、指定した回数rnd-pickをしているだけなので、同じ要素が取り出されることもあります。
そうじゃなくて指定した個数の固有な要素が欲しいときありますよね?
大丈夫です、それできるんです。

(setf pitch-set '(c4 db4 f4 g4 bb4 c5))
(rnd-unique 5 pitch-set)

何回か評価すると、

rnd-unique
(db4 f4 c4 bb4 g4)
1 > rnd-unique
(db4 c5 g4 bb4 f4)
1 > rnd-unique
(c4 f4 c5 bb4 g4)

毎回、被りなくランダムな要素を抽出することができました。

ベクタ系

サイン波、三角派、ホワイトノイズなどを使って、数学的にパラメーターを生成することもできます。
返り値は全てlispのベクタです。
また、ベクタを見やすくグラフで表示してくれるlist-plotという関数があるので便利です。

gen-sine, gen-triangle, gen-sawtooth

たとえば、1200個の点からなる3回上下するサイン波を生成する場合、

(setf wave (gen-sine 1200 3 1))

評価すると、

1 > gen-sine
(0.0 0.15643448 0.309017 0.45399052 0.58778524 0.70710677 0.809017 0.8910065 0.95105654 0.98768836 1.0 0.98768836 0.9510565 0.89100647 0.809017 ... )

(※長いので省略。1200個入ってます)

list-plotした結果が
Screenshot 2018-09-03 07.07.29.png

似たような関数でgen-trianglegen-sawtoothなどがありますが波の形が違うだけで使い方は同じです。

gen-triangle
Screenshot 2018-09-03 07.11.11.png

gen-sawtooth
Screenshot 2018-09-03 07.12.07.png

vector-to-pitch

ベクタはそのままだと小数の集まりなので、なんらかの音楽的データに変換したいところです。
vector-to-pitchを使って、C4からC6の音域の音高データに変換してみましょう。

(setf wave (gen-sine 32 3 1))
(vector-to-pitch '(c4 c6) wave)

評価すると、

1 > vector-to-pitch
(c5 g5 b5 c6 gs5 d5 g4 d4 c4 d4 g4 d5 gs5 c6 b5 g5 c5 f4 cs4 c4 e4 bb4 f5 bb5 c6 bb5 f5 bb4 e4 c4 cs4 f4)

⌘+3で表示すると、
Screenshot 2018-09-03 07.18.57.png
ちゃんとサイン波の形に音高を生成することができました。

ほかにもvector-to-lengthvector-to-velocityなどを使うことで、音価やダイナミクスにマッピングすることも可能です。

tonality-map

vector-to-pitchでベクタを変換すると、指定した音域内で、平均律でアトーナルにマッピングされます。
でもこれでは困ることもありますよね。
大丈夫です。スケールにマッピングできるんです

(setf wave (gen-sine 32 3 1))
(setf raw-pitch (vector-to-pitch '(c4 c6) wave))
(tonality-map '(major :root 'd4) raw-pitch)

ルートをD4にしてD majorにクオンタイズしました。

4 > 
(d5 a5 cs6 d6 a5 e5 a4 e4 d4 e4 a4 e5 b5 d6 cs6 a5 d5 g4 d4 d4 fs4 b4 g5 cs6 d6 b5 g5 b4 fs4 d4 d4 g4)

Screenshot 2018-09-03 07.26.53.png

繰り返し系

前回の記事では、omnを定数でベタ書きしていましたが、あんまり人間向きの方法ではありません。
必要最小限なパラメーター以外はなんらかの方法でループしたり再帰的に処理するのが吉でしょう。

gen-repeat

gen-repeatを使うと、指定した回数omnをリピートさせることができます。

(gen-repeat 2 '(q c4 d4 e4))

評価すると、

1 > gen-repeat
(q c4 mf d4 e4 c4 d4 e4)

Screenshot 2018-09-03 06.30.54.png
指定した回数(2回)繰り返されています。

span

リストの長さを揃えて新しいリストを作りたい時に便利です。
例えば、先にピッチが生成されていて、そのピッチの個数分の音価を作りたい時などによく使います。

(setf my-pitch '(c4 d4 e4 f4 g4 a4 b4))
(span my-pitch '(e s s))

評価すると、

5 > 
(1/8 1/16 1/16 1/8 1/16 1/16 1/8)

Screenshot 2018-09-03 07.36.56.png

このようにピッチの個数分の音価データを作ることができました。

OMNを作る

音高や音価のデータをそれぞれ作った後、omnに変換するのはどうすればいいのでしょうか?
そのままの名前の関数があります。

make-omn

ここに音高と音価のデータがそれぞれあるじゃろ?
( ^ω^)
⊃  ⊂

(setf my-pitch '(c4 d4 e4 f4 g4 a4 b4))
(setf my-length (span pitch '(e s s)))

これを
( ^ω^)
⊃)  (⊂

( ^ω^)
≡⊃⊂≡

こうじゃ…

(setf my-omn (make-omn :pitch my-pitch :length my-length))

( ^ω^)
⊃ .. ⊂  
‘∵  
‘:’;

6 > 
(e c4 s d4 e4 e f4 s g4 a4 e b4)

合体完了!
Screenshot 2018-09-03 07.44.37.png

まとめ

最後に、ここまでの内容をまとめた簡単なサンプル曲を書いてみました。


(setf wave (gen-sine 64 5 1))
(setf my-pitch
 (tonality-map '(minor-pentatonic)
  (vector-to-pitch
   '(c4 c6)
   wave
  )
 )
)
(setf my-length (span my-pitch '(s)))
(setf my-omn (make-omn :pitch my-pitch :length my-length))

(def-score qiita-tutorial-2
 (:key-signature '(c minor)
  :time-signature '(4 4)
  :tempo 144)
 (piano :omn my-omn)
)
(display-musicxml *last-score*)
(display-midi *last-score*)

Screenshot 2018-09-03 07.51.11.png

Opusmodusで楽しく音楽をコーディングしよう!!
興味があったらTwitterもよろしくお願いします!

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3