Why can't I do an equality test of a synth parameter?

113 views Asked by At

I'm mystified. In this code:

SynthDef(\acid,
    {
        |out, gate = 1, freq, myParam, amp, cutoff, resonance, filtEnvAmt|
        var env, audio, filtEnv;
        if (myParam == \something, { freq = 200; });
        env = Linen.kr(gate, 0, 1, 0, doneAction: 2);
        audio = LFSaw.ar(freq, mul: amp);
        filtEnv = Line.kr(midicps(cutoff + filtEnvAmt), midicps(cutoff),  0.2);
        audio = RLPFD.ar(audio, ffreq: filtEnv + MouseX.kr(0, 5000), res: MouseY.kr(0, 1), dist: 0);
        Out.ar(out, audio * env);
    }
).add;

b = Pbind(*[
    out: 0,
    instrument: \acid,
    stepsPerOctave: 19,
    scale: [0, 3, 5, 8, 11, 14, 17],
    octave: 3,
    degree: Pseq([0, \, 3, 3, 4, 4, 9, 4, 4]),
    myParam: \something,
    //prevFreq: Pseq([0, 0, 0, 0, 9, 0, 0, 0, 0]),
    dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
    cutoff: Pseq([60, \, 50, 60, 80, 60, 90, 80, 50]),
    filtEnvAmt: Pseq([20, \, 20, 20, 20, 20, -10, 20, 20]),
    resonance: Pseq([0.5, \, 0.5, 0.5, 0.5, 0.5, 0.3, 0.5, 0.5])
]);

b.play;

..the equality test myParam == \something never returns true, despite the fact that the Pbind is clearly sending \something each time. No other value will work either: 0, nil etc.

The equality tests myParam == myParam and \something == \something do work however, so in these cases I get a monotone melody.

I can only guess that a Pbind sends each value in some kind of wrapper, but I've no idea how to then check them from inside the synth. Can anyone help?

1

There are 1 answers

2
Dan Stowell On BEST ANSWER

First: you can't send symbols to a synth control. You can only send numbers.

Second: your example doesn't say what freq should be if the test is false. In fact, you should write it in more of a dataflow style such as:

 freq = if(testcondition, 200, 300);

That's the kind of thing that will work in a synthdef.

Third is a slightly frustrating thing in sc language, which is that the == message is always evaluated at synthdef compile time - the equality is checked once, and then never again. In order to have "live" equality checking, you can use this slightly clunky expression:

   BinaryOpUGen("==", thinga, thingb)

So in summary you might write

 freq = if(BinaryOpUGen("==", myParam, 1), 200, 300);