我尝试使用非返回信封(即其中的片段不会返回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
行为的内容,但也能够重新触发并具有可自定义的曲线。
我正在尝试做什么?
答案 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)
信封没有问题。您认为信封的行为就好像每次重新触发时一样,它会将其新输出“添加”到之前输出的任何内容 - 这不是信封的行为方式。触发信封总是会跳转到重启点(通常是开始)。 Env
或EnvGen
中没有关于输出内容的长期记忆的概念。
如何做你想做的事:
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来做到这一点,但每次触发时只需增加基频。狡猾,但可能工作正常。