1
( 

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”,它自动使用只是因为有 Linen。

同样,freq 不会发生这种情况:事件都在 440 而不是在 220 播放,这只是因为 SynthDef 不使用“freq”作为参数。那么为什么sustain不遵循同样的规则呢?

另外,有没有办法引用由事件创建的合成器?这样,当他们有sustain: inf争论时,我可以在以后释放他们。

4

2 回答 2

2
(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]) 您可以添加任何其他您想要的参数,例如频率或维持,但它们没有效果,因为这些不是您的 synthdef 的参数。而且,与 Event 不同,synth 不会代表您进行任何计算。当您希望音符结束时,您自己将门设置为 0:a.set(\gate, 0)

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

于 2013-06-22T21:06:14.527 回答
0

关于你的最后一个子问题,

另外,有没有办法引用由事件创建的合成器?这样,当他们有sustain: inf争论时,我可以在以后释放他们。

Event是的,通过“索引”\id按键。这实际上返回了一个节点 ID 数组,因为一个事件\strum可以触发多个节点/合成器。此外,该\id值是nil事件未播放时的值。但是这种索引方法对于你想要的来说是相当不必要的,因为......

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

基本上

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在 a 之外使用Routine,这就是fork上面示例中需要的原因。交互式地,在编辑器中,您当然可以“手动等待” ,然后再调用releaseSynth.Event

作为包络门控工作原理的一个微妙点,它实际上并没有开始播放(技术上开始过渡到第一个 [attack] 包络段的端点),直到您将门设置为 1。即您可以延迟(包络)开始如:

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

请注意,默认值Event.play 不会生成这种 0 到 1 的gate过渡,即如果您gateSynthDef.

另外,我假设“免费”是指“停止播放”而不是“释放他们在服务器上的内存”。无需手动释放后一种意义上的那些(事件)合成器,因为它们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控件而不是随机字段的数组创建多个节点,因此“弹奏” \freq(或其前体\degree等)只会在您SynthDescfreq控件时创建多个节点。

Pbind唉,在播放s(模式)时,“复杂”的方法几乎没用。这是因为Pbind.playreturn 和EventStreamPlayer... 唉,制作正在播放的原型事件的私有副本并播放该私有副本,调用者上下文无法访问该副本(除非您 hack EventStreamPlayer.prNext)。令人困惑的是,EventStreamPlayer有一个可访问的event变量,但这只是“原型”,而不是正在播放的私有复制事件......因此,即使在播放时,如果p是一个EventStreamPlayerthen的实例,p.event[\id]也总是为零(或您事先设置的任何值)。因为一个人很少单独演奏Events,而更多时候是模式……

简单来说,黑客练习很困难,事实证明有一种更复杂的方式来访问EventStreamPlayer触发的节点的 id... 这依赖于覆盖默认事件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)

然而,一般来说,模式显然不是为这种方式设计的,即通过破解“下面的一层”来获取节点 ID。Pbind作为“证明”,虽然上面的内容与(使用默认Event类型)一起工作得很好,\note但它不能可靠地工作,Pmono它不会\id在其第一个音符(事件类型\monoNote)上设置事件,但只能在后续音符上(生成一个不同的事件类型,\monoSet)。Pmono保留节点 ID 的内部副本,但在第一个单音音符上完全无法访问;出于某种原因,它仅将其复制到Event后续注释中的 s (可能是错误,但可能是“设计使然”)。此外,如果你使用Pdefwhich extends Eventtype \phrase... 上面的技巧并不能全部工作,即\id从不按类型设置\phrase;也许您可以了解以某种方式生成的潜在子事件......我没有费心进一步调查。

SC 文档(在模式指南中)甚至在某一点上说

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

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

于 2020-02-21T03:32:41.010 回答