0

嗨,我正在使用 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'

);
)
4

1 回答 1

0

首先,这个 if 语句:

if ((msg[3] > 200), {x.clear;} && {f.play;});

很奇怪——目前还不清楚是否能做到这一点,但它不太可能按照你的意愿去做。&& 是一个布尔运算符,所以一般的期望是左右两边是真/假。在您的使用中,它实际上是在左侧和右侧功能上执行功能组合,但考虑到您的功能,这仍然没有做任何连贯的事情。我想你可能想要的是:

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));
于 2016-11-26T06:04:34.280 回答