在初始化synth时,将参数传递给SynthDef不会注册

时间:2016-06-16 10:23:55

标签: supercollider

我有一个简单的SynthDef,我想使用CCIn类,如下所示:

(
SynthDef(\lfo_sin, {|bus, amp, myArg|
    var m = CCIn.new;
    var v = [300, 700, \exp].asSpec;
    var sig = SinOsc.ar(m.kr(0, myArg, v), mul:amp);
    Out.ar(bus, sig);
}).add;
)

当我像y = Synth(\lfo_sin, [\bus, 0, \amp, 1, \myArg, 71]);那样实例化它时,为了与MIDI控制器上的MIDI CC匹配,我无法像我应该那样使用CCIn.kr方法。

如果我在定义SynthDef时直接输入MIDI CC:

(
SynthDef(\lfo_sin2, {|bus, amp|
    var m = CCIn.new;
    var v = [300, 700, \exp].asSpec;
    var sig = SinOsc.ar(m.kr(0, 71, v), mul:amp);
    Out.ar(bus, sig);
}).add;
)

一切都按照应有的方式运行,我可以使用MIDI控制器控制频率。

为什么会出现这种情况?如何修改我的代码,以便我可以在初始化合成器时传入MIDI CC,或者之后设置参数?

1 个答案:

答案 0 :(得分:0)

如果你看一下CCIn的来源,你可以看到它比普通的UGen更复杂:

    kr { |chan = 0, num = 0, spec = \amp, lag = 0.05|
        var outArray = [chan, num, spec, lag].flop.collect{ |args| 
            var ch, n, sp, lg;
            # ch, n, sp, lg = args;
            (sp.asSpec.map( In.kr(this.prGetBus(ch, n).index) ).lag3(lg))
            };
        if (outArray.size>1) {^outArray} {^(outArray[0])} //fix to work with muliout

具体来说,这......

this.prGetBus(ch, n)

正在使用提供的频道和号码(chn)来查找可以读取MIDI数据的Bus(请参阅prGetBus)。它正在进行此查找作为构建SynthDef的一部分,而不是运行Synth,所以一旦它被构建,它正在读取的总线几乎是固定的。 CCIn夸克掩盖了一些相当复杂的东西,以便表现得像一个简单的UGen,所以你不太可能轻易地获得你正在寻找的行为。

以下是一些替代方案。

<强> 1。自己将MIDI数据写入总线

// One for each cc number
~ccBusses = 127.collect({
    Bus.control(s, 1);
}); 

// A midi responder that sets the value of the right bus
MIDIdef.cc(\cc, {
    |value, cc|
    ~ccBusses[cc].set(value);
}, ccNum: (0..127) )   // meaning: all cc values

// Once those are set up, to map a cc to a new synth use:
Synth(\mySynth, args:[\freq, ~ccBusses[10].asMap]);

<强> 2。使用连接夸克

// Create a value between 100..2400, controlled by MIDI
~freq = MIDIControlValue(spec:ControlSpec(100, 2400));
~freq.cc_(10); // cc number 10

// Run your synth
~note = Synth(\mySynth, args:[\freq, ~freq]);

// Connect the value of ~freq to the \freq argument of your synth. Now, MIDI changes will be broadcast to your synth.
~freq.signal(\value).connectTo(~note.argSlot(\freq));