Events 超级对撞机:具有包络线的事件中的自动维持

Events 超级对撞机:具有包络线的事件中的自动维持,events,envelope,supercollider,Events,Envelope,Supercollider,在SynthDef之后执行第一行和第二行将创建一个永远播放的synth,而第三行的synth按照生成的事件的默认值播放0.8秒 问题是,我在SynthDef中的任何地方都没有使用“sustain”,它会自动使用,只是因为有一张亚麻布 对于freq,同样的情况不会发生:两个事件都在440播放,而不是在220播放,这只是因为SynthDef没有使用'freq'作为参数。那么为什么sustain不遵循同样的规则呢 还有,有没有一种方法可以引用由事件创建的Synth?这样,当它们有sustain:inf

在SynthDef之后执行第一行和第二行将创建一个永远播放的synth,而第三行的synth按照生成的事件的默认值播放0.8秒

问题是,我在SynthDef中的任何地方都没有使用“sustain”,它会自动使用,只是因为有一张亚麻布

对于freq,同样的情况不会发生:两个事件都在440播放,而不是在220播放,这只是因为SynthDef没有使用'freq'作为参数。那么为什么sustain不遵循同样的规则呢

还有,有没有一种方法可以引用由事件创建的Synth?这样,当它们有
sustain:inf
作为参数时,我可以稍后释放它们

( 

SynthDef(\testEvt,{
    arg out, gate = 1;
    var sint = Blip.ar(440) * Linen.kr(gate,doneAction:2,releaseTime:0.8);
Out.ar(out, Pan2.ar(sint, 0));
}).add();

Synth(\testEvt) 
(instrument: \testEvt, freq:220, sustain: inf).play;
(instrument: \testEvt,freq:220).play;

)

这些都是事件。事件为你处理很多事情。他们做的一件事是计算何时将闸门设置为0。(请记住,gate是SynthDef中的参数之一。)在第一个示例中,由于持续时间是无限的,所以gate永远不会归零。在第二个示例中,它使用默认的持续时间,并在该持续时间过后将gate设置为零。通过查看event.sc源文件,可以了解事件环境变量中使用了哪些关键字。如果你搜索sustain,你会发现它用于计时的其他关键字。其中之一是杜尔。试试这个:

(instrument: \testEvt,freq:220).play;
Freq也是事件的关键字,但由于没有Freq参数,它不会影响synthDef。如果要设置频率,则需要进行更改:

(instrument: \testEvt, dur:3).play
要查看事件和直接控制synth之间的对比,请尝试: a=Synth.new(\testEvt,[\out,0,\gate,1]) 您可以添加任何其他想要的参数,如freq或sustain,但它们没有效果,因为这些不是synthdef的参数。而且,与Event不同,synth不代表您进行任何计算。当您希望便笺结束时,请自己将gate设置为0: a、 设置(\gate,0)


了解事件环境变量很好,因为PBIND也使用它们,通过使用它们,您可以影响其他事情。如果您的synthdef使用sustain作为其他内容的参数,您可能会惊讶于它更改了您的持续时间。

关于您的最后一个子问题

还有,有没有一种方法可以引用由事件创建的Synth?这样,当它们有
sustain:inf
作为参数时,我可以稍后释放它们

是,通过
\id
键“索引”
事件。这实际上返回一个节点ID数组,因为带有
\strum
的事件可以触发多个节点/synth。此外,事件未播放时,
\id
值为
nil
。但是这种索引方法对于您想要的内容来说是相当不必要的,因为

您可以通过使用
release
提前结束
事件来结束(关联的)synth,就像对
synth
本身一样。这基本上是关闭了它的内部合成器。(在您的示例中,此
release
调用通过将
gate
降低到0,转换到
Linen
生成的ASR信封的释放点。)。当然,如果您不打算在程序中立即发布synth和/或事件(使用选通封套不会产生声音),请使用变量保存对synth和/或事件的“引用”

基本上

SynthDef(\testEvt,{
    arg out, gate = 1, freq = 440;
    var sint = Blip.ar(freq) * Linen.kr(gate,doneAction:2,releaseTime:0.8);
    Out.ar(out, Pan2.ar(sint, 0));
}).add();

fork { var x = Synth(\testEvt); 2.wait; x.release }
但在后一种情况下,发行版有一层间接层。第一个例子也相当于

fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait; e.release }
它明确地执行
发布
的工作
Event
还支持
set
,它将值传递给相应的
Synth
控件(如果后者在服务器上正确
add
ed)

现在,您询问的复杂方法(检索事件的节点ID并向其发送消息)也可以实现了。。。尽管几乎没有必要:

fork { var x = Synth(\testEvt); 2.wait; x.set(\gate, 0); }
顺便说一下,您不能在
例程
之外使用
等待
,这就是为什么在上述示例中需要
fork
。当然,您可以在编辑器中以交互方式“手动等待”,然后在
Synth
事件上调用
release

作为封套选通工作原理的一个微妙点,它实际上并没有开始播放(从技术上讲,它开始转换到第一个[攻击]封套段的端点),直到您将gate设置为1。即,您可以延迟(信封)启动,如下所示:

fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait;
    e[\id].do({ arg n; s.sendMsg("/n_set", n, "gate", 0); }) }
请注意,默认的
事件.play
不会生成0到1的
转换,也就是说,如果您在
SynthDef
中将初始
值设置为零,则无法依靠它来触发合成器的信封

另外,我假设“free”的意思是“停止播放”,而不是“在服务器上释放内存”。在后一种意义上,不需要手动释放这些(事件)合成器,因为它们在封套中有
doneAction:2
,一旦它们被释放并且封套的最后一段完成播放,您就可以这样做。如果您想立即终止synth(如Ctrl+.does),而不是触发其淡出,您可以用
s.sendMsg(“/n_free”,n)
替换“复杂”示例(如上)的内部函数中发送的消息。或者更简单地说

fork { x = Synth(\testEvt, [\gate, 0]); 3.wait; x.set(\gate, 1); 2.wait; x.release }
此外,如果您想了解
\strum
,例如:

fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait; e.free }
现在
e[\id]
是一个由两个节点组成的数组
Event
有点冒失,因为它只会为传递给实际的
Synth
控件而不是随机字段的数组创建多个节点,所以“strumming”
\freq
(或其前身,如
\degree
等)只会在
Syntdesc
具有
freq
控件时创建多个节点

唉,“复杂”的方法在播放
Pbind
s(模式)时几乎毫无用处。这是因为
Pbind。
fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait; e.free }
e = (instrument: \testEvt, sustain: inf, strum: 1, out: #[0, 0]).play
(p = Pbind(\instrument, \testEvt, \sustain, Pseq([1, 2]), \play, {
    arg tempo, srv;
    var rv;
    "playhack".postln;
    rv = Event.parentEvents[\default][\play].value(tempo, srv);
    ~id.postln;
    rv;
}).play)