axjack's blog

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

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

Envでキックを作る

Envに慣れる

Envでエンベロープを作る。Envのargumentはlevelsの配列やtimesの配列、curveのシンボル、などを取る。timesを省略すると、1!(levelsの配列).size - 1がtimesに指定され、curveを省略すると\linが指定される。

なお、.plotを付けるとエンベロープカーブを見ることができる。

Env(levels:[0,1,0],times:[1,1]).plot;

Env(levels:[440,880,440,330,220],curve:-5).plot;

Env([0.0, 0.5, 0.0, 1.0, 0.9, 0.0], [0.5, 0.1, 0.01, 1.0, 1.5], -4).plot;

キックを作る

Envはamplitudeに掛けるのみと思っていたがそれのみにとどまらず、frequencyに掛ける(周波数変調)こともできる。

コード例

(
SynthDef(\wow,
    {
        |amp = 0.5|
        var lv_lists = [80,180,80,100,300,100];
        var num_lv = lv_lists.size;
        var e_times = 0.05;

        var f_env = Env.new(levels:lv_lists,times:(e_times!num_lv),curve:-1);
        var f_envgen = EnvGen.ar(f_env);
        var a_env = EnvGen.ar(Env.perc(0,e_times*num_lv),doneAction:2);

        var sig = SinOsc.ar(f_envgen,0,mul:amp) * a_env;
        Out.ar(0,sig!2);
    }).add;
)

//単音実行
Synth(\wow);

//Pbindで四分音符刻み
~aWow = Pbind(\instrument,\wow,\dur,1).play;

コード備忘録

f_envとf_envgenはfrequencyのエンベロープ、a_envはamplitudeのエンベロープ(パーカッシブのデフォルト)である。f_envはこのような形。

f:id:axjack:20171029230552p:plain

実行すると「一瞬ウニュってる」ような?キックが聞こえるはず。

参考

Env | SuperCollider 3.9dev Help

SC3 こーどりーでぃんぐ1 - sc3onlinuxの日記

Mixの使い方

Mix.fillのargumentsはnとfunction。このfunctionは(0..n-1)の値を取るカウンターを引数として受け取る。0から始まる点に注意。

なお、SC3だとMix.arFill == Mix.krFill == Mix.fillである。

コード例

(
var num = 5;
{Mix.fill(
    num,
    { arg i; 
        i.postln;//-> 0,1,2,3,4
        SinOsc.ar(500 * (2*i+1),0,1/num);
    }
)}.play;
)

参照

07. Mix it Up | SuperCollider 3.9dev Help

9. - SuperCollider 3.2 help files

MuseScoreでmp3出力する(macOS)

参照

メモ

32bit環境と64bit環境ではインストールするlibファイルが異なる。私のMacbookx86_64(uname -mなどで確認)なので、LAME Audio Encoder 3.99.5 — Thalictrumからlame-3.99.5.pkg.zipをダウンロードした。

ダウンロード→解凍→インストールすると、

/usr/local/bin/lame
/usr/local/lib/libmp3lame.dylib
...

なかんじでlameのbinやlibが配置される。

この作業後に、MuseScoreで譜面を開き[ファイル]>[エクスポート]>ファイルの種類をmp3と選択し実行すると、無事にmp3ファイルとして書き出すことができる。

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