# How do you do FOR or WHILE loops in capytalk?

+1 vote
298 views

I'm creating a kind of sequencer that's relatively simple but with an interesting behaviour - it transposes itself over time in ever increasing length cycles. I'm calling it a "fractal sequencer".

Think of a four step sequencer. Once it completes a cycle, it spawns an outer cycle running at a quarter of the speed which transposes the original values. Once the outer cycle completes it spawns a further outer cycle that runs at a quarter of the speed again which transposes the inner two cycles... and so on and so on ad infinitum... or until you run out of processing power.

This algorithm was relatively easy to write in python using a while loop:

values = [-2, 7, -3, 0]  #the values of the four sequence steps
bpm = 600

seqlen = len(values)
scale = 2.0 ** (1/12.0)
middleC = 261.63
note0 = middleC / 32.0

value_range = 12    #A range limit so values don't run off to infinity

i = 0

while True:
positions = []

d, r = divmod(i, seqlen)
positions.append(r)
while d > 0:
d, r = divmod((d-1), seqlen)
positions.append(r)

value = 0
value_list = []
for pos in positions:
value = value + values[pos]
value_list.append(values[pos])

value = ((value + value_range) % (value_range * 2)) - value_range
beep(value + 60)

i += 1

It's not the most efficient algorithm. It maintains state solely by keeping a count of the current beat, which increments ad infinitum. It uses a while loop and mod function to work out how many outer loops to create and what step they would be on, then adds all the values together from all the loops to get the output value.

I can't see how to implement this in kyma / capytalk without using a FOR or WHILE loop and appending values to a list. Can you do that in capytalk? I want to do this in real-time, that is capytalk rather than smalltalk, because I want to be able to manually change the sequencer values while it's running.

Hi Alan,

Have you had a look at the Prototype called Self similar sequencer?  It comprises three, nested cyclic sequencers; each scales the durations (and adds an interval to the pitches) in the sequence to its left.

What if, instead, you nested two sequencers, the outer one running at a fraction of the rate of the inner one such that, when the fastest (inner) sequence finishes, the next sequencer to the right adds a transposition interval to all the pitches in the sequence to its left?  The outer sequencer's pitches (or extra value array) would function as a sequence of transposition intervals for the sequencer to its left.

answered Jan 6, 2017 by (Savant) (121,880 points)
Hi,

Yes that's exactly what I'm trying to do but instead of using two nested sequencers I'm using an infinite number... or rather every time the current outer sequencer completes a cycle I'm growing a new outer one at a fraction of the rate... And I keep doing that until I run out of processing power.. or I get bored.

So I need some kind of extending list, or a FOR loop or something so I can build up this nested structure at run-time.
You could use a Script to build an arbitrarily long chain of nested StepSequencers following the model of the Self similar sequencer.  Make the nesting levels a variable so you can experiment with how deep you can go before the durations become too short to hear any more.