Fibonacci Pattern
Projects > Performances > Stasi > Fibonacci Pattern
/* IZ 100520
Creating patterns that will send the structure of the fibonacci-tree
via OSC using automatically generated messages and arguments that reflect the structure of the tree.
In this version, the values generated by current = current + 1 are not used.
Other things could be substituted as contents of the leaves.
*/
Fib { // generates fibonacci trees
*ascending { | n = 3 | ^this.new.ascending(n) }
ascending { | n = 3 |
^{ | n = 1, prev = 1, current = 1 |
var next;
n do: {
next = [prev, current + 1];
prev = current;
current = next;
};
current;
}.(n)
}
*descending { | n = 3 | ^this.new.descending(n) }
descending { | n = 3 |
^{ | n = 1, prev = 1, current = 1 |
var next;
n do: {
next = [current + 1, prev];
prev = current;
current = next;
};
current;
}.(n)
}
}
Pfib : Prout { // creates patterns for playing fibonacci trees
var <>tree;
var <>startNode; // the node from which to start the playback
// nodes before this are skipped
var <>startFunc, <>endFunc;
var <count;
var <skip = false;
var <totalSize;
var <syncSender, <tempo;
*new { | tree, startNode, startFunc, endFunc |
^this.newCopyArgs(
nil,
tree ?? { Fib.ascending },
startNode,
startFunc ?? {{ | label, count, branch |
format("start %, %, %", label, count, branch.asArray.flat.size).postln;
}},
endFunc ?? {{ | label, count | format("end %, %", label, count).postln; }}
).init;
}
init {
var func;
count = 0;
totalSize = tree.asArray.flat.size;
func = { | tree, label = "", level |
this.skipOrBranch(startFunc, label, tree.asArray.flat.size, level);
if (tree.size == 0) {
count = count + 1;
if (skip.not) { tree.yield };
}{
thisFunction.(tree[0], label ++ "A", level + 1);
thisFunction.(tree[1], label ++ "B", level + 1);
};
this.skipOrBranch(endFunc, label);
};
routineFunc = { func.(tree, "", 0) };
if (startNode.notNil) { skip = true };
}
skipOrBranch { | func, label, size, level |
if (skip.not or: { label == startNode }) {
skip = false;
func.(label, count, size, level)
}
}
broadcast { | argSyncSender, type = "s", syncMessage, displayMessage = "branch" |
syncSender = argSyncSender;
syncMessage = syncMessage ? SyncSender.defaultSyncMessage;
displayMessage = type ++ "_" ++ displayMessage;
startFunc = { | label, count, size, level |
syncSender.broadcast(displayMessage, count, size, level, totalSize,
tempo = syncSender.clock.tempo,
totalSize / tempo / 60, // totalDuration in minutes
(totalSize - count) / tempo / 60 // remainingDuration in minutes
);
syncSender.broadcast(syncMessage, type ++ "_start_" ++ label, count, size, level);
};
endFunc = { | label, count |
syncSender.broadcast(syncMessage, type ++ "_end_" ++ label, count);
};
}
asPbind { | syncSender, type = "s", syncMessage, displayMessage = "branch" |
this.broadcast(syncSender, type, syncMessage);
syncMessage = syncMessage ? SyncSender.defaultSyncMessage;
^Pbind(type.asSymbol, this);
}
}