ぐる式 (貳) より引っ越し作業中.未完.

2005年7月21日木曜日

Squeak 三昧;クラスライブラリに耳を傾ける

SML に流したモノ.

なんでもエエんだけど, FM 音源系なら,高さ,長さ,強さの三つを決めたらそれなりに音を操れるので,ライブラリに含まれるクラスの超簡単なプロフィールから音を組み立ててみたもの.三要素には以下の統計情報を使った.

  • ピッチはルート・クラスからの隔たりで半音間隔.
  • 長さはそのクラスのサイズ.
  • 音量は,最初クラスの人気度 (リファレンス数) にしたかったんだけど,半端じゃない時間 (CD 2 枚分以上?) が掛かるんで,適当にセレクタ数で妥協.

ほとんどのクラスはサイズも小さくて,セレクタ数もそんなに突飛な数にはなってない,ごく一部のクラスがデカくてセレクタもいっぱいというのが聴いて判る (笑).

最初に鳴り出すドローンはいわゆるスクリャービンの神秘和音で,これはクラス関連とは全く無関係,単なる伴奏.全体の演奏時間 (?) は約 6’50" ほど掛かる.

  • Squeak3.8-6665-full でしか試してない.
  • PB の内蔵スピーカはヘボいので,安価いのでエエから外部スピーカを接続して鳴らした方がエエ

コード断片 

  | spaceUsedMax allSuperclassesMax selectorsMax collection basePitch instruments     chromaticScale soundCollection totalDuration offsetSecond droneVolume droneMakeBlock     droneL1 droneR1 droneL2 droneR2 droneL3 droneR3 score aMixedSound |  spaceUsedMax := 0.  allSuperclassesMax := 0.  selectorsMax := 0.  collection := OrderedCollection new: Metaclass allInstances size.  Cursor execute    showWhile: [SystemNavigation default        allBehaviorsDo: [:aClass | aClass isMeta            ifFalse: [| spaceUsed allSuperclasses selectors |              spaceUsed := aClass spaceUsed + aClass class spaceUsed.              allSuperclasses := aClass allSuperclasses size.              selectors := aClass selectors size + aClass class selectors size.              spaceUsedMax < spaceUsed                ifTrue: [spaceUsedMax := spaceUsed].              allSuperclassesMax < allSuperclasses                ifTrue: [allSuperclassesMax := allSuperclasses].              selectorsMax < selectors                ifTrue: [selectorsMax := selectors].              collection                add: (Array                    with: aClass name                    with: spaceUsed                    with: allSuperclasses                    with: selectors)]]].  basePitch := 'c4'.  instruments := (FMSound class organization listAtCategoryNamed: #instruments)        select: [:each | (each beginsWith: #random) not].  chromaticScale := ((AbstractSound chromaticPitchesFrom: basePitch)        copyFrom: 1        to: 13) reverse.  soundCollection := OrderedCollection new: collection size.  totalDuration := 0.  Cursor execute    showWhile: [collection        do: [:each |          | pitch duration loudness aSound |          pitch := chromaticScale at: (each at: 3)                  + 1.          duration := (each at: 2)                / spaceUsedMax * 15 max: 0.15.          totalDuration := totalDuration + duration.          loudness := (each at: 4)                / selectorsMax max: 0.346.          aSound := FMSound perform: instruments atRandom.          soundCollection            add: (aSound                soundForPitch: pitch                dur: duration                loudness: loudness)]].  offsetSecond := 12.  droneVolume := 268.  droneMakeBlock := [:restDuration :dronePitch :droneDuration :droneLoudness | Array        with: (Array with: #rest with: restDuration)        with: (Array            with: dronePitch            with: droneDuration            with: droneLoudness)].  droneL1 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: 0            value: #c3            value: totalDuration + offsetSecond            value: droneVolume).  droneR1 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: offsetSecond / 6            value: #'f#3'            value: totalDuration + offsetSecond            value: droneVolume).  droneL2 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: offsetSecond / 6 * 2            value: #bf3            value: totalDuration + offsetSecond            value: droneVolume).  droneR2 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: offsetSecond / 6 * 3            value: #e4            value: totalDuration + offsetSecond            value: droneVolume).  droneL3 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: offsetSecond / 6 * 4            value: #a4            value: totalDuration + offsetSecond            value: droneVolume).  droneR3 := FMSound        noteSequenceOn: FMSound organ1        from: (droneMakeBlock            value: offsetSecond / 6 * 5            value: #d5            value: totalDuration + offsetSecond            value: droneVolume).  soundCollection    addFirst: (RestSound dur: offsetSecond).  score := SequentialSound new.  soundCollection    do: [:each | score add: each].  aMixedSound := MixedSound new add: droneL1 pan: 0.1;         add: droneL2 pan: 0.25;         add: droneL3 pan: 0.4;         add: droneR3 pan: 0.6;         add: droneR2 pan: 0.75;         add: droneR1 pan: 0.9;         add: score pan: 0.5.  aMixedSound play.  ^ {score. soundCollection. collection. spaceUsedMax. allSuperclassesMax. selectorsMax}

まぁ,途中でいろいろ小細工してるけど,大目に見てちょ. FM 音源系なので三要素が必要なんだが,ダイレクトにテーブル組み立てて SampledSound を作ると,もっと面白くなるはず.

ついでに四重奏版も作ってみた.何かフリーっぽく聴こえて,けっこう笑える. playClassLibraryByQuartet.st.そうそう,こちらはこれ以上テンポラリ変数等作れない.作ってもコンパイルできない.フレーム・サイズぎりぎりです (笑).

最初の allBehaviorsDo: ブロック内で三要素からなる配列のコレクションを組み立てているんで,ここの取得先を変えれば他のモノが鳴らせる. Jun646 を入れた VWNC7.2 のクラス・ライブラリから音データを作ってみた.サンプリング・レート 22K,ビット・レート 64K とヘボヘボな音だが,サイズをデカくしてもしょうがないし,雰囲気は判る (笑).こちらの演奏時間 (?) は約 9 分半. VWNC72Jun646-64.mp3 (4.3MB).

0 件のコメント:

コメントを投稿