Pdef set , how exactly?

\dur=1=one beat
\dur= 1.02= slightly more then 1 beat

Was late at night …wrong placement of \

Woow , that is seriously a lot of code to get them in sync , and all for some simple triplets that gets them out of sync .
Sigh
When usnig common time there is no issue at all
p.s. I know about the done Action being mostly relevant in the Amp env. , it was just old code that I never updated

But it’s not only getting them in sync… With Pdef, it’s very simple to reset on a barline, but you weren’t happy with that. You needed to be able to adjust patterns independently and resync dur on the barline. “I need something complicated… gosh, why isn’t it simple?”

After you’ve got a technique that you’re reasonably happy with, then it’s possible to package it into a class so that it’s easier to use. It’s very common in programming to hide the difficult implementation details within an object (kind of like, well, everything in sclang).

hjh

Well I don’t if it was that complicated
Up untill now I have used supercollider primarly as live environment ,recording straight to output,
Re-analyzing PDefs patterns with the use variables inside the pdefs that point to note -gate data, but that wasn’t fluint .at all .
So it’s pretty obvious one wants to switch patterns on the fly without interrupting , no ?
I will tackle it sooner or later :slight_smile:

The catch is, if I’m reading your requirement correctly, that you do want to interrupt the rhythm (sync back to the barline). This is fairly simple if you’re willing to interrupt the other members of the Pbind as well (i.e. you already know how to do this with plain Pdef).

The complication comes from interrupting one child stream (dur) while not interrupting the others.

hjh

What do you mean by childstreams , streams of the same Pdef ?
It ‘s pretty easy
Pdef 1 plays a kick at 4/4
Pdef 2 ( independent from pdef 1) plays a hihat pattern , \dur 1/4 .
With pbindef I can change the hihat pattern \dur from 1/8 to whatever I like , even throw in a new pseq , all without interupting .
Let’s call these variation patterns of our main hihat pattern .
As soon as I switch the hihat to a non common timing ( using a variation pbindef paytern) , the sync between the hihat an kick is lost .
It’s showcased in the examples with \dur 1.02 .

Did you try this example?

// changeable pattern
(
Pbindef(\kik).quant = -1;
Pbindef(\kik,
	\instrument, \kick,
	\dur, 1,
	\pitch, Pseq([50, 50], inf),
	\pdec, 0.8,
	\shamt, Pseq([2, 2, 2, 2], inf),
	\vol, 0.5,
	\out, 0,
);
)

TempoClock.tempo = 132/60;

// wrapper for bar sync
(
Pdef(\k).quant = -1;  // whole-bar
Pdef(\k, Pbindef(\kik).asStream);

Pdef(\k).play;
)

(
f = { |pbkey, playerKey ... pairs|
	// *pairs: see
	// http://doc.sccode.org/Overviews/SymbolicNotations.html#Where%20f%20is%20a%20function
	Pbindef(pbkey, *pairs);
	// try to reset on the next quant division
	Pdef(playerKey, Pdef(pbkey).asStream);  // rebuild this reference
};
)

// do this for one bar: 6 notes * 0.75 = 4.5
f.(\kik, \k, \dur, 0.75);

// this will chop the last note down to a 16th and land on the downbeat
f.(\kik, \k, \dur, 1);

For percussion, this is probably enough.

hjh

I thought it might be good to add some remarks about scheduling behavior.

TempoClock.sched(1, { "oh hi".postln });

sched takes now and adds the given number of beats (call it ‘time’), then puts the function/routine/task/event stream player into the clock’s queue at ‘time’.

When ‘time’ arrives, that “thing” gets popped out of the queue, and awake is called on it. Since this example uses a function: Function’s awake method just evaluates the function, passing in some time information. So it prints oh hi.

At this point, the return value is important. If it’s not a number, then it stops here. If it is a number, then a new time is calculated = now + that number, and the same thing gets put back into the queue at the new time. (“Return value” for a routine/task is the wait or yield value. For an event pattern like Pbind, it’s .delta on the event.)

SC’s timing is oriented towards time deltas, not toward metrical position.

So let’s take that 1.02 example, and call the reference barline 0.

  • Awake at 0, reschedule for 1.02.
  • Awake at 1.02, reschedule for 2.04.
  • Awake at 2.04, reschedule for 3.06.
  • Awake at 3.06, reschedule for 4.08.

But to re-sync for the bar line, you need 4.00, not 4.08.

So the pattern’s natural timing must be interrupted.

A key fact about scheduling is that there is no way to un-schedule anything: once it goes into the queue, it will awake. So in the original event stream player is going to wake up at 4.08. (How, then, does anything stop? The state of the object may be changed so that it does nothing upon awake.)

So to re-jigger the time, it’s necessary to deactivate the old event stream player, and schedule a new one for 4.0.

This is exactly what Pdef does when you replace the entire source pattern. It’s an all-new pattern, so it can’t use the old stream player – must deactivate it (one part of rescheduling) – and it must make a new one, which it’s free to schedule at a different time. So this (by luck!) happens to do both of the things that are needed for rescheduling.

Pbindef has a different purpose: to keep some of the streams running continuously, while replacing others.

For the unchanged streams to run continuously, it has to keep going with the same event stream player. So it does not automatically deactivate the old and replace it. So, under “natural” usage, there is no way for Pbindef to reschedule.

So the purpose of my code examples from yesterday was to force a new stream player to be scheduled on the bar line, while pulling data from a Pbindef.

For this, there are two possible cases:

  1. Maybe you want everything in the Pbindef to reset to the beginning. For kick and hi-hat, this is probably enough – if the other parameters are constant values, you can’t tell the difference between resetting and continuing. That’s my \kik and \k example.

  2. Or, maybe you want only the timing to go back to the bar line, while other streams keep going, unaffected. For instance, in an arpeggiator, you might want to change the rhythm but not break the note pattern. This is where it gets complicated, because you need to isolate the non-resetting data streams away from the timing stream.

    • Maybe you don’t need this yet, in which case, you could safely forget about that longer example.
    • Or maybe you do need it, in which case… just be prepared: with the main pattern library, this is never going to be as easy as you want it to be.

hjh

1 Like

If there is a way to retime and restart the Pdef while replaceing data with a pbindef , I guess that’s ok too
So it behaves like a Pdef that 's reanalayzed .

I’m pretty sure that’s the \kik and \k example that I posted yesterday.

hjh