超级对撞机:使用 Mix.fill 进行加法合成的变量和参数范围
Supercollider: scope of variables and arguments for additive synthesis using Mix.fill
我对如何在加法合成中实现参数感到很困惑。
我正在尝试实现一个系统,我可以在其中对以下参数进行排序:任意数量的分音、基频。我不确定任意数量的分音是否可行,但我认为对基频进行排序确实是完全可能的。
这是我正在处理的代码:
(
z = {
arg index, freq, nn;
var finalFreq, ff, amp, nn;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
)
(
SynthDef.new('additive',{
arg freq, nn;
var sig, env;
env = Line.kr(1,0,0.2);
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
)
(p = Pbind(
\instrument, \additive,
\dur, Pseq([0.1,0.2,0.3,0.4],inf),
\freq, Pseq([100,440,880,55],inf),
\nn, Pseq([1,5,10,100],inf)
).play;
)
失败 Index not an Integer
。而且我什至不确定如何将参数发送到 z。
我设想利用变量范围的替代公式如下:
(
SynthDef.new('additive',{
arg freq, nn;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp, nn;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
)
它也不起作用,失败 Index not an Integer
。
你会如何解决这个问题?
Mix.fill 在创建 Synth 时创建一次数组,因此您不能使用 Synth 参数动态更改数组的大小。
您的底部示例还将 nn
声明为 z
函数内的变量,这意味着 amp = 0.5/nil
一个可能的解决方案是制作许多 SynthDef。假设您知道您想要的 SinOsc 的最小数量是 2,最大数量是 25。
(
(2..25).do({ arg nn;
SynthDef.new('additive'++nn,{
arg freq;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
});
)
这将为您提供名为 additive2、additive3、additive4、...additive25 的 SynthDef。
当你想改变数组的大小时,你必须改变你正在播放的 SynthDef。这是一个 Pbind,它从你的附加 SynthDefs 之间随机选择:
Pbind(
\instrument, Pfunc({ 'additive' ++ 2.rrand(25) })
).play
或者,使用上面示例中的 pbind:
(
n = [1,5,10,100];
n.do({ arg nn;
SynthDef.new('additive'++nn,{
arg freq;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
});
)
Pbind(
\instrument, Pfunc({ 'additive' ++ n.choose }),
\dur, Pseq([0.1,0.2,0.3,0.4],inf),
\freq, Pseq([100,440,880,55],inf)
).play
我对如何在加法合成中实现参数感到很困惑。
我正在尝试实现一个系统,我可以在其中对以下参数进行排序:任意数量的分音、基频。我不确定任意数量的分音是否可行,但我认为对基频进行排序确实是完全可能的。
这是我正在处理的代码:
(
z = {
arg index, freq, nn;
var finalFreq, ff, amp, nn;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
)
(
SynthDef.new('additive',{
arg freq, nn;
var sig, env;
env = Line.kr(1,0,0.2);
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
)
(p = Pbind(
\instrument, \additive,
\dur, Pseq([0.1,0.2,0.3,0.4],inf),
\freq, Pseq([100,440,880,55],inf),
\nn, Pseq([1,5,10,100],inf)
).play;
)
失败 Index not an Integer
。而且我什至不确定如何将参数发送到 z。
我设想利用变量范围的替代公式如下:
(
SynthDef.new('additive',{
arg freq, nn;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp, nn;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
)
它也不起作用,失败 Index not an Integer
。
你会如何解决这个问题?
Mix.fill 在创建 Synth 时创建一次数组,因此您不能使用 Synth 参数动态更改数组的大小。
您的底部示例还将 nn
声明为 z
函数内的变量,这意味着 amp = 0.5/nil
一个可能的解决方案是制作许多 SynthDef。假设您知道您想要的 SinOsc 的最小数量是 2,最大数量是 25。
(
(2..25).do({ arg nn;
SynthDef.new('additive'++nn,{
arg freq;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
});
)
这将为您提供名为 additive2、additive3、additive4、...additive25 的 SynthDef。
当你想改变数组的大小时,你必须改变你正在播放的 SynthDef。这是一个 Pbind,它从你的附加 SynthDefs 之间随机选择:
Pbind(
\instrument, Pfunc({ 'additive' ++ 2.rrand(25) })
).play
或者,使用上面示例中的 pbind:
(
n = [1,5,10,100];
n.do({ arg nn;
SynthDef.new('additive'++nn,{
arg freq;
var sig, env;
env = Line.kr(1,0,0.2);
z = {
arg index;
var finalFreq, ff, amp;
ff = index*freq;
amp = 0.5/nn;
finalFreq = freq + ff;
finalFreq.postln;
s = SinOsc.ar(finalFreq, 0, amp);
};
sig = Mix.fill(nn, z) * env;
Out.ar(0,sig);
}).add
});
)
Pbind(
\instrument, Pfunc({ 'additive' ++ n.choose }),
\dur, Pseq([0.1,0.2,0.3,0.4],inf),
\freq, Pseq([100,440,880,55],inf)
).play