Simple Routine question

Trying to get a ping at random that plays 1.0 or 0.5, 0,5. subdivisions. Im guessing several ways to handle it. But interested in how to with the least amount of code. Im super new and this ugly mess I was trying is not working…


(
SynthDef(\ping,{
	var sig;
	sig = SinOsc.ar() * Env.perc(0.01, 0.1).ar(2) !2 * 0.2;
	Out.ar(0, sig) ;
}).add
)

/// guessing something like this plugged in but have to get synth to play aswell..
(
|n = 1.0|
[n, [n/2, n/2]].choose;
)

/// i know this won't work
(
Routine { |n|
	[n, [n/2, n/2]].choose;
	Synth(\ping);
	loop({
		Synth(\ping)
		wait(n);
	});
	
}.play
)

///// or this 

(
Routine 
	loop({
		Synth(\ping)
	wait(1.0, [0.5, 0.5]).rrand;
	});
	
}.play
)
1 Like

This is tailor-made for patterns.

(
Routine {
	var dur = Prand([
		1.0,        // one of the 2 random choices
		Pn(0.5, 2)  // the other (must play both 0.5 values consecutively)
	], inf).asStream;
	loop({
		s.bind { Synth(\ping) };  // see "Server Timing" help
		dur.next.wait;
	});
}.play;
)

hjh

1 Like

Two possibilities/sketches. But it depends on how you will develop this idea

Routine({
    loop {
        if(0.5.coin) {
            Synth(\ping); 1.wait;
        } {
            Synth(\ping); 0.5.wait;
            Synth(\ping); 0.5.wait;
        }
    }
}).play;


fork{
    var dur = Prand([1,Pn(0.5,2)],inf).asStream;
    loop{
        Synth(\ping);
        dur.next.wait;   
    }
};
1 Like

Oh, I’m not 100% sure why s.bind is needed here.

For accurate scheduling, see “Server Timing” help :wink:

1 Like

yea it def is a pattern problem but for some reason I got fixated on doing it without going to pattern… :melting_face:

You could also isolate the dur stream into a Routine.

(
Routine {
	var dur = Routine {
		loop {
			if(0.5.coin) {
				1.yield
			} {
				2.do { 0.5.yield };
			}
		}
	};
	loop {
		s.bind { Synth(\ping) };
		dur.next.wait;
	};
}.play;
)

… but, you have also asked for shorter code, and I think it isn’t going to get any shorter than the pattern way. (Also, patterns aren’t all or nothing – using Prand for the duration doesn’t require using Pbind to run the sequence.)

In sequencing contexts, it’s generally recommended to send messages with timestamps. Synth() by itself omits the timestamp; as a result, synths’ onset times will be quantized to hardware buffer boundaries, which generally you don’t want (except for live triggering, where “as soon as possible” is the desired behavior).

hjh

1 Like

yes great point for some odd reason I have the Prand etc linked to Pbinds in my head…

Okay, sure. I think I’m blind; I read (in my mind) s.sync
Though there, the jitter would possibly be below 5ms?

as a result, synths’ onset times will be quantized to hardware buffer boundaries,

That’s not the only problem!

There three sources of jitter when it comes to Server message scheduling:

  1. language jitter (caused by thread wakeup times and the execution time of user code)
  2. network jitter (on localhost this is just a few microseconds)
  3. hardware buffer size

Without scheduling, messages are quantized to hardware buffer boundaries (in the worst case) and they can be arbitrarily delayed.

1 Like