在 Supercollider 中,我需要选择 Ndefs 来播放并停止列表中的前一个
In Supercollider I need to choose Ndefs to play and stop the previous from a list
您好,我正在使用 mindwave 来通过 OSC 控制一些 Ndef。我需要编写一个从列表(例如 [x, f])中选择下一个并停止上一个的函数。此外,我需要能够只播放第一个 Ndef(例如 x)而不是第二个(例如 f),直到我收到适当的消息(例如 msg[3])并同时停止 x。这是我的尝试,但效果不理想:
(
OSCdef.new(
\select,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[3] > 200), {x.clear;} && {f.play;});
},'/neurovals'
);
SynthDef.new(\Syn, { arg freq = 440, amp = 1, sustain = 0.5;
var sig, env, mod;
env = EnvGen.kr(Env.linen(0.05, sustain, 0.5, 0.08), doneAction: 2);
mod = Saw.ar(freq * 0.1) * LFNoise1.kr(2).range(10,800);
sig = SinOsc.ar(freq + mod) * env;
Out.ar(0, RLPF.ar(sig, freq, 1.7)).dup;
}).add;
x= Ndef(\blinkpat1, Pbind(
\instrument, \Syn,
\dur, 0.03,
\freq, 440
));
OSCdef.new(
\base,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[1] == msg[1]),
{x.set(\freq, msg[1].linlin(0, 100, 300, 1000);)});
},'/neurovals'
);
SynthDef.new(\fmsyn, { arg freq = 440, amp = 1, sustain = 1;
var sig, env, mod;
env = EnvGen.kr(Env.linen(0.05, sustain, 0.5, 0.08), doneAction: 2);
mod = SinOsc.ar(freq * 0.5) * LFNoise1.kr(2).range(10,800);
sig = SinOsc.ar(freq + mod) * env;
Out.ar(0, RLPF.ar(sig, freq, 1.7)).dup;
}).add;
f = Ndef(\blinkpat2, Pbind(
\instrument, \fmsyn,
\freq, 440,
\sustain, 2,
\octave, 3,
\amp, 0.4,
));
OSCdef.new(
\base2,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[1] == msg[1]),
{f.set(\freq, msg[1].linlin(0, 100, 300, 1000);)});
if ((msg[1] == msg[1]),
{f.set(\sustain, msg[1].linlin(0, 100, 1, 2);)});
},'/neurovals'
);
)
首先,这个 if 语句:
if ((msg[3] > 200), {x.clear;} && {f.play;});
很奇怪 - 不清楚是否试图做到这一点,但它不太可能做你想做的事。 && 是一个布尔运算符,所以一般的期望是左边和右边是 true/false。在您的使用中,它实际上是在左侧和右侧功能上执行功能组合,但鉴于您的功能,它仍然没有做任何连贯的事情。我认为您可能想要的是:
if (msg[3] > 200) {
x.clear;
f.play;
}
...这将清除 x 并播放 f。
您可以通过多种方式实现我认为您正在尝试做的事情。这里有一个建议 - Pdef
可以相互分配,并在播放期间热交换。这意味着,您可以:
( // set up \a, \b, and \player, and start playing \player
Pdef(\a, Pbind(
\dur, 1/4,
\degree, 0,
));
Pdef(\b, Pbind(
\dur, 1/3,
\degree, 2,
));
\ Start playing an empty Pdef to use later.
Pdef(\player).play;
)
然后,您可以将\player设置为\a或\b之一,在它们之间透明切换:
// Assign Pdef(\a) to player, to start it playing
Pdef(\player, Pdef(\a));
// Assign Pdef(\b) to player, which starts \b and stops \a
Pdef(\player, Pdef(\b));
您好,我正在使用 mindwave 来通过 OSC 控制一些 Ndef。我需要编写一个从列表(例如 [x, f])中选择下一个并停止上一个的函数。此外,我需要能够只播放第一个 Ndef(例如 x)而不是第二个(例如 f),直到我收到适当的消息(例如 msg[3])并同时停止 x。这是我的尝试,但效果不理想:
(
OSCdef.new(
\select,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[3] > 200), {x.clear;} && {f.play;});
},'/neurovals'
);
SynthDef.new(\Syn, { arg freq = 440, amp = 1, sustain = 0.5;
var sig, env, mod;
env = EnvGen.kr(Env.linen(0.05, sustain, 0.5, 0.08), doneAction: 2);
mod = Saw.ar(freq * 0.1) * LFNoise1.kr(2).range(10,800);
sig = SinOsc.ar(freq + mod) * env;
Out.ar(0, RLPF.ar(sig, freq, 1.7)).dup;
}).add;
x= Ndef(\blinkpat1, Pbind(
\instrument, \Syn,
\dur, 0.03,
\freq, 440
));
OSCdef.new(
\base,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[1] == msg[1]),
{x.set(\freq, msg[1].linlin(0, 100, 300, 1000);)});
},'/neurovals'
);
SynthDef.new(\fmsyn, { arg freq = 440, amp = 1, sustain = 1;
var sig, env, mod;
env = EnvGen.kr(Env.linen(0.05, sustain, 0.5, 0.08), doneAction: 2);
mod = SinOsc.ar(freq * 0.5) * LFNoise1.kr(2).range(10,800);
sig = SinOsc.ar(freq + mod) * env;
Out.ar(0, RLPF.ar(sig, freq, 1.7)).dup;
}).add;
f = Ndef(\blinkpat2, Pbind(
\instrument, \fmsyn,
\freq, 440,
\sustain, 2,
\octave, 3,
\amp, 0.4,
));
OSCdef.new(
\base2,
{
arg msg, time, addr, port;
[msg, time, addr, port].postln;
if ((msg[1] == msg[1]),
{f.set(\freq, msg[1].linlin(0, 100, 300, 1000);)});
if ((msg[1] == msg[1]),
{f.set(\sustain, msg[1].linlin(0, 100, 1, 2);)});
},'/neurovals'
);
)
首先,这个 if 语句:
if ((msg[3] > 200), {x.clear;} && {f.play;});
很奇怪 - 不清楚是否试图做到这一点,但它不太可能做你想做的事。 && 是一个布尔运算符,所以一般的期望是左边和右边是 true/false。在您的使用中,它实际上是在左侧和右侧功能上执行功能组合,但鉴于您的功能,它仍然没有做任何连贯的事情。我认为您可能想要的是:
if (msg[3] > 200) {
x.clear;
f.play;
}
...这将清除 x 并播放 f。
您可以通过多种方式实现我认为您正在尝试做的事情。这里有一个建议 - Pdef
可以相互分配,并在播放期间热交换。这意味着,您可以:
( // set up \a, \b, and \player, and start playing \player
Pdef(\a, Pbind(
\dur, 1/4,
\degree, 0,
));
Pdef(\b, Pbind(
\dur, 1/3,
\degree, 2,
));
\ Start playing an empty Pdef to use later.
Pdef(\player).play;
)
然后,您可以将\player设置为\a或\b之一,在它们之间透明切换:
// Assign Pdef(\a) to player, to start it playing
Pdef(\player, Pdef(\a));
// Assign Pdef(\b) to player, which starts \b and stops \a
Pdef(\player, Pdef(\b));