gateを0にしてreleaseする
Envelopeにてgate=0でreleaseを作動させるには、SynthDefのargにgateを設定し、なおかつEnvGenにgateを渡す必要がある。これを怠ると、当然ながら.set(\gate,0)
と実行しても音は止まない。
doneAction:2
と設定していると、gateを0にしreleaseが終わったタイミングで、実行したSynthがGroupeから消える。なので、再び実行するときはSynthをServerにnewなりnewPausedなりする必要がある。
gate
This triggers the envelope and holds it open while > 0. If the Env is fixed-length (e.g. Env.linen, Env.perc), the gate argument is used as a simple trigger. If it is an sustaining envelope (e.g. Env.adsr, Env.asr), the envelope is held open until the gate becomes 0, at which point is released. If gate < 0, force release with time -1.0 - gate. See EnvGen: Forced%20release example.
作ったコード
(s.meter(0,2); s.plotTree; ) (SynthDef(\tri, {|out=0,gate=1,amp=0.1,freq=440| var sig,e,eg; e = Env.adsr(attackTime:1,decayTime:3,sustainLevel:0.5,releaseTime:3,peakLevel:1,curve:-8); eg = EnvGen.kr(e,gate,amp,0,1,2); sig = LFTri.ar(freq); sig = sig * eg; Out.ar(out,sig); } ).add; ) ~x = Synth(\tri,[\freq,500]); ~x.set(\gate,0);
参考
Busの練習
Busを介して音を出す、はずであった。作ったコードのoBus
やiBus
でそれらしいことをしたつもりである。しかし、どちらかというと
//use one bus ( ~b1 = Bus.audio(s,1); {Out.ar(0,In.ar(~b1,1))}.play; {Out.ar(~b1,SinOsc.ar(440))}.play; ) //use two busses ( ~b1 = Bus.audio(s,1); ~b2 = Bus.audio(s,1); {Out.ar(0,In.ar(~b1,1))}.play; {Out.ar(~b1,In.ar(~b2,1))}.play; {Out.ar(~b2,LFTri.ar(440))}.play; )
と明示的にBusを作った方が良かったと最後になって気付いた。
メモ
Synth.newPaused
で一時停止した状態のSynthを作ることが出来る。~x = Synth.newPaused(...)
を実行した後に~x.run
と実行すると再生することが出来る。Synth.after(aNode,defName)
でaNodeの後ろにSynthを作ることが出来る。source -> effect
のような流れを作る場合に使う。左右の信号に掛けるLFOの位相をそれぞれ変え(例:左は0, 右はpi/2)ておくと、位相のズレを体感することが出来る(論より証拠)。
作ったコード
s.meter(0,2); s.plotTree; //Triangle Osc ( SynthDef(\tri,{ |freq = 440,oBus = 10| var out,sig; sig = Mix.fill(4,{|i|LFTri.ar(freq/(1+i),0,1/4)}); out = sig; Out.ar(oBus,out); }).add; ) //Effector ( SynthDef(\eff,{ |iBus = 10,afreq=1| var in,in_r,in_l; in = In.ar(iBus); in_r = in * SinOsc.kr(afreq,0,0.2,0.4); in_l = in * SinOsc.kr(afreq,pi/2,0.2,0.4); Out.ar(0,[in_r,in_l]); }).add; ) //kick ( SynthDef(\kick,{ var env = EnvGen.ar(Env(levels:[100,200,60,0],times:[0.01,0.2,0.2,0.2],curve:-10)); var sig = SinOsc.ar(env,0,1,0) + WhiteNoise.ar(0.01); sig = sig * EnvGen.ar(Env.perc(attackTime:0,releaseTime:0.3),doneAction:2); Out.ar(0,sig!2); }).add; ) //Synth ( ~tri = Synth.newPaused(\tri,[\freq,200]); //~eff = Synth(\eff); ~eff = Synth.after(~tri,\eff); ) //run Synth ~tri.run; //Routine ( ~r = Routine({ var n = 10; loop{ n.do({|i| ~eff.set(\afreq,(i+1)); (i+1).postln; 4.wait; }); } }); ~rk = r({loop{Synth(\kick);1.wait;}}); ) ( ~rk.play(); ~r.play(); )
参考
Bus | SuperCollider 3.9dev Help
授業料無償化と発言したのは本当なのだろうか?
授業料無償化?
Twitterが授業料無償化(教育費無償化)で有象無象のごった煮となっていたので、ソースなどを辿る旅に出た記録。
According to NHK
大学在学中は授業料無償化 自民が検討案まとめる | NHKニュース
NHKニュースサイトの動画を見たが、ニュースキャスターの声が大きすぎて自民党教育再生実行本部?の生の声が聞こえなかった。果たして本当に「無償化」と発言したのだろうか?
教育再生実行本部
教育再生実行本部 第八次提言 | 政策 | ニュース | 自由民主党
教育再生実行本部の提言は、サイトを確認すると第八提言(2017年5月18日)は存在するものの(おそらく今回に相当する)第九提言はまだ存在しない。「無償化」発言のエビデンスを追うにはもう少し時間を待つ必要があるかもしれない。
自民党の政策パンフレット
「無償化」では無いが「卒業後拠出金方式」という単語は自民党の政策BANK2017のp.32に記述がある。オーストラリアのHECSを参考にした仕組みらしい。
ベネッセ
直接は関係ないが教育費無償化については、ベネッセのコラムが分かりやすかった。
考えたこと
完全無償化となると財源どうするの?となるし、卒業後拠出金方式だとすると大学の経営不安定になるような気がする。
いずれにしても現状維持より良い選択肢・現状維持より魅力的な解決策には見えないのが残念である。
全然関係ない余談
はてなブログのmarkdownモードにおいて、リンクを挿入する際[URL:title]
だとtitleが自動挿入される。
がしかし、URL参照先がpdfだとtitleを取得してくれないようである。
なので手動でタイトルを打ち込む必要がある。その方法は以下の2つである。
[URL:title=タイトル]
[タイトル](URL)
換気扇の音を作りたい
どうも音が籠もってしまう。かといってハイパスだとシャリシャリ感が邪魔である。 目的の音とは違うが、waveの音は冷蔵庫から鳴る低音に近い。
コード
( SynthDef(\kanki, { |cfreq = 388,amp=0.4| var noise,wave,out; noise = RLPF.ar(BrownNoise.ar(0.5),cfreq,0.5); wave = RLPF.ar(Saw.ar(cfreq/8,0.5),cfreq,0.3); out = noise + wave; Out.ar(0,Pan2.ar(out,0,amp)); }).add; ) ~x = Synth(\kanki);
PseqにasStreamを付けるとRoutineになる
Pseqに限らずPrandとかPbrownでも.asStream
付けるとRoutineになる。PatternをRoutineの中で使うときに重宝する、のだろうか?
なお、Patternに加えてEnvも.asStream
付けてRoutine化することが可能。
コード
///////////////////////////////// //Routine ( ~r = Routine( { 2.do({ 12.yield; 34.yield; 56.yield; }); }); ) ~r.reset; ( { 7.do({ ~r.next.postln; 1.wait; }); }.fork ) ///////////////////////////////// //Pseq ~p = Pseq([12,34,56],2).asStream; ~p.reset; ( { 7.do({ ~p.next.postln; 1.wait; }); }.fork )
参考
Pseq | SuperCollider 3.9dev Help
Ptparでカエルの歌を輪唱する
TaskかRoutineを用いて書いてみたかったけれども、思いつかなかったのでPtpar
を用いて書いてみた。
いつか「カエルの歌 無限輪唱」を書きたい。
PtparとPpar
Ptpar
はtime offset付きでparalell実行するPatternPpar
はtime offset無しでparalell実行するPattern
コード
//カエルの歌 //////////////////////////////////// ( var melody = [ 60,62,64,65,64,62,60, 64,65,67,69,67,65,64, 60,60,60,60, 60,60,62,62,64,64,65,65, 64,62,60]; var dur = [ 1,1,1,1,1,1,2, 1,1,1,1,1,1,2, 2,2,2,2, 0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5, 1,1,2]; var song = Pbind( \midinote,Pseq(melody,1), \dur,Pseq(dur,1), ); var tempo = TempoClock(120/60); /* Ptpar embed event streams in parallel, with time offset Arguments: list list of pairs of times and patterns: [time, pat, time, pat .. ]. repeats repeat the whole pattern n times. */ Ptpar([0,song,8,song,16,song],1).play(tempo); ) ////////////////////////////////////
参考
TaskやRoutineで時間制御する
TaskとRoutine
.wait
を使って時間を制御したい場合、TaskやRoutineを使う。Taskの特徴は一時停止・再開できること。一方Routineの特徴は、一時停止・再開は出来ないが.yield
が使えることである。ということで、Task・Routineで使えそうに見えるメッセージについて比較した。
TaskとRoutineの比較
メッセージ\ | Task | Routine |
---|---|---|
.play | 使える | 使える |
.start | 使える | ERROR |
.resume | 使える | .nextと同じ |
.pause | 使える(.stopと同じ) | ERROR |
.stop | 使える(.pauseと同じ) | 使える |
.reset | 使える | 使える |
.next | nil | 使える |
.value | nil | .nextと同じ |
TaskとRoutineの使い分け
Task | SuperCollider 3.9dev Helpによると、
Tasks are not 100% interchangeable with Routines. Condition does not work properly inside of a Task. Stopping a task and restarting it quickly may yield surprising results (see example below), but this is necessary to prevent tasks from becoming unstable if they are started and/or stopped in rapid succession.
また
As a result, Task should be used for processes that need to start and stop relatively infrequently, but for which maximum stability is required. If you need fine-grained control over when and how the process stops and resumes (as is the case, for instance, with condition), Routine is preferred.
とある。内部でコンディションを持つならRoutineがおすすめ、ということだと思われる。
ところでforkは?
forkは
Returns a Routine using the receiver as it's function, and plays it in a TempoClock.
である。and plays it in a TempoClockがポイントで、forkは実行すると即座にplayされてしまう、すなわちあとから実行・途中で止めることが出来ない。
コード確認
//Task ( t = Task({ inf.do({|i| ("Task" + i).postln; 1.wait; }); }); ) //Routine ( r = Routine({ inf.do({|i| ("Routine" + i).postln; 1.wait; }); }); ) //Task t.play; t.start; t.resume; t.pause; t.stop; t.reset; t.next;//nil t.value;//nil //Routine r.play; r.start;//ERROR: Message 'start' not understood. r.resume; r.pause;//ERROR: Message 'pause' not understood. r.stop; r.reset; r.next; r.value; //fork /* Returns a Routine using the receiver as it's function, and plays it in a TempoClock. */ ( f = fork({ inf.do({|i| ("fork" + i).postln; 1.wait; }); }); )
参考
Task | SuperCollider 3.9dev Help
Envでキックとハイハットを作る
昨日の復習がてら、キックとハイハットを作る。カーブの値(curve:-10)
)をいじると音が結構変わるもんだ。どうやったらセンスや勘所を掴めるのだろう・・・。
コード
//キック ( SynthDef(\kick,{ var env = EnvGen.ar(Env(levels:[100,200,60,0],times:[0.01,0.2,0.2,0.2],curve:-10)); var sig = SinOsc.ar(env,0,1,0) + WhiteNoise.ar(0.01); sig = sig * EnvGen.ar(Env.perc(attackTime:0,releaseTime:0.3),doneAction:2); Out.ar(0,sig!2); }).play ) //ハイハット ( SynthDef(\hi,{ var sig = PinkNoise.ar(0.1); sig = sig * EnvGen.ar(Env.perc(attackTime:0,releaseTime:0.1),doneAction:2); Out.ar(0,Pan2.ar(sig,SinOsc.kr(0.3))); } ).play; ) //とりあえず同時に鳴らす ( Pbind(\instrument,\kick,\dur,Pseq([1,1,1,1/2,1/4,1/4],inf)).play(TempoClock(144/60)); Pbind(\instrument,\hi,\dur,1/4).play(TempoClock(144/60)); )