[sc] Pattern, Streamなど

引き続きscのお勉強中。
楽しく音を鳴らすのが目下の目標。
いや、音はなるんです既に。
今だとサイン波が延々となるばかりなのでアレです。
そうじゃなくてメロディを作りたい訳です。
ということで調べてみたらPatternだとかStreamだとか、その辺を使うっぽいことがわかりました。


とりあえずなんじゃそりゃということでドキュメントを参照。

The SuperCollider Pattern library provides a means of specifying dynamic structural transformations of musical processes. It provides similar capabilities as one finds in Nyquist, Elody, Siren, Kyma, HMSL, DMix, and Patchwork.

音響処理のためのダイナミックな構造変化のための機構、ってとこでしょうか。
Nyquistとかそういうのは似たような言語やツールみたいなもんですかね。

つらつら読んでいくと、どうやらStreamというのはPythonで言うジェネレータに近いんじゃないかという気がしてきました。
Routineなんか特に、yieldで値返す訳ですし。
というか書いてありますね↓

More about Streams can be learned from the book A Little Smalltalk by Timothy Budd. He calls them Generators and shows how they can be used to solve problems like the “eight queens” problem etc.

book A Little SmalltalkでもっとStreamに関して学べるそうですが、それが何かは知りません。
またそれの中で著者はStreamをジェネレータと読んでいるそうなので、やはり普段ジェネレータと思って使っているものがStreamの正体っぽいですね。

つまりこれを音のfreqencyとかamplitudeとかに突っ込んで音を変えるってことなんでしょう。
となるとその値を任意のオブジェクトに対して、時間にそって適用するための仕組みなんかが必要そうです。

また、StreamはStreamオブジェクト自体で足し算引き算などが出来るらしいです。
こんな具合に。

(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
  10.do({ arg i; i.yield; })
});
b = a + 100; // add a constant value to stream a
12.do({ b.next.postln; });
)

結果は

100
101
102
103
104
105
106
107
108
109
nil
nil

となりました。わかりやすい。
Pythonでも似たことは出来そうですね。新しいジェネレータのインスタンスを返してやれば良い訳なので。

あとはフィルタを掛けて返り値をコントロールするだとかも可能なようです。

(
var a, b;
// a is a stream that counts from 0 to 9
a = Routine.new({
  10.do({ arg i; i.yield; })
});
// b is a stream that only returns the odd values from stream a
b = a.select({ arg item; item.odd; });
6.do({ b.next.postln; });
)

ページの一番下に音を鳴らすサンプルコードがついてましたが、僕の環境では鳴りませんでした。なぜ。。

あと:(コロン)演算子の意味もよくわかりません。なんだこれは。

んー、、、音をならすという目的によって、またSmalltalkやらLispやらRubyやらに影響されている分(というか多分作者が言語マニアなんでしょうけど)、全然わからない概念がたくさん入っているように思います。

てかリファレンスがよくわからない。
もうちょっと整備してほしいけどまぁ慣れの問題かなー。

サンプルコード、鳴らなかったけど大枠はわかったからOK。
やっぱりさっきの考察通り、Streamからの戻り値をSynthに突っ込んでるっぽい。
これだと毎回Synthのインスタンス作ってるっぽいけど、これでいいのかな?

まぁこの辺は追々なんかあるでしょう。

で、次のページでPattern登場。

Often one wants to be able to create multiple streams from a single stream specification. Patterns are just a way to make multiple Streams from a single specification, like a cookie cutter. A pattern can be any object that responds to the asStream message by creating a Stream. Once again there is a default implementation in class Object of asStream that simply returns the receiver as its own stream. Thus any object is by default a pattern that returns itself as a stream when sent the asStream message.

なるほど、PatternはStreamを作るための定義、ということで良いようです。
like a cookie cutterってのは、クッキー作る時の星とかハートとかの型抜きってことですかね。
asStreamメッセージを送ることでStreamを作成することが可能なようです。

Pxxxxみたいな、Pなんとかって名前がPatternみたいです。
Routine返したりとかクラスによってアレコレあるみたいですね。

って思ったより巨大な言語だなSC。。。
もっと音響合成に特化してて簡単だと思ってたおれが馬鹿だった、、、

PatternもStreamよろしく合成したりとか出来るっぽい。

(
var a, b, c;
// a is a pattern whose stream counts from 0 to 9
a = Pseries.new(0,1,10);
b = a + 100; // add a constant value to pattern a
c = b.asStream;
12.do({ c.next.postln; });
)

Streamを作る前、もう1個上のレベルでの合成が可能となるとそれはそれで使い出がありそうです。

同様にフィルタリングも可能なようですが、Streamと違ってインスタンス同士を足すことは出来ませんでした。
そこはStreamにしてからやれってことなのかな。
ここまで一緒ならやれても良いだろうに、と思うのは僕だけ?
まぁやる意味がないだけなのかもしれないので、それはそれで。

と思ったら一番下のサンプルコードでPatternからStream引いてる。なんぞこれ。

サンプルコードが突然複雑でよくわからん。
というかPattern以前によくわからんメソッドが多いな。。
なのでとりあえずスルー。感じつかめたのでOK。

その3はListから作るPatternに関して。
PseqとかPshufとかPrandとか。
関数とかだけがPatternに登録出来るものじゃないのね。
Pseqなんかは実際よく見かけるので頻繁に使うものなんでしょう。
使いやすいよな確かに。
Pseq要チェック。

このページのサンプルは、PrandやPseqを入れ子にしている。
1個のPatternの再生が終わったら次のPatternに移る。
うーん、面白いなこれは。そして便利。要チェック。

次のページからはEnvironmentとEventの話になるようなので、今回はこの辺で。

ちなみにサンプルコード見てて気づいたのですがというか当然ですが、音が鳴りっぱなしなのはエンベロープつけてないからでした。
まぁそりゃそうだよね。。。
ということでこれも追々。
あと継続的なシーケンスの操作というか、曲として成り立たせるための手法もちゃんと見ておかんとイカンなと思いました。
これも追々。

うおおお楽しいぜSC。
でもまだ何も作れてないのが悔しい。
まぁ追々。←全部それか

気長に頑張ります。

コメントを残す

メールアドレスが公開されることはありません。