{
   "labels" : [
      "composition"
   ],
   "id" : "1-4Qp",
   "is_private" : null,
   "code" : "(\r\nServer.internal.waitForBoot({\r\n\tvar clock = TempoClock(4);\r\n\tvar bus = 8;\r\n\tvar channels = 2; // per bus\r\n\tPproto(\r\n\t\t{\r\n\t\t\tvar out = ~out = (type: \\audioBus, channels: channels * bus).yield.out;\r\n\t\t\t{ // or multichannel diskout\r\n\t\t\t\tOut.ar(0, Mix(In.ar(~out, channels * bus).clump(channels))) \r\n\t\t\t}.play(Server.internal);\r\n\t\t\t{ Stethoscope(Server.internal, channels * bus, out, zoom:1/4).toggleSize }.defer;\r\n\t\t},\r\n\t\tPspawn(\r\n\t\t\tPbind(*[ // or maybe ppar for independent partition \r\n\t\t\t\tmethod: \\par,\r\n\t\t\t\ttag: Pwrand([\\break,\\steady,\\transit], [1,3,1].normalizeSum, inf), // part tag - Pfsm?..\r\n\t\t\t\trepeatability: Pwrand([true,false], [0.1,0.9], inf),\r\n\t\t\t\tdelta: Pfunc({ |ev| // set part duration and pattern\r\n\t\t\t\t\tev.dur = (8,12..16).choose;\r\n\t\t\t\t\tev.param = ev.dict.param.next(());\r\n\t\t\t\t\tev.pattern = ev.retrieve;\r\n\t\t\t\t\tev.dur;\r\n\t\t\t\t})\r\n\t\t\t]),\r\n\t\t\t( // proto event used as object\r\n\t\t\t\tretrieve: { |ev|\r\n\t\t\t\t\tvar pat = ev.dict.selector(ev);\r\n\t\t\t\t\tev.repeatability.and(ev.archive.size > 0).if({ // add some already played part\r\n\t\t\t\t\t\tvar part = ev.archive.choose;\r\n\t\t\t\t\t\tev.dur = ev.dur + part[1].dur;\r\n\t\t\t\t\t\tpat = Pseq([ part[0], pat ]);\r\n\t\t\t\t\t});\r\n\t\t\t\t\tev.archive.add([pat, (dur: ev.dur)]); // backup part\r\n\t\t\t\t\tpat;\r\n\t\t\t\t},\r\n\t\t\t\tdict: ( \r\n\t\t\t\t\tparam: Pbind(*[ // common part params\r\n\t\t\t\t\t\tintensity: Pbrown(),\r\n\t\t\t\t\t\tvariability: Pbrown(),\r\n\t\t\t\t\t]).asStream,\r\n\t\t\t\t\tselector: { |self, ev| // selects first combinator with nearest common param\r\n\t\t\t\t\t\tself.find(\\combinators, ( tags: ev.tag.asArray, param: ev.param )).first.fn(ev);\r\n\t\t\t\t\t},\r\n\t\t\t\t\tcombinators: [ // tagged part variants\r\n\t\t\t\t\t\t( tags:[\\steady], param: (intensity: 0.5), fn: { |self, ev| \r\n\t\t\t\t\t\t\tPfindur( ev.dur * 1.rrand(4), Pbindf(\r\n\t\t\t\t\t\t\t\tev.bag.rnd(ev, Pseq([1,2],inf)),\r\n\t\t\t\t\t\t\t\t\\octave, self.state.octave.next\r\n\t\t\t\t\t\t\t))\r\n\t\t\t\t\t\t}, state: ( octave: Prand((2..6), inf).asStream ) ),\r\n\t\t\t\t\t\t( tags:[\\break], param: (intensity: 0.5), fn: { |self, ev| \r\n\t\t\t\t\t\t\tPfindur( ev.dur * 1.rrand(4), Pbindf(\r\n\t\t\t\t\t\t\t\tev.bag.rnd(ev, Pbrown(1/16,2,1.rrand(4)/16)),\r\n\t\t\t\t\t\t\t\t\\note, Pbrown(0,22,1.rrand(4)),\r\n\t\t\t\t\t\t\t\t\\octave, 2.rrand(5)\r\n\t\t\t\t\t\t\t))\r\n\t\t\t\t\t\t}),\r\n\t\t\t\t\t\t( tags:[\\transit], param: (intensity:0.5), fn: { |self, ev|\r\n\t\t\t\t\t\t\tPfindur( ev.dur, ev.bag.rnd(ev, ev.dur * 2.rrand(3)) )\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t],\r\n\t\t\t\t\tfind: { | self, type, params | // function for to search pattern by tags and sort by distance to param\r\n\t\t\t\t\t\tself.at(type).select({ |i,n| // select by tag\r\n\t\t\t\t\t\t\t(i.includesKey(\\tags).if({i.tags},{[]})).includesAll(params.tags); \r\n\t\t\t\t\t\t}).collect({ |i,n|\r\n\t\t\t\t\t\t\t[ i, params.param.keys.sect(\r\n\t\t\t\t\t\t\t\ti.includesKey(\\param).if({i.param.keys},{[]})\r\n\t\t\t\t\t\t\t).collect({ |k| i.param[k] sqrdif: params.param[k] }).sum ];\r\n\t\t\t\t\t\t}).sort({ |a, b| a[1] < b[1] }).collect({ |i| i[0] }); // sort by params\r\n\t\t\t\t\t}\r\n\t\t\t\t),\r\n\t\t\t\tbag: ( // simple key-value store\r\n\t\t\t\t\trnd: { |self, ev, dur| Pbind(*[\r\n\t\t\t\t\t\tdelta: dur,\r\n\t\t\t\t\t\tdur: Pkey(\\delta) * Pfunc({ thisThread.clock.beatDur }) / 1.rrand(4),\r\n\t\t\t\t\t\tamp: Pseg(Pbrown(0.1, 0.5), Pseq(ev.dur.partition(ev.dur,1/16)), \\sine, inf),\r\n\t\t\t\t\t\tnote: Pbrown(0,11,1.rrand(4)),\r\n\t\t\t\t\t\tout: Pkey(\\out) + (bus.rand * 2),\r\n\t\t\t\t\t\tpan: Pstutter(1.exprand(16), Pbrown(-0.9,0.9,0.1.rrand(0.8)))\r\n\t\t\t\t\t]) }\r\n\t\t\t\t),\r\n\t\t\t\tarchive: [] // already played patterns\r\n\t\t\t)\r\n\t\t)\r\n\t).play(clock, (server:Server.internal));\r\n})\r\n)",
   "name" : "composition barebone",
   "author" : "vividsnow",
   "ancestor_list" : [],
   "description" : "attempt to create abstraction for composition based on spawning parts using tags and distance between numerical params (check \"find\" function)"
}
