Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2011-03-07

CLMを試してみる

| 19:47 | CLMを試してみる - わだばLisperになる を含むブックマーク はてなブックマーク - CLMを試してみる - わだばLisperになる

CLMは音響を色々操作できるパッケージだそうで以前から一度試してみたかったのですが、なんとなく面倒臭さそうだなと思っていて手を付けずにいました。ふと、気まぐれにサイトからソースをダウンロードしてみたところ、中に.asdファイルがあり、想像していたより簡単に導入できそうなので試してみました。

CLMのソースが微妙にCLの作法に則ってない様子でインストールでも妙な躓き方をしますが、とりあえずは導入できたので手順をメモ。

環境は、SBCL 1.0.46、ASDF2、Ubuntu 10.10 64bitです。

ソースを入手

https://ccrma.stanford.edu/software/snd/snd/clm.html

からCLM-4のソースを入手します。

適当なASDFでロードできるところに展開します。

音響系ライブラリの準備

ALSAを使うので開発ライブラリをインストールしておきます。

$ sudo apt-get install libasound2-dev

また、シェルの実行にcshが使われるのでcshもインストールしておく必要があるかもしれません。自分はソースの方を書き換えました。

ロード

どうやら現状ではライブラリをロードした環境(パッケージ)に色々撒き散らすようなので専用のパッケージを作成して、その中に読み込みます。

(defpackage :clm-user
  (:use :cl))

(in-package :clm-user)

;; ソースのディレクトリを指定
(setq clm-directory ".../clm-4/")

(asdf:load-system :clm)

という感じでロードされます。

色々こけたりするかもしれませんが、適当に手で直したりします。

音を鳴らしてみる

〜.insファイルというのが音源が定義されたもののようで、サンプルとしてヴァイオリンが付いてくるのでマニュアルの通りコンパイルしてみます。

(compile-file ".../clm-4/v.ins")
(load ".../clm-4/v.fasl")

適当にいじってみる

使い方は良く分かりませんが、ランダムに音を鳴らす位のことはすぐできました。

WITH-SOUNDマクロで囲んでやると式を評価して音声ファイルを書き出し、音を鳴らしてくれるようです。

;; R2D2的なもの
(with-sound ()
  (dotimes (start 400)
    (let ((r (expt (expt 2 1/12) (random 48))))
      (fm-violin (* start 1/8)
                 1/4
                 (* 110 r)
                 1/10)
      (fm-violin (/ start 8)
                 1/8
                 (* 110
                    (aref #(11/2 13/4 3/4 9/4) (random 4))
                    r)
                 1/10)
      (fm-violin (+ (/ start 8) 1/16)
                 1/8
                 (* 110
                    (aref #(2 3/2 5/2 7/4) (random 4))
                    r)
                 1/10))))
;; マザーコンピュータ的なもの
(with-sound ()
  (dotimes (start 400)
    (let ((r (expt (expt 2 1/12) (random 48))))
      (fm-violin (/ start 8)
                 1/8
                 (* 220 r)
                 1/10)
      ;;
      (fm-violin (+ (* start 1/8) 1/32)
                 1/32
                 (* 440 r)
                 1/10)
      ;;
      (fm-violin (/ start 8)
                 1/8
                 (* 110 (elt #(11/4 3/2 3/4 9/4) (random 4)) r)
                 1/10)
      ;;
      (fm-violin (+ (/ start 8) 1/16)
                 1/8
                 (* 110 (elt #(2 3/2 5/2 7/4) (random 4)) r)
                 1/10)
      ;;
      (fm-violin (/ start 8)
                 1/8
                 (/ 880 r)
                 1/10))))

7平均律や、19平均律など簡単に試してみることができそうです。

その他、CLM情報

Luke Gorrie氏がECLM 2005でSLIMEのデモでCLMを取り上げたことがあったようでいくつか関連の記事/資料をみつけました。

まとめ

SchemeのImpromptuのようにリアルタイムで操作できるものなのかは、調べ切れていないので分からないのですが、自動作曲的なことに使ったり自分用のソルフェージュのプログラムを書いて音感の訓練をしてみたりは手軽にできそうです。

読み書きの速度 (3)

| 18:08 | 読み書きの速度 (3) - わだばLisperになる を含むブックマーク はてなブックマーク - 読み書きの速度 (3) - わだばLisperになる

SBCLでSYMBOL-VALUEでの書き込みが異様に遅い原因

SBCLだと (SETF SYMBOL-VALUE)がどういうわけか異様に遅いということが分かったのですが、Twitterでぶつぶつ言っていたらdisassembleすると良いよ!と言われたので、なるほどと思い、とりあえず定義を追い掛けてみました。

SBCLの場合、(SETF SYMBOL-VALUE)は、SETへ展開されるようで、そのSETは、SB-IMPL::%SET-SYMBOL-VALUEとSB-IMPL::ABOUT-TO-MODIFY-SYMBOL-VALUEを呼ぶようです。

SB-IMPL::%SET-SYMBOL-VALUEが本体のようなので、とりあえずこれを前回と同じように一億回呼んで測定してみます。

  0.125 sec. %SET-SYMBOL-VALUE-1-WRITE
 78.712 sec. SYMBOL-VALUE-1-WRITE

なるほど、%SET-SYMBOL-VALUEだと圧倒的に速いようです。

ということは、ABOUT-TO-MODIFY-SYMBOL-VALUEが遅いのかということで、これだけで計測してみましたが予想通りこの関数が原因でした。

この関数はどんな関数なのかと眺めてみると、コメントに

;;; This function is to be called just before a change which would affect the
;;; symbol value. We don't absolutely have to call this function before such
;;; changes, since such changes to constants are given as undefined behavior,
;;; it's nice to do so. To circumvent this you need code like this:
;;;
;;;   (defvar foo)
;;;   (defun set-foo (x) (setq foo x))
;;;   (defconstant foo 42)
;;;   (set-foo 13)
;;;   foo => 13, (constantp 'foo) => t
;;;
;;; ...in which case you frankly deserve to lose.
(defun about-to-modify-symbol-value (symbol action &optional (new-value nil valuep) bind)

のようなことが書いてあります。コメントにあるコード例が、こんなことしても良かったのか、というような例ですがSBCLでは可能なようです。(他の処理系ではエラー;未定義動作らしいですが…)

面白い色機能ですが速度低下の原因になったりするとしたら微妙な気もします…。