2016年5月31日火曜日

ヘルプファイルの閲覧


SCのヘルプファイルは、関数などの説明が非常に充実しています。



調べたい部分を選択し、
Macならコマンド+d 、Windows環境ならF1で、
ヘルプウインドウに詳細や、実行例が表示されます。


インパルス オシレータ - Impulse

{ Impulse.ar([440, 440], 0, 0.2, 0) }.play

引数は他のオシレータと同じく、

ar(周波数、位相、掛ける値、足す値)

になります。

{Impulse.ar([440, 440], 0, 0.2, 0)}.plot




{Impulse.ar([440, 440], 0, 0.5, 0)}.scope




Band Limited ImPulse - Blip

帯域制限を用いたインパルス・ジェネレータ

Band Limited ImPulse

Blipについては次のWEBサイトが分かりやすく解説しています。



指定した倍音を重ねて出力する関数ですが、
ただ単純に重ねるのではなく、
ノイズになる無駄な部分をカットする処理を行っているようです。


{Blip.ar(440, 1, 1, 0)}.plot
440Hz で倍音を1つとして出力。



普通のサイン波です。

{Blip.ar(440, 2, 1, 0)}.plot
倍音を2つにしたときに、振幅がうまく調整されているのが分かります。


{Blip.ar(440, 3, 1, 0)}.plot



{Blip.ar(440, 5, 1, 0)}.plot




{Blip.ar(440, 10, 1, 0)}.plot



{Blip.ar(440, 100, 1, 0)}.plot



{Blip.ar(440, 200, 1, 0)}.plot




倍音の数が200ほどにもなると、
帯域制限が効いて、
それぞれの周波数の振幅が、
はっきりと調整されていることが分かります。


音源サンプル

{ Blip.ar([523.3/4, 523.3/4],Line.kr(1,100,20),0.2) }.play;


使いようで非常に面白い効果が期待できそうです。

2016年5月24日火曜日

サイン波 - SinOsc

サイン波の出力

SinOsc.ar( 周波数値, 位相, 積, 加)

MAXなら "cycle~"
PDなら "osc~"
といった関数と同じですね。

{[SinOsc.ar(440, 0, 1, 0)]}.plot


美しい波形です。


実行例:
{var x = 440;
[
  SinOsc.ar(x, 0, 1, 0),
  SinOsc.ar(x*5/3, 0, 1, 0)
]}.play


左chから440Hzのサイン波、
右chから440*5/3Hzのサイン波が出力されます。


のこぎり波 - LFSaw

音を作っていく上で重要なパーツの1つ

LFSaw(周波数, 位相, 積, 加)

{LFSaw.ar(440, 0, 1, 0)}.plot


プロットで見れば分かるように、
−1から1に向けて直線的に上昇したのち、
1から−1に値が変わって、再び上昇・・・
の繰り返しです。

「ファミコン音源みたいな」音が発音されます。

実行例:
{[LFSaw.ar(440, 0, 0.25, 0),LFSaw.ar(520, 0, 0.25, 0)]}.play
{[LFSaw.ar(440, 0, 0.25, 0),LFSaw.ar(660, 0, 0.25, 0)]}.play
{[LFSaw.ar(XLine.ar(440*10, 1.0, 10), 0, 0.25, 0), LFSaw.ar(XLine.ar(440*10, 1.0, 10), 0, 0.25, 0)]}.play
{[LFSaw.ar(220, 0, 0.25, 0),LFSaw.ar(220, 0, 0.25, 0)]}.play

※タイマー使って、順番に実行するようにしたら綺麗なんだろうけれど、
各音源を手動で順番に実行しています・・・。






実行例:
{ [
  LFSaw.ar(LFSaw.kr(4, 0, 200, 400), 0, 0.1) ,
  LFSaw.ar(LFSaw.kr(4, 0, 200, 400), 0, 0.1)
] }.play



LFOを用いた音源です。
ソース中のkrとarの違いは別の投稿にて。



また、この音源では、途中で右チャンネルの位相を逆転させています。
{ [
  LFSaw.ar(LFSaw.kr(4, 0, 200, 400), 0, 0.1) ,
  LFSaw.ar(LFSaw.kr(4, 0, 200, 400), 1, 0.1)
] }.play


位相のズレの音への影響などが、参考になればと思います。

ノイズ生成 - LFNoise2

LFNoise2(freq, mul, add)


SCのExampleを順に実行した音源が上になります。
(LFNoise0から続けて編集するのがしんどかったので、左チャンネルのみからのままにしています。)

LFNoise0、LFNoise1との違いは、
こちらもプロットをみればはっきりすると思います。

{[LFNoise0.ar(800, 0.75, 0),
LFNoise1.ar(800, 0.75, 0),
LFNoise2.ar(800, 0.75, 0)
]
}.plot



LFNoise0 が矩形的な変化
LFNoise1 が値の間を線形に補完
LFNoise2 が値の間を曲線的に補完(なめらか)

となっています。

うまく活用していくことで、
LFNoise1とは違った美しさが表現出来ると思います。

