Cellular Automata: Pattern classes and UGens

I’m not sure whether I’ve understood correctly, but I would do something like this

(
var a=Array.fill(7, {|i| choose([0,1])}), m=[31,43,57,64,70,76,77].midicps;
var p=Pca1(a, 90, inf);
var x=p.asStream;

//mapping between 0-1 automata list and corresponding values
//return an array, when 1 then returns the corresponding value, otherwise returns 0
~interpret={|list, values| //
	var out=Array.new(list.size);
	list.do({|item, ind|
		if (item==1, 
			{out.add(values[ind])},
			{out.add(0)}
		);
		
	});
	out;
};

Routine.new({
	20.do({
		var pitches=~interpret.value(x.next, m);
		{Mix.new(SinOsc.ar(pitches, 0, 0.5)*EnvGen.ar(Env.perc(0.01,0.4), 1, 0.3, doneAction:2))}.play;
				0.4.wait;
	});
}).play;

);

hey thanks for your help.
My idea was to convert the Midi notes of the specific Chord Voicing to degrees of the corresponding scale, create an Array and fill it with 0 and 1.
the function should go through the Scale (multiple octaves) by step and always put a 1 in the Array if there is a match with a note of the chord and put a 0 in the Array if not.
The iteration should end when the last item of the chord has been put in the new Array.
I will have a look at your example, many thanks for sharing :slight_smile:

your idea is really great for staying within a specific set of pitches. thanks
would be nice if someone would also have an idea for the other approach :slight_smile:

I using your ~interpret function and was trying to use Pdefn or PL to access the notes dynamically outside a Pbind. unfortunately its not working. any ideas for adjusting the Pfunc in \midinote?

(
SynthDef(\test, {
	arg out=0, pan=0, amp=0.35, freq=150;
	var env = EnvGen.ar(Env.perc(0.01,0.4), 1, 0.3, doneAction:2);
	var sig = SinOsc.ar(freq);
	sig = Pan2.ar(sig, pan, amp * env);
	Out.ar(out, sig);
}).add;
)

(
~interpret={
	arg list, values;
	var out=Array.new(list.size);
	list.do({|item, ind|
		if (item==1,
			{out.add(values[ind])},
			{out.add(0)}
		);

	});
	out;
};
)

(
Pdefn(\notes, [31,43,57,62,70,76,77]);

Pdef(\test,
	Pbind(
		\instrument, \test,

		\dur, 0.5,

		\midinote, Pfunc {
			~interpret.value(
				Pca1(Array.fill(~m.size, {|i| choose([0,1])}), 90, inf).asStream.next,
				~m
				//Pdefn(\notes)
				//PL(\m)
			)
		}.trace,

		\amp, 0.25,
		\out, 0,
	)
).play;

fork {
	loop {
		~m = [31,43,57,62,70,76,77];
		//Pdefn(\notes, [31,43,57,62,70,76,77]);
		4.wait;
		~m = [31,43,53,58,64,72,76,81];
		//Pdefn(\notes, [31,43,53,58,64,72,76,81]);
		4.wait;
		~m = [31,43,55,62,64,69,74];
		//Pdefn(\notes, [31,43,55,62,64,69,74]);
		4.wait;
	}
}
)

ive also seen that my pattern implementation is wrong. the array is constantly creating a new set of items (was using .debug) and not only when its initialized. so the progression is unfortunately not created by Pca1, its created by the updated array. any ideas how to implement the function into the Pbind in the right way?

EDIT: I could mangage to fix this issue. the other with PL and Pdefn still remains.

(
SynthDef(\test, {
	arg out=0, pan=0, amp=0.35, freq=150;
	var gainEnv = EnvGen.ar(Env.perc(0.01,0.4), 1, 0.3, doneAction:2);
	var sig = SinOsc.ar(freq);
	sig = sig * gainEnv;
	sig = Pan2.ar(sig, pan, amp);
	Out.ar(out, sig);
}).add;
)

(
~interpret={
	arg list, values;
	var out=Array.new(list.size);
	list.do({|item, ind|
		if (item==1,
			{out.add(values[ind])},
			{out.add(0)}
		);

	});
	out;
};
)

(
~m = [31,43,57,62,70,76,77];
//Pdefn(\notes, [31,43,57,62,70,76,77]);

Pdef(\test,
	Pbind(
		\instrument, \test,
		\dur, 0.5,

		\rule, 90,
		\cellular, Pca1(Array.fill(~m.size, { |i| 2.rand }).debug, Pkey(\rule).trace, inf).asStream,
		\midinote, Pn(Plazy {|event|
			Pseq([~interpret.value(event[\cellular].next, ~m)], 1)
			}, inf).trace,

		\amp, 0.25,
	)
).play;

fork {
	loop {
		~m = [31,43,57,62,70,76,77];
		//Pdefn(\notes, [31,43,57,62,70,76,77]);
		8.rand.wait;
		~m = [31,43,53,58,64,72,76,81];
		//Pdefn(\notes, [31,43,53,58,64,72,76,81]);
		8.rand.wait;
		~m = [31,43,55,62,64,69,74];
		//Pdefn(\notes, [31,43,55,62,64,69,74]);
		8.rand.wait;
	}
}
)
1 Like

I think there is also another issue when you change m~ to an array with fewer elements then the initial array with 0 and 1 is not matching anymore, or?