From CSWiki
// ivyTree.ck
// v1.01
// written by Matthew Shanley
// matthewshanley@littlesecretsrecords.com
// Attributes:
// 0 - studio/home (0/1)
// 1 - no people/people sounds (0/1)
// 2 - harsh/pretty (0-9)
// 3 - noisy/tonal (0-9)
// 4 - low pitch/high pitch (0-9)
// declare global variables
// variables for working with sound files
sndbuf name00 => dac;
"data/morgan02norm.wav" => name00.read;
sndbuf name01 => dac;
"data/morgan03norm.wav" => name01.read;
sndbuf name02 => dac;
"data/morgan04norm.wav" => name02.read;
sndbuf name03 => dac;
"data/morgan05norm.wav" => name03.read;
sndbuf name04 => dac;
"data/morgan06norm.wav" => name04.read;
sndbuf name05 => dac;
"data/morgan07norm.wav" => name05.read;
sndbuf name06 => dac;
"data/morgan08norm.wav" => name06.read;
sndbuf name07 => dac;
"data/morgan09norm.wav" => name07.read;
sndbuf name08 => dac;
"data/morgan10norm.wav" => name08.read;
sndbuf name09 => dac;
"data/morgan11norm.wav" => name09.read;
sndbuf name10 => dac;
"data/morgan13norm.wav" => name10.read;
sndbuf name11 => dac;
"data/morgan14norm.wav" => name11.read;
sndbuf name12 => dac;
"data/morgan15norm.wav" => name12.read;
sndbuf name13 => dac;
"data/morgan16norm.wav" => name13.read;
sndbuf name14 => dac;
"data/morgan17norm.wav" => name14.read;
sndbuf name15 => dac;
"data/morgan18norm.wav" => name15.read;
sndbuf name16 => dac;
"data/my-pulses.aif" => name16.read;
sndbuf name17 => dac;
"data/recording1.wav" => name17.read;
sndbuf name18 => dac;
"data/recording2.wav" => name18.read;
sndbuf name19 => dac;
"data/recording3.wav" => name19.read;
sndbuf name20 => dac;
"data/talking01.wav" => name20.read;
sndbuf name21 => dac;
"data/talking02.wav" => name21.read;
sndbuf name22 => dac;
"data/talking03.wav" => name22.read;
sndbuf name23 => dac;
"data/talking04.wav" => name23.read;
sndbuf name24 => dac;
"data/talking05.wav" => name24.read;
sndbuf name25 => dac;
"data/talking06.wav" => name25.read;
26 => int numFiles;
// attributes for files
5 => int NUM_ATTRIBS; // number of attrib digits
63400 => int attrib00;
72510 => int attrib01;
55300 => int attrib02;
66500 => int attrib03;
44400 => int attrib04;
23410 => int attrib05;
32310 => int attrib06;
22310 => int attrib07;
52410 => int attrib08;
63300 => int attrib09;
76000 => int attrib10;
76610 => int attrib11;
53400 => int attrib12;
63610 => int attrib13;
46600 => int attrib14;
32300 => int attrib15;
93911 => int attrib16;
65001 => int attrib17;
31301 => int attrib18;
07401 => int attrib19;
75711 => int attrib20;
59911 => int attrib21;
60411 => int attrib22;
63611 => int attrib23;
35711 => int attrib24;
55911 => int attrib25;
// global flags to determine whether branches and leaves are alive
0 => int branch0alive; // first branch
0 => int branch1alive; // second branch
0 => int branch2alive; // third branch
0 => int leaf00alive; // first branch, first leaf
0 => int leaf01alive; // first branch, second leaf
0 => int leaf02alive; // first branch, third leaf
0 => int leaf10alive; // second branch, first leaf
0 => int leaf11alive; // second branch, second leaf
0 => int leaf12alive; // second branch, third leaf
0 => int leaf20alive; // third branch, first leaf
0 => int leaf21alive; // third branch, second leaf
0 => int leaf22alive; // third branch, third leaf
// resources used by the creation and destruction of branches and leaves
10 => int resources;
10 => int BRANCH_MAX_RANDOM; // setting for determining random branch creation
1 => int BRANCH_CREATION_THRESH; // for randomly determining whether to grow a branch
2 => int BRANCH_DEATH_RANDOM; // for randomly determining whether branch dies
0 => int BRANCH_DEATH_THRESH; // for randomly determining whether branch dies
15 => int LEAF_MAX_RANDOM; // setting for determining random leaf creation
2 => int LEAF_CREATION_THRESH; // for randomly determining whether to grow a leaf
// constants determining timing of looping events
19 => int BRANCH_TIMING; // in seconds, time between maybe growing leaves
11 => int ROOT_TIMING; // in seconds, time between maybe growing branches
// make a number into a digit in a given position
fun int makeDigit(int pos, int num) {
return(num*(int)math.pow(10.0, (float)pos));
}
// return the digit from whole of a given position
fun int getDigit(int pos, int whole) {
return (int)((whole%(int)math.pow((10.0, (float)(pos+1))))/(int)math.pow(10.0, (float)pos));
}
// return an attribute int determined randomly
fun int makeRandAttrib() {
return (makeDigit(4, std.rand2(0,9)) + makeDigit(3, std.rand2(0,9)) + makeDigit(2, std.rand2(0,9)) + makeDigit(1, std.rand2(0,1)) + makeDigit(0, std.rand2(0,1)));
}
// return a weight int determined randomly
fun int makeRandWeight() {
return (makeDigit(4, std.rand2(0,9)) + makeDigit(3, std.rand2(0,9)) + makeDigit(2, std.rand2(0,9)) + makeDigit(1, std.rand2(0,9)) + makeDigit(0, std.rand2(0,9)));
}
// returns the count of how many leaves are on a given branch
fun int countLeaves(int branchNum) {
0 => int count;
if (branchNum == 0) {
if (leaf00alive) { count + 1 => count; }
else if (leaf01alive) { count + 1 => count; }
else if (leaf02alive) { count + 1 => count; }
}
else if (branchNum == 1) {
if (leaf10alive) { count + 1 => count; }
else if (leaf11alive) { count + 1 => count; }
else if (leaf12alive) { count + 1 => count; }
}
else if (branchNum == 2) {
if (leaf20alive) { count + 1 => count; }
else if (leaf21alive) { count + 1 => count; }
else if (leaf22alive) { count + 1 => count; }
}
chout => " branch " => branchNum => " has " => count => " leaves" => endl;
return count;
}
// return the attributes for a file of a given number
fun int getAttrib(int fileNum) {
if (fileNum == 00) { return attrib00; }
else if (fileNum == 01) { return attrib01; }
else if (fileNum == 02) { return attrib02; }
else if (fileNum == 03) { return attrib03; }
else if (fileNum == 04) { return attrib04; }
else if (fileNum == 05) { return attrib05; }
else if (fileNum == 06) { return attrib06; }
else if (fileNum == 07) { return attrib07; }
else if (fileNum == 08) { return attrib08; }
else if (fileNum == 09) { return attrib09; }
else if (fileNum == 10) { return attrib10; }
else if (fileNum == 11) { return attrib11; }
else if (fileNum == 12) { return attrib12; }
else if (fileNum == 13) { return attrib13; }
else if (fileNum == 14) { return attrib14; }
else if (fileNum == 15) { return attrib15; }
else if (fileNum == 16) { return attrib16; }
else if (fileNum == 17) { return attrib17; }
else if (fileNum == 18) { return attrib18; }
else if (fileNum == 19) { return attrib19; }
else if (fileNum == 20) { return attrib20; }
else if (fileNum == 21) { return attrib21; }
else if (fileNum == 22) { return attrib22; }
else if (fileNum == 23) { return attrib23; }
else if (fileNum == 24) { return attrib24; }
else { return attrib25; }
}
// return the name for a file of a given number
fun sndbuf getName(int fileNum) {
if (fileNum == 00) { return name00; }
else if (fileNum == 01) { return name01; }
else if (fileNum == 02) { return name02; }
else if (fileNum == 03) { return name03; }
else if (fileNum == 04) { return name04; }
else if (fileNum == 05) { return name05; }
else if (fileNum == 06) { return name06; }
else if (fileNum == 07) { return name07; }
else if (fileNum == 08) { return name08; }
else if (fileNum == 09) { return name09; }
else if (fileNum == 10) { return name10; }
else if (fileNum == 11) { return name11; }
else if (fileNum == 12) { return name12; }
else if (fileNum == 13) { return name13; }
else if (fileNum == 14) { return name14; }
else if (fileNum == 15) { return name15; }
else if (fileNum == 16) { return name16; }
else if (fileNum == 17) { return name17; }
else if (fileNum == 18) { return name18; }
else if (fileNum == 19) { return name19; }
else if (fileNum == 20) { return name20; }
else if (fileNum == 21) { return name21; }
else if (fileNum == 22) { return name22; }
else if (fileNum == 23) { return name23; }
else if (fileNum == 24) { return name24; }
else { return name25; }
}
// returns measurement of how good given attributes are based on given weights
fun int measureAttrib(int attrib, int optimal, int weights) {
0 => int count;
0 => int i;
for (0 => i; i < 2; i++) {
if (getDigit(i, attrib) == getDigit(i, optimal)) {
count + (9 * getDigit(i, weights)) => count;
}
}
for (2 => i; i < NUM_ATTRIBS; i++) {
count + (getDigit(i, weights) * (9-(int)std.abs((float)(getDigit(i, attrib)-getDigit(i, optimal))))) => count;
}
return count;
}
// pick a file to be assigned to a leaf being grown
fun int pickFile(int optimal, int weights) {
int newFile;
26 => int bestFile;
for (0 => int i; i < std.rand2(1, 5); i++) {
std.rand2(00, 25) => newFile;
if ((bestFile == 26) || (measureAttrib(getAttrib(newFile), optimal, weights) > measureAttrib(getAttrib(bestFile), optimal, weights))) { newFile => bestFile; }
}
return bestFile;
}
// lowest "child" stage of sporking
fun void leaf(int leafNum, sndbuf soundFile, int vol) {
chout => " LEAF" => leafNum => ": I am alive. vol=" => vol => endl;
// set the gain for the buffer (0-405 range)
(float)vol / 300.0 => float fVol;
if (fVol > 1.0) { 1.0 => fVol; }
chout => " LEAF" => leafNum => ": gain=" => fVol => endl;
fVol => soundFile.gain;
// play through once
0 => soundFile.pos;
soundFile.length => now;
chout => " LEAF" => leafNum => ": I am dying." =>endl;
resources + 1 => resources;
if (leafNum == 00) { 0 => leaf00alive; }
else if (leafNum == 01) { 0 => leaf01alive; }
else if (leafNum == 02) { 0 => leaf02alive; }
else if (leafNum == 10) { 0 => leaf10alive; }
else if (leafNum == 11) { 0 => leaf11alive; }
else if (leafNum == 12) { 0 => leaf12alive; }
else if (leafNum == 20) { 0 => leaf20alive; }
else if (leafNum == 21) { 0 => leaf21alive; }
else if (leafNum == 22) { 0 => leaf22alive; }
}
// middle "parent" stage of sporking
fun void branch(int branchNum, int optimal, int weights) {
00 => int nextLeaf; // next leaf to grow
chout => " BRANCH" => branchNum => ": I am alive. optimal=" => optimal => " weights=" => weights => endl;
while(true) {
if(resources>0 && std.rand2(0, (LEAF_MAX_RANDOM-resources-countLeaves(branchNum)))<=LEAF_CREATION_THRESH) {
if (branchNum == 0) {
if (!leaf00alive) { 00 => nextLeaf; }
else if (!leaf01alive) { 01 => nextLeaf; }
else if (leaf02alive) { 02 => nextLeaf; }
}
else if (branchNum == 1) {
if (!leaf10alive) { 10 => nextLeaf; }
else if (!leaf11alive) { 11 => nextLeaf; }
else if (!leaf12alive) { 12 => nextLeaf; }
}
else if (branchNum == 2) {
if (!leaf20alive) { 20 => nextLeaf; }
else if (!leaf21alive) { 21 => nextLeaf; }
else if (!leaf22alive) { 22 => nextLeaf; }
}
else { 30 => nextLeaf; }
if (nextLeaf < 30) {
chout => " BRANCH" => branchNum => ": I am growing leaf number " => nextLeaf => endl;
resources - 1 => resources;
if (nextLeaf == 00) { 1 => leaf00alive; }
else if (nextLeaf == 01) { 1 => leaf01alive; }
else if (nextLeaf == 02) { 1 => leaf02alive; }
else if (nextLeaf == 10) { 1 => leaf10alive; }
else if (nextLeaf == 11) { 1 => leaf11alive; }
else if (nextLeaf == 12) { 1 => leaf12alive; }
else if (nextLeaf == 20) { 1 => leaf20alive; }
else if (nextLeaf == 21) { 1 => leaf21alive; }
else if (nextLeaf == 22) { 1 => leaf22alive; }
pickFile(optimal, weights) => int leafFile;
spork ~ leaf(nextLeaf, getName(leafFile), measureAttrib(getAttrib(leafFile), optimal, weights)); // crap arguments
}
}
if (countLeaves(branchNum)==0 && std.rand2(0, BRANCH_DEATH_RANDOM)<=BRANCH_DEATH_THRESH) { // death clause
chout => " BRANCH" => branchNum => ": I am dying." => endl;
resources + 1 => resources;
if (branchNum == 0) { 0 => branch0alive; }
else if (branchNum == 1) { 0 => branch1alive; }
else if (branchNum == 2) { 0 => branch2alive; }
return;
}
chout => " BRANCH" => ": resources=" => resources => endl;
BRANCH_TIMING::second => now;
}
}
// initial "grandparent" stage of sporking
fun void root() {
0 => int nextBranch; // next branch to grow
chout => "ROOT: I am alive!" => endl;
chout => "ROOT: resources=" => resources => endl;
while(true) {
if (resources>0 && std.rand2(0, (BRANCH_MAX_RANDOM-resources))<=BRANCH_CREATION_THRESH) {
if (!branch0alive) { 0 => nextBranch; }
else if (!branch1alive) { 1 => nextBranch; }
else if (!branch2alive) { 2 => nextBranch; }
else { 3 => nextBranch; }
chout => "ROOT: nextBranch=" => nextBranch => endl;
if (nextBranch < 3) {
chout => "ROOT: I am growing branch number " => nextBranch => endl;
resources - 1 => resources;
if (nextBranch == 0) { 1 => branch0alive; }
else if (nextBranch == 1) { 1 => branch1alive; }
else if (nextBranch == 2) { 1 => branch2alive; }
spork ~ branch(nextBranch, makeRandAttrib(), makeRandWeight());
}
}
chout => "ROOT: resources=" => resources => endl;
chout => "ROOT: branch0alive=" => branch0alive => endl;
chout => "ROOT: branch1alive=" => branch1alive => endl;
chout => "ROOT: branch2alive=" => branch2alive => endl;
ROOT_TIMING::second => now;
}
}
// call root
root();
while (true) {
1::second => now;
}