ノイズ生成 - LFNoise1

LFNoise1(freq, mul, add)



上の音源は次のコードを実行したものです。

{
  [LFNoise1.ar(800, 0.75, 0), LFNoise1.ar(400, 0.75, 0)]
}.play

左右のfreqを変えたり、少しいじっていますが、
先にあげたLFNoise0との違いが感じにくいと思います。

しかし、プロットで見るとその違いがとてもわかりやすいです。

{[LFNoise0.ar(800, 0.75, 0),
LFNoise1.ar(800, 0.75, 0)]
}.plot


上のプロットが LFNoise0
下のプロットが LFNoise1
です。

LFNoise1は値と値の間を補完しているのがわかります。
SinOscの引数にすると、音としてもその違いがはっきりとわかります。




{ [
 SinOsc.ar(LFNoise0.ar(4, 400, 450),0, 0.5),
 SinOsc.ar(LFNoise1.ar(4, 400, 450),0, 0.5)
] }.play;

左チャンネルがLFNoise0を引数に与えたSinOsc
右チャンネルがLFNoise1を引数に与えたSinOsc

左が階段状にピッチが変わるのにくらべて、
右チャンネルは、線形にピッチが変わっていると思います。

ノイズ生成 - LFNoise0

LFNoise0(freq, mul, add)

ノイズ生成にいくつかのUGenがあり、
そのひとつがLFNoise0になります。

実行例:
{[LFNoise0.ar(1000, 0.75, 0)]}.plot



SampleRateを引数に与えたFreqで割った値をもとに、
乱数を生成するようです。

実行例1:



{
  [LFNoise0.ar(500, 1, 0),
    LFNoise0.ar(500, 1, 0)]
}.play

上のSoundCloudの埋め込みは、
左チャンネル右チャンネルともに、
500Hzのノイズを発生させたものです。

実行例2:
{ LFNoise0.ar(XLine.kr(1000, 10000, 10), 0.25) }.play;



Frequencyの部分にXLineをもちいることで、
引数になる周波数を上げてやると、
上の音源のように変化していきます。
(左チャンネルからのみです)

実行例3:
{
[SinOsc.ar(LFNoise0.ar(4, 400, 450),0, 0.5),
  SinOsc.ar(LFNoise0.ar(XLine.kr(1, 10, 10), 400, 10),0, 0.5)]
}.play;

リファレンスにあるStepNoiseについては、
Exampleのコードを実行するとわかりやすいと思います。

Exampleのコードを少し編集したのがこちらの音源です。
他のLFNoiseと比較してみてください。


値のソート - sort

sort(並び替える値の配列) 




■実行例:乱数を昇順にソートして返す
sort({100.rand}!10)

■実行結果例:
[ 19, 26, 43, 48, 61, 62, 80, 81, 82, 95 ]

値を四捨五入 - round

round(四捨五入する値, 小数点以下)




■実行例(1):
round(0.005, 0.01)

■結果:
0.01


■実行例(2):
round(0.004, 0.01)

■結果:
0


■実行例(3):
round({100.00000.rand}!10, 0.01)

■結果
[ 51.4, 44.53, 6.7, 73.4, 44.35, 9.48, 37.11, 70.66, 34.89, 6.89 ]



同じ計算を繰り返す - dup

dup(繰り返す内容, 繰り返す回数)

繰り返す内容が、配列となって、指定した回数分返ってきます。




例:文字列を10回出力

dup("test", 10);

実行結果:
[ test, test, test, test, test, test, test, test, test, test ]


例:rand関数を実行

dup(rand(100), 10)

実行結果:
[ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 ]

別の値が10回返ってくると思いきや、
同じ値が10回返ってきます。

[ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41 ]
[ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79 ]
[ 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 ]
[ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 ]
[ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26 ]
[ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ]
[ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 ]
[ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 ]

おそらく、乱数を生成するのに使う、Seed値が同じまま、
繰り返し実行されているのではないかな、と思います。

→ 『rand()で生成された値』を、『10回出力』しているようです。

回避策:
dup({rand(100)}, 10)

このように、rand関数を{ } でかこむと回避できます。
→ { } でかこむことで関数扱いになり、
『rand()』を『10回出力』することになるようです。

実行結果例:
[ 83, 14, 86, 31, 15, 72, 76, 57, 42, 66 ]
[ 75, 62, 10, 38, 0, 95, 90, 38, 1, 46 ]
[ 92, 98, 47, 20, 96, 9, 85, 93, 13, 62 ]
[ 47, 93, 77, 32, 26, 77, 92, 16, 96, 9 ]
[ 38, 95, 27, 49, 77, 88, 35, 5, 56, 66 ]
[ 50, 64, 67, 50, 86, 7, 40, 90, 85, 61 ]
[ 53, 83, 67, 36, 93, 78, 59, 41, 93, 93 ]
[ 76, 70, 54, 78, 57, 68, 1, 34, 76, 38 ]
[ 58, 42, 35, 2, 29, 58, 52, 86, 35, 68 ]
[ 19, 86, 0, 85, 6, 81, 2, 61, 96, 99 ]
[ 12, 31, 16, 54, 80, 48, 27, 5, 94, 66 ]
[ 12, 51, 43, 20, 82, 58, 9, 49, 45, 45 ]
[ 31, 72, 21, 57, 98, 32, 50, 20, 9, 62 ]


!を使っての繰り返し

"TEST" ! 10;
rand(10) ! 10;
{rand(10)} ! 10;

繰り返す作業の後に!をつけて繰り返す回数を与えると、
dupと同じ結果が返ってきます。

それぞれの実行結果は下になります。

[ TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST, TEST ]
[ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ]
[ 9, 6, 9, 1, 9, 0, 6, 4, 9, 1 ]


指数分布を用いた乱数生成 - exprand

exprand(1.0, 100.0)
引数に与えた小さい値に偏りを持つ値を返します。



rand 関数と違う点として、exprand関数では、
この場合の引数だと、1から10までの値と、
10から100までの値がでる確率が同じになります。


■実行結果例

47.656370272524
43.80190417783
1.2091068107496
5.9676588085445
1.7298887475711
2.2762870707028
79.104229877935
4.6093322577873
1.6666314335012
31.07596776077
5.7769098624727
1.4709877119437
33.460263807101
6.3403401862268
53.762953958958

2016年5月23日月曜日

乱数生成 - rand

乱数生成

rand(100)

int での乱数生成



■実行例

99
27
57
27
36
85
87
42
2
77
87
35
84
82

rand(100.0)

float での乱数生成

■実行例
24.290478229523
28.832364082336
31.247639656067
60.463559627533
86.959481239319
76.355004310608
45.971369743347
36.063897609711
35.087251663208
32.206809520721
6.2441468238831
66.770470142365
2.1321415901184
24.255168437958


rand(-100)

負の値 での乱数生成

■実行例

-14
-9
-10
-67
-15
-68
-61
-60
-16
-60
-20
-76
-66
-12
-56

rand(-0.01)

負の値 でのfloat の乱数生成

■実行例
-0.002821854352951
-0.0045204067230225
-0.0043455028533936
-0.0040916311740875
-0.0013518214225769
-0.0044581925868988
-0.00046616315841675
-0.0093869364261627
-0.0093834805488586
-0.002179092168808
-0.0015838646888733
-0.00074442505836487
-0.0069698321819305
-0.003640388250351
-0.0031287336349487



100.rand
100.1.rand

こういった呼び出し方も可能です。

"Hello World" の実行 - PostWindow

あらゆる言語で最初に行うことは、
コンソールに"Hello World"やら、
なんやらの文字を出力することだと思います。

Super Colliderでも同じことをやっておきます。

エディタに、








"Hello World" と入力し、
実行(Mac なら Shift + Enter、Win ならCtrl + Enter)します。

するとPost Window 側に
Hello World と出力されます。
簡単ですね。



また、サーバーを起動しておけば、
"文字列".speakでしゃべってくれます。
(Macにて確認)

実行例:
"Hello World".speak

localhost の起動 - server

SC でエディターに入力した内容を出力するだけなら、
サーバーの起動は必要ありませんが、
「音」を出力するには、
Serverの起動が必要になります。

以前のバージョンでは、
Localhost Server と Internal Server というウインドウがあり、
Localhost Server で受け取った値を、
Internal Server が出力する... といった流れだったと思うのですが、

バージョンが3.6に上がり、
画面上(右下)にあるのは、
Interpreter と Server のステータスとなりました。




上の写真では、Inactive となっています。

Super Colliderを起動した直後は、
私の環境では、自動的に Interpreter が起動するようです。


しかし、Server が起動していないために、
この状態では音を発音することができません。

以前のバージョンでは、

Server.internal.boot
Server.local.boot

といったコマンドを実行して、
サーバーを起動する必要があったのですが、

3.6系では、コマンド + B で(localhost)を起動することができます。
簡単です。


InterpreterもServerもActiveになっています。

この状態でエディターに

{SinOsc.ar(440)}.play

と入力し、Shift + Enter ( Winなら Ctrl + Enter )とすると、
音が出力されます。

音をとめるコマンドを入力しないと、
延々と音が流れるので、

Cmd + .(ピリオド)、
Winなら Atl + . (ピリオド)でサウンドをとめることができます。


サーバーの起動に失敗する場合 

server failed to start


サーバーの起動に失敗することが環境によってあると思います。
私は失敗しました。

PostWindowには、

http://supercollider.sourceforge.net/wiki/index.php/ERROR:_server_failed_to_start

を参考にというメッセージが出て、
ページをみると、
終了されてないSCSynthのタスクがいたら、
そのタスクを終了するようにとあります。


色々原因があると思います、が、
自分の場合は、使っているUSB Audioデバイスのサンプリングレートの問題でした。






入力・出力ともに、44.1Khz に変更すると、
無事サーバーの起動に成功しました。

Mac なら、「Audio MIDI 設定」での変更になります。