Supercollider:带信封的活动自动延音

时间:2013-06-22 20:34:43

标签: events envelope supercollider

( 

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;

)

在SynthDef之后执行第一行和第二行将创建永久播放的合成器,而第三行的合成器按默认值播放0.8秒生成的事件。

问题是我在SynthDef的任何地方都没有使用'Sustain',它只是因为有亚麻而自动使用。

对于freq,情况并非如此:两个事件都在440而不是220处播放,这只是因为SynthDef不使用'freq'作为参数。那么为什么维持不遵循同样的规则呢?

另外,有没有办法引用事件创建的合成器?因此,当他们以sustain: inf作为参数时,我可以在以后释放它们。

2 个答案:

答案 0 :(得分:1)

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

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

是事件。事件可以为您处理很多事情。他们做的一件事就是计算何时将门设置为0.(请记住,门是SynthDef中的参数之一。)在第一个例子中,因为你持续了无限的持续时间,所以门永远不会变为零。在第二个示例中,它使用默认持续时间,并在持续时间过后将门设置为零。您可以通过查看Event.sc源文件找出事件环境变量中使用的关键字。如果你搜索维持,你会发现它用于计时的其他关键词。其中一个是dur。试试这个:

(instrument: \testEvt, dur:3).play

Freq也是事件的关键字,但由于你没有freq参数,它不会影响你的synthDef。如果要设置频率,则需要进行更改:

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

对于事件和直接控制合成器之间的对比,请尝试:     a = Synth.new(\ testEvt,[\ out,0,\ gate,1]) 你可以添加你想要的任何其他参数,比如freq或sustain,但它们没有效果,因为它们不是你的synthdef的参数。而且,与Event不同,synth不会代表您进行任何计算。当您想要结束音符时,请将您自己设置为0:     a.set(\ gate,0)

了解事件环境变量是很好的,因为它们也被Pbinds使用,并且通过使用它们,您可以影响其他事物。如果你有一个使用维持作为其他东西的参数的合成器,你可能会因为它改变你的持续时间而感到惊讶。

答案 1 :(得分:0)

关于您的上一个子问题

还有,有没有办法引用由事件创建的合成器?这样,当他们将sustain: inf作为参数时,我可以稍后再释放它们。

是的,通过使用Event键对\id进行索引。实际上,这会返回一个节点ID数组,因为带有\strum的事件可以触发多个节点/合成器。此外,事件未播放时,\id的值为nil。但是对于您想要的东西,这种索引方法是不必要的,因为...

您可以通过以Event结束release来结束(关联的)合成器,就像Synth本身一样。这基本上是淘汰内部合成器。 (在您的示例中,此release调用通过将Linen降低为0,转换到gate生成的ASR信封的释放点。)并且,当然,如果不打算立即在程序中释放合成器和/或事件的“引用”,则使用变量保存它(该合成器不会产生带有门控包络的声音)。

基本上

fork { var x = Synth(\testEvt); 2.wait; x.release }

相同
fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait; e.release }

除非在后一种情况下存在一层间接释放。第一个示例也等同于

fork { var x = Synth(\testEvt); 2.wait; x.set(\gate, 0); }

明确执行release的工作。 Event还支持set,并将其值传递给相应的Synth控件(如果在服务器上正确add设置了该控件)。

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

fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait;
    e[\id].do({ arg n; s.sendMsg("/n_set", n, "gate", 0); }) }

顺便说一句,您不能在wait之外使用Routine,这就是上面示例中需要fork的原因。交互式地,在编辑器中,您当然可以“手动等待”,然后再在releaseSynth上调用Event

作为信封门控工作原理的一个微妙点,它直到您将gate设置为1时才真正开始播放(从技术上开始过渡到第一个[attack]信封段的端点)。您可以按如下方式延迟(信封)启动:

fork { x = Synth(\testEvt, [\gate, 0]); 3.wait; x.set(\gate, 1); 2.wait; x.release }

请注意,默认的Event.play 不会会生成0到1的gate过渡,即,如果您使用它来触发合成器的包络,则不能依靠它将gate中的初始SynthDef值设置为零。

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

fork { var e = (instrument: \testEvt, sustain: inf).play; 2.wait; e.free }

此外,如果您对\strum感到疑惑,请参见以下示例:

e = (instrument: \testEvt, sustain: inf, strum: 1, out: #[0, 0]).play

现在e[\id]是两个节点的数组。 Event有点厚脸皮,因为它只会为传递给实际Synth控件的数组创建多个节点,而不是为随机字段创建数组,因此“ strumming” \freq(或其{{1 }}等)仅在您的\degree具有SynthDesc控件的情况下创建多个节点。

可惜的是,在播放freq s(模式)时,“复杂”方法几乎没有用。这是因为Pbind返回并且Pbind.play ... a使正在播放的原型事件成为私有副本并播放该私有副本,调用者上下文无法访问该私有副本(除非您入侵{{1 }}。令人困惑的EventStreamPlayer有一个可访问的EventStreamPlayer.prNext变量,但这只是“原型”,而不是正在播放的私人复制事件……因此,如果EventStreamPlayer是{{1}的实例},那么event即使在播放时也始终为零(或您预先设置的任何数值)。由于很少有人单独玩p,更经常玩模式...

作为一项艰巨的黑客练习,事实证明,还有一种更加复杂的方法来访问EventStreamPlayer触发的节点的ID ...这取决于重写默认事件p.event[\id],值得庆幸的是可以扩展到类继承之外,因为默认值方便地保存在类字典中...

Events

但是,一般来说,模式显然不是设计用于这种方式的,即通过黑客入侵“一个下面的层”来获取节点ID。作为“证明”,尽管以上方法在EventStreamPlayer(使用默认的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) )下可以很好地工作,但在Pbind下却不能可靠地工作将事件Event设置在其第一音符上(事件类型\note),但仅将其设置在后续音符上(它们会生成不同的事件类型Pmono)。 \id保留节点ID的内部副本,但这在第一个单音符上是完全不可访问的。它仅出于某种原因将其复制到后续注释中的\monoNote(可能是错误的,但可能是“有意设计的”)。另外,如果您使用的\monoSet扩展了Pmono的类型为Event ...上述黑客攻击无法全部起作用,即Pdef永远不会由类型{{1 }};也许您可以了解以某种方式生成的潜在子事件...我不必费心进行进一步的调查。

SC文档(在模式指南中)甚至只说一遍

请记住,由模式组成的流不会暴露其内部。这意味着您无法直接调整效果合成器的参数,因为您无法找出其节点ID是什么。

鉴于上述黑客攻击,这并不完全正确,但在某些情况下确实如此。