Controling complex "playable object"

I’m trying to build a way to control, with patterns, a complex “playable object”, which is the sum of different synths played at different times.

If a regular PBind could be represented this way ( a synth replayed at each Pbind event):

pbind

And a Pmono like ( a synth played once, and modified at each Pmono event):
pmono

What I’m trying to do, is this:

a complex “playable object” that I could play on and on, and control like a Synth with a Pbind.

I’ve already taken one approach. It’s a kind Timeline and Nodes mechanism (the code is here).

And I would use like this:

~loop=StTimeline.new();
~n1=~loop.addNode(
	StNode.new(name: "node1", start: 0,
		action: {
			~yellow=Synth.newPaused(\yellowSynth);
			~green=Synth.newPaused(\greenSynth,addAction: 'addToTail');
			~blue=Synth.newPaused(\blueFilter,addAction: 'addToTail');
			~yellow.run;
	}, actionArgs: [])
);
...
~n8=~loop.addNode(
	StNode.new(name: "node8", dependOn: ~n7, start: 7.5,
		action: {
			~yellow.release;
			~black.run;
	}, actionArgs: [])
);
...

// build timeline control
(
~ready=Condition.new(false);
NotificationCenter.register(~n9,\done,this,{~ready.unhang;});
)

// play loop
(
~r={
	~gate=1;
	while({~gate>0},
		{
		// add some variations
		~n8.start=5+4.0.rand2;
		~n5.set(\freq,~n5.get(\freq)*1.5.rand2);
		// play 
		~loop.play(TempoClock(1));
		~ready.hang;
		}
	);
}.fork;
)

It’s working well.
It allows dependencies between nodes (StNode.new(dependOn: ~n7), manually holding at some points (StNode.new(holdCondition:~hold2), looping within the pattern (as a sampler would do: StNode.new(loopAt:~n3), defining from which node the timeline should be retriggered (NotificationCenter.register(~n8,\done,this,{~ready.unhang;}) ), …

But I miss the flexibility of the patterns, and their “neatness”, their concision.

So I’m here, wondering if I could achieve this “playable object” in some other ways in a pure Pattern style, or if I could introduce patterns in my current Timeline approach.

Any advice ?

Hi,

looking at your graphics, I conclude that you are wanting a kind of compound structure. Two objects come into my mind:

.) Pspawner, one of the most flexible meta-patterns, could be you used to sequence your playable objects.

.) As fxs seem to be a relevant part of playable objects, have a look at PbindFx from miSCellaneous, basically it’s for applying fxs on a per-event base.

I cannot estimate how these two Patterns go together with your timeline approach, but I suppose it should be possible to include them in such a framework.
Other than that, maybe Pspawner itself could be used to introduce a timeline approach.

1 Like

Thanks. I’ll have a look at this.

Maybe you can find useful the recursive phrasing of Pdef, it allow you to control a pattern with a Pbind as if it was a Synth:

TempoClock.default.tempo = 1;
(
SynthDef(\fx_freeverb2, { arg out=0, gate=1;
	var sig;
	var in = InFeedback.ar(\inbus.kr(0), 2); 
	sig = in;
	sig = FreeVerb2.ar(sig[0],sig[1], \verbmix.kr(1), \room.kr(0.5), \damp.kr(0.5));
	sig = SelectX.ar(\mix.kr(0.5), [in, sig]);
	sig = sig * EnvGen.ar(Env.adsr(0.01,0,1,0.01),gate,doneAction:2);
	sig = sig * \gain.kr(1);
	Out.ar(out, sig);
}).add;
~bus1 = ~bus1 ?? { Bus.audio(s,2) }
)


(
Pdef(\player1, { arg freq, amp;

	Ptpar([
		0, Pbind(
			\instrument, \default,
			\freq, freq * Pseq([0,7,2,1],inf).midiratio,
			\dur, 1/4,
			\amp, amp,
			\out, topEnvironment[\bus1], // we are in another Environment
		),
		0, Pmono(\fx_freeverb2,
			\inbus, topEnvironment[\bus1],
			\addAction, \addToTail,
			\lag, 0.0009,
			\dur, 1,
		),		
		1, Pbind(
			\instrument, \default,
			\freq, freq*2,
			\dur, 1,
			\amp, amp,
		),
	])
})
);

(
Pdef(\player2, { arg blast=1, note, amp;
	Ppar(
		blast.collect({ arg idx;
			Pbind(
				\instrument, \default,
				\note, Pseq([
					0,5,2,
				],inf) + note,
				\lag, 1/8/4 * idx,
				\dur, 1/8,
				\amp, amp,
			)
		})
	)
})
);


(
Pdef(\main, 
	Pseq([
		Pbind(
			\type, \phrase,
			\instrument, \player1,
			\freq, 400 * Pseq([1,1/2],1),
			\legato, 0.7,
			\dur, 4,
			\amp, 0.1,
		),
		Pbind(
			\type, \phrase,
			\instrument, \player2,
			\note, Pseq([0,6],2), 
			\blast, Pseq([
				1,2,3,4,
			],inf),
			\legato, 1,
			\dur, 1,
			\amp, 0.1,
		),
	],2),
).play;
);


Look for recursive phrasing in doc

1 Like