Higher resolution for server side sequencing

I have looked at one server side sequencing attempt on sc code 303 emulation

It basically can be reduced to this:

(
var every = { |eventTrigger, barTrigger, x|
	var pattern = [1] ++ (0 ! (x - 1));
	eventTrigger * Demand.ar(eventTrigger, barTrigger, Dseq(pattern, inf));
};

var sequencer = { |trig, barTrigger, pattern|
	var barCounter = PulseCount.ar(barTrigger);
	var isBarZero = InRange.ar(barCounter % 1, 0, 0.99999);
	Demand.ar(trig, barTrigger * isBarZero, Dseq(pattern, inf));
};

{
	var bpm = 135;
	var clockFreq = bpm / 60;
	var barLengthInBeats = 4;

	var reso = 96;
	var resetLength = 1;

	var eventTrigger = Impulse.ar(clockFreq * reso);
	var barTrigger = PulseDivider.ar(
		trig: eventTrigger,
		div: (barLengthInBeats * reso * resetLength).floor,
		start: barLengthInBeats * reso
	);

	var trig = every.(eventTrigger, barTrigger, 24);

	var envTrig = trig * sequencer.(trig, barTrigger, [1, 0, 1, 1, 1, 1, 1, 0]);

	envTrig!2 * 0.25;

}.play;
)

You see the reso variable and the x argument for the every function, they have basically a factor of 4 between them 24 to 96 instead of 1 to 4. I was assuming that this is indicating some increased trigger resolution.
Does it in general make any difference if you run the triggers at a higher rate for accurancy, maybe for the resetLength?

If you take the code and reduce it to this, it sounds the same to me:

(
{
	var bpm = 135;
	var clockFreq = bpm / 60;
	var barLengthInBeats = 4;
	
	var reso = 4;
	var resetLength = 1;

	var trig = Impulse.ar(clockFreq * reso);
	var barReset = PulseDivider.ar(
		trig: trig, 
		div: (barLengthInBeats * reso * resetLength).floor, 
		start: barLengthInBeats * reso
	);

	trig = trig * Demand.ar(trig, barReset, Dseq([1, 0, 1, 1, 1, 1, 1, 0], inf));

	trig!2 * 0.25;

}.play;
)

There is also this isBarZero calculation with:

var barCounter = PulseCount.ar(barTrigger);
var isBarZero = InRange.ar(barCounter % 1, 0, 0.99999);

is this actually necessary for the reset and isnt PulseCount.ar(barTrigger) > 0 the same?

1 Like

One other thought was, that this probably makes sense if you run different instruments on the same server side clock. But maybe not.

i think this makes the roles of the different bits and pieces even more clear:

(
var clockGenerator = { |bpm, reso|
	var clockFreq = bpm / 60 * reso;
	Impulse.ar(clockFreq);
};

var eventTriggers = { |clock, barTrigger, x|
	var pattern = [1] ++ (0 ! (x - 1));
	clock * Demand.ar(clock, barTrigger, Dseq(pattern, inf));
};

var barTriggers = { |clock, barLengthInBeats, reso|
	PulseDivider.ar(clock, (barLengthInBeats * reso).floor, barLengthInBeats * reso);
};

var sequencer = { |eventTrigger, barTrigger, pattern|
	Demand.ar(eventTrigger, barTrigger, Dseq(pattern, inf));
};

{
	var bpm = 135;
	var barLengthInBeats = 4;
	var reso = 96;

	var clock = clockGenerator.(bpm, reso);
	var barTrigger = barTriggers.(clock, barLengthInBeats, reso);
	var eventTrigger = eventTriggers.(clock, barTrigger, 24);

	var trig = eventTrigger * sequencer.(eventTrigger, barTrigger, [1, 0, 1, 1, 1, 1, 1, 0]);

	trig!2 * 0.25;

}.play;
)

This can’t be done with client side like Pmono?

In case you have made some analysis on this code, please share it! It is a really interesting way of using the server and the language.

the sequencing with Pmono is not audio rate. all my attempts are ment to be used for granular synthesis and Im trying to bridge the gap between control rate rhythm sequencing and audio control ratchets, clouds and textures. see this thread: Duty Sequence for multichannel phase - #22 by dietcv
I want to continuously move between rhythm and tone https://www.youtube.com/watch?v=l_UHaulsw3M (min 17:05 - 17:55)

Made a post on the differencies a while ago: Making transitions with language or server side sequencing

In the ~gen book is one chapter about sub-sample accurate phasors for granulation with high trigger rates, which prevent aliasing and here we are just talking about control vs. audio rate.

I think i have broken down the code to its core sequencing functionality already in my former posts.

1 Like

I don’t think it makes a difference in that case. But I believe it is useful to have the clock running at a higher resolution and then use different PulseDividers for different clock divisions if it is something you need. I usually use them to do things like doubling the speed a specific instrument based on conditions, change the speed as an effect and so on… So I setup my sequencer to output many different divisions based on a main clock and then I can use Select with specific conditions to dynamically change between divisions.

2 Likes

yeah, i guess this makes a lot of sense :slight_smile: