axjack's blog

### axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz ###

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);

参考

Env | SuperCollider 3.9dev Help

Busの練習

Busを介して音を出す、はずであった。作ったコードのoBusiBusでそれらしいことをしたつもりである。しかし、どちらかというと

//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

Order of execution | SuperCollider 3.9dev Help

Synth | SuperCollider 3.9dev Help

授業料無償化と発言したのは本当なのだろうか?

授業料無償化?

Twitterが授業料無償化(教育費無償化)で有象無象のごった煮となっていたので、ソースなどを辿る旅に出た記録。

According to NHK

大学在学中は授業料無償化 自民が検討案まとめる | NHKニュース

NHKニュースサイトの動画を見たが、ニュースキャスターの声が大きすぎて自民党教育再生実行本部?の生の声が聞こえなかった。果たして本当に「無償化」と発言したのだろうか?

教育再生実行本部

教育再生実行本部 第八次提言 | 政策 | ニュース | 自由民主党

教育再生実行本部の提言は、サイトを確認すると第八提言(2017年5月18日)は存在するものの(おそらく今回に相当する)第九提言はまだ存在しない。「無償化」発言のエビデンスを追うにはもう少し時間を待つ必要があるかもしれない。

自民党の政策パンフレット

政策BANK2017

「無償化」では無いが「卒業後拠出金方式」という単語は自民党の政策BANK2017のp.32に記述がある。オーストラリアのHECSを参考にした仕組みらしい。

ベネッセ

教育費負担をどう考えるか|ベネッセ 教育情報サイト

直接は関係ないが教育費無償化については、ベネッセのコラムが分かりやすかった。

考えたこと

完全無償化となると財源どうするの?となるし、卒業後拠出金方式だとすると大学の経営不安定になるような気がする。

いずれにしても現状維持より良い選択肢・現状維持より魅力的な解決策には見えないのが残念である。

全然関係ない余談

はてなブログmarkdownモードにおいて、リンクを挿入する際[URL:title]だとtitleが自動挿入される。

がしかし、URL参照先がpdfだとtitleを取得してくれないようである。

なので手動でタイトルを打ち込む必要がある。その方法は以下の2つである。

  • [URL:title=タイトル]
  • [タイトル](URL)

上ははてな専用の書き方で、下は一般的なmarkdownの書き方である。pdfのリンク張るときは少し注意。

換気扇の音を作りたい

どうも音が籠もってしまう。かといってハイパスだとシャリシャリ感が邪魔である。 目的の音とは違うが、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

http://doc.sccode.org/Classes/Pattern.html#-asStream

http://doc.sccode.org/Classes/Env.html#-asStream

Ptparでカエルの歌を輪唱する

TaskかRoutineを用いて書いてみたかったけれども、思いつかなかったのでPtparを用いて書いてみた。 いつか「カエルの歌 無限輪唱」を書きたい。

PtparとPpar

  • Ptparはtime offset付きでparalell実行するPattern
  • Pparは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);

)
////////////////////////////////////

参考

Ptpar | SuperCollider 3.9dev Help

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

Routine | SuperCollider 3.9dev Help

Function | 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));
)
axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz.