Recursive Routines ...?

Dear Community,
I have a triky Problem.
I’m need to have something like a recursive Routine.

My Problem is, that I have a Árray of Arrays of Pitches. Which should be played.
To do this, I have a Function which iterates over this Array.
Then it see the items of the Array is this is a Number it plays this Number, is it a Array it would recursively call his self, with the remainder Array.

So this will work Wonderful.

The Problems begin when this recursive Levels are interpreted as different Rhythmical Structures. So that on each Level the Duration to the next Pitch is given by respect on this Levels.

I try doing it by wait and yield. Which gives me the Idea to convert this Function to a Routine.

New this working as there is no recursive call. But is it it will broke the Process.

Any Ideas how to handle this

In hope of Solution

CreCo

You can check PSrecur from miSCellaneous_lib quark. It lets you define the recursion in a Function where you can refer to previous items with indices. E.g., this would define a Fibonacci sequence:

(
a = PSrecur({ |x| x[0] + x[1] }, start: [0, 1]);
b = a.iter;
b.nextN(10);
)

-> [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ]

The buffer size can be determined. PSrecur can also act as an Event pattern.

For recursion, I think this won’t work directly.

A standard recursive function requires an input. The classic example is a factorial, which shows all the parts: an exit condition (a branch which doesn’t recur, and which you’re guaranteed to reach eventually), and calling back into the same function with a different input.

~factorial = { |n|
    if(n <= 1) {
        1  // exit branch
    } {
        n * ~factorial.value(n - 1)
    }
};

But in a Routine that is playing on a clock, the input is already used. So a Routine by itself can’t implement the above design.

But you could write a Routine that calls a recursive function. I guess that’s your stumbling block – “convert this Function to a Routine” makes you think you should have a Routine instead of a function, but you really need a Routine that uses a function.

hjh

// build a recursive data structure
(
var p = Pseq([0, 2, 1, 4, 2, Pwhite(-3, -1, 1)], inf);
var build = { |array, stream, transpose, n, level|
	n.do {
		if(level > 0 and: { 0.5.coin }) {
			array = array.add(build.(Array.new, p.asStream, transpose + [1, 2, 3].choose, n * 0.5, level - 1))
		} {
			array = array.add(stream.next + transpose)
		}
	};
	array
};

a = build.(Array.new, p.asStream, 0, 32, 5);
)

(
var recurse = { |array, baseDelta|
	array.do { |item|
		if(item.isArray) {
			// recursive branch
			// "on each Level the Duration to the next Pitch is given by respect on this Levels"
			// --> baseDelta * 0.5, next lower level is twice as fast
			// you could use a different rule
			recurse.(item, baseDelta * 0.5)
		} {
			// non-recursive branch: single item, just yield it
			(degree: item, dur: baseDelta).yield
		}
	}
};

var dataRoutine = Routine { recurse.(a, 2) };

// note-playing routine
r = Routine {
	var event;
	while {
		event = dataRoutine.next.debug("event");
		event.notNil  // always need a termination condition!
	} {
		event.play;
		event.delta.wait
	};
}.play;
)

r.stop;

hjh

That’s the Solution !!! :smiley: :smile: :smile:

Very much Thanks to you jamshark70

A now very happy

CreCo