IvyTree.ck

From CSWiki
Jump to: navigation, search
// 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;
}