为什么这个不归还的信封不会被重新触发?

时间:2014-04-18 18:37:44

标签: supercollider

我尝试使用非返回信封(即其中的片段不会返回0)。我发现在以下代码中不能多次触发信封env

(
SynthDef(\stupidSynth,
    {
        |t_trig|
        var env, envShape, audio, env2;
        envShape = Env.new([0, 1], [0.5], \sine);
        env = EnvGen.kr(envShape, t_trig);
        env2 = EnvGen.kr(Env.perc, t_trig);
        audio = SinOsc.ar(400 + (env * 100)) * env2 * 0.1;
        Out.ar(0, audio);
    }
).add;
)

(
p = Pmono(*[
    \stupidSynth,
    \t_trig, 1
]
).play;
)

我所希望的是,每当合成器被重新触发时,音高会越来越高。实际发生的是第一个音符播放音调包络,并且每个后续音符仅处于最终(即高)频率。 env显然没有被重新启用。

我不确定为什么会这样。信封在重新触发之前不必返回0 - 完全可以在信封完成之前重新触发信封。我的信封上有些东西不起作用。

我基本上在寻找具有Line行为的内容,但也能够重新触发并具有可自定义的曲线。

我正在尝试做什么?

2 个答案:

答案 0 :(得分:3)

与以往一样,这是我的一个误解,我发现信封 被重新触发 - 只是它没有从指定的起点开始。它始终以当前值开始。这实际上是有道理的,因为信封可以在它完成之前被重新触发,在这种情况下你不会希望它突然跳到起点。

因此,我发布的代码的唯一问题是,一旦信封运行一次,每次运行它就会从当前值(即信封的终点)变为信封'结束点 - 即信封不会改变任何东西。

以下代码演示了起点有点无关紧要,并说明了我所追求的行为:

(
SynthDef(\test,
    {
        |freq = 300, on = 1, amp = 0.2, t_pitchEnv = 0, pitchEnvEnd = 1|
        var audio, onswitch, pitchEnv;
        onswitch = EnvGen.kr(Env.cutoff(5, curve: \exp), on, doneAction:2);
        pitchEnv = EnvGen.kr(Env.new([0, pitchEnvEnd], [1], \sine), t_pitchEnv) * freq;
        audio = SinOsc.ar(freq + pitchEnv, mul: amp * onswitch);
        Out.ar(0, audio ! 2);
    }
).add;
)

x = Synth(\test);
x.set(\t_pitchEnv, 1, \pitchEnvEnd, 1);
x.set(\t_pitchEnv, 1, \pitchEnvEnd, 2);
x.set(\t_pitchEnv, 1, \pitchEnvEnd, 1);
x.set(\t_pitchEnv, 1, \pitchEnvEnd, 0);
x.set(\on, 0);

答案 1 :(得分:1)

信封没有问题。您认为信封的行为就好像每次重新触发时一样,它会将其新输出“添加”到之前输出的任何内容 - 这不是信封的行为方式。触发信封总是会跳转到重启点(通常是开始)。 EnvEnvGen中没有关于输出内容的长期记忆的概念。

如何做你想做的事:

1)不要使用信封来实现“记忆性”行为,而是使用类似积分器的东西,然后使用滞后:

(
SynthDef(\stupidSynth,
    {
        |t_trig|
        var env, envShape, audio, env2, note;
        note = 67 + Integrator.kr(t_trig * 5).lag(0.2); /* up by 5 semitones at a time */
        env2 = EnvGen.kr(Env.perc, t_trig);
        audio = SinOsc.ar(note.midicps) * env2 * 0.1;
        Out.ar(0, audio);
    }
).add;
)

(
p = Pmono(*[
    \stupidSynth,
    \t_trig, 1
]
).play;
)

2)如果您迫切想要使用Env来达到效果(例如对形状的精细控制),那么您可以将您的合成器分成两个:一个从Bus读取当前频率并且是一个长寿命的合成器,以及一个合成器,你可以创建多个实例并从env输出到总线。然后,无论何时触发,都会创建一个新实例,添加到后一个synthdef的实例堆中。 (凌乱吧。)

3)我打赌你可以通过使用EnvGen来做到这一点,但每次触发时只需增加基频。狡猾,但可能工作正常。