How to retrigger a perc using set (is it possible?)

Hi!

I’ve been running into a wall trying to make monophonic sequences with Routines.

My intent with the code is to:

  • create a synth on the server (without triggering its envelope)
  • trigger its envelope using set
  • retrigger that same synth a short while later to create a smooth, melismatic, monophonic sound

Here is a short code snippet of how I expected this to work. The result is silence:

(
SynthDef(\v, {
  var snd, env, gate = \trigger.kr(0); //doneAction:Done.freeSelf

  env = Env.perc(1,\duration.kr(10)).ar(gate:gate);

  snd = Saw.ar(freq:\freq.kr(110));

  snd = LPF.ar(snd, Env.perc(5,10).ar(gate:gate).linexp(0,1,200,12000));

  snd = snd*env;

  Out.ar(\out.ir(0),snd!2);
}).add;

Routine {
  var beat = 60/76;
  var s = Server.default;
  var vx = Synth(\v,[trigger:0]);
  s.sync;

  4.do{|k|

    beat.wait;


    s.bind{ vx.set([freq:440,trigger:1]);};
    beat.wait;
    beat.wait;

    s.bind{ vx.set([freq:550,trigger:1]);};

    beat.wait;
    beat.wait;
    beat.wait;


  };

  vx.free;


}.play;
);

Context: I know about Pmono and related objects but I don’t really get along with the pattern system. I really do like to use Routines to make imperative compositions.

If anyone has done this before and knows how I would be very grateful for a hint! Thanks in advance!

Well, I seem to have solved my problem. The following code works:

(
SynthDef(\v, {
  var snd, env, gate = \trigger.kr(0); //doneAction:Done.freeSelf

  env = Env.perc(1,\duration.kr(10)).ar(gate:gate);

  snd = Saw.ar(freq:\freq.kr(110));

  snd = LPF.ar(snd, Env.perc(5,10).ar(gate:gate).linexp(0,1,200,12000));

  snd = snd*env;

  Out.ar(\out.ir(0),snd!2);
}).add;

Routine {
  var beat = 60/76;
  var s = Server.default;
  var vx = Synth(\v,[trigger:0]);
  s.sync;
  beat.wait;

  4.do{|k|

    beat.wait;


    s.bind{ vx.set(\freq,440,\trigger,1);};
    beat.wait;
    beat.wait;
    s.bind{ vx.set(\trigger,0);};

    s.bind{ vx.set(\freq,550,\trigger,1);};

    beat.wait;
    beat.wait;
    beat.wait;
    s.bind{ vx.set(\trigger,0);};


  };

  vx.free;


}.play;
);

My theory is that this is because trigger needs to go to zero at some point in order to make the envelope actually restart and set does not accept arrays in place of varargs and silently fails.

Is this right?

Try changing this to gate = \trigger.tr(0) – this will remove the need to set to 0 explicitly.

hjh

2 Likes