PNDSteps Superclass: ArrayNDPattern PNDSteps is a Pattern that operates on a multidimensional Array (ArrayND). You would need to get a version of ArrayND.sc for this to work. This class does in N dimensions about what Pseq or Pser do in 1. In a sence Pseq or Pser could be 'subclasses' of PNDSteps if N turns out to be 1. You supply an ArrayND filled with whatever you like. PNDSteps gives you the ability to 'wander' around in its N-dimensional space and returns the items from it. Creation new(arrayND, steps, startPositions, edges, repeats) creates a new PNDSteps. steps, startPositions and edges are supplied as arrays (just like [1,1,1] or [\fold, \wrap]) steps give the progress for each dimension. startPositions gives the offset in each dimension. edges set the behavior for the edges in each dimension. \fold and \wrap are allowed values. '\fold' is the default Changing progress in one dimension freezeStp(index) sets steps for dimension index zero. mirrorStp(index) sets steps for dimension index to its negative. cushStp(index) decreases steps for dimension index by one. boostStp(index) increases steps for dimension index by one. mirrorcushStp(index) decreases steps for dimension index by one and set it to its negative. mirrorboostStp(index) increases steps for dimension index by one and set it to its negative. randStp(index, n) randomize steps for dimension index with n.rand Changing progress in all dimensions freezeStpAll sets all steps to zero. mirrorStpAll sets all steps to their negative. ******All sets all steps to what the ****** does for one dimension rotateStpAll(n) rotates the steps Array for n = 1 it does [1, 2, 3] -->> [3, 1, 2] Examples ( // simple step example with wrap edges var array, a, b; // ArrayND fill creation in 2 dimensions array = ArrayND.fill([6,5], {arg pos;(1*pos.at(0))+(10*pos.at(1))+11 }); array.postln; // increasing by one for each dimension with wrap edges a = PNDSteps.new(array, [1,1], [0,0], [\wrap,\wrap],inf); b = a.asStream; 12.do({ b.next.postln; }); ) ( // same as above using fold edges var array, a, b; // ArrayND fill creation in 2 dimensions array = ArrayND.fill([6,5], {arg pos;(1*pos.at(0))+(10*pos.at(1))+11 }); array.postln; // increasing by one for each dimension this time with fold edges (mirror) a = PNDSteps.new(array, [1,1], [0,0], [\fold,\fold],inf); b = a.asStream; 12.do({ b.next.postln; }); ) ( // the cheesy music? example // you would rather fill your arrayND with other arrayNDs that hold // a whole world of parameters for your instrument fuction instead var modarray, valarray, valpnd, stream, trig, out; valarray = ArrayND.fill([8,7], {arg pos; pos.at(1)+1*0.4*pos.at(0)+40}); valarray.postln; valpnd = PNDSteps.new(valarray, [1,2], [1,0], [\fold,\fold],inf); stream = valpnd.asStream; { trig = Impulse.kr(6); out = LFSaw.ar( freq: Sequencer.kr( stream, trig ).midicps, mul: Decay2.kr(trig, 0.1, 0.4, 0.25) ); out = [out, DelayN.ar(out, 0.04, 0.04) ]; out }.play; ) ( // shure enough you can nest ArrayNDPatterns with other Patterns var a, b; a = Prand.new([ PNDSteps.new( ArrayND.fill([3,2], {arg pos;[-2,-4].choose }), [1,1], //steps [0,0], //offsets [\fold,\wrap], //edges 4 // repeats ), PNDSteps.new( ArrayND.fill([4,3], {arg pos;(1*pos.at(0))+(10*pos.at(1))+22 }), [1,1], //steps [1,1], //offsets [\wrap,\wrap], //edges 6 // repeats ), Pseq.new([5, 6], 2) ], 3); b = a.asStream; 13.do({ b.next.postln; }); ) ( // a gui patch to change progress online var guiarray, pnd, stream, trig, playfunc, hold; w = GUIWindow.new("panel", Rect.newBy(260, 100, 514, 460)); guiarray = ArrayND.fill([19,18], {arg pos; ButtonView.new( w, Rect.newBy(pos.at(0)*10+30, pos.at(1)*10+30, 7, 7), "", 0, 0, 1, 0, 'linear') .backColor_(Color.white); }); pnd = PNDSteps.new(guiarray, [1,1], [1,0], [\fold,\fold],inf); stream = pnd.asStream; hold = guiarray.at(0,0); ButtonView.new( w, Rect.newBy(30, 244, 104, 22), "fold", 0, 0, 1, 0, 'linear') .action_({pnd.edges_([pnd.edges.at(0),\fold]) }); ButtonView.new( w, Rect.newBy(30, 270, 104, 22), "wrap", 0, 0, 1, 0, 'linear') .action_({pnd.edges_([pnd.edges.at(0),\wrap]) }); ButtonView.new( w, Rect.newBy(331, 199, 104, 22), "freezeall", 0, 0, 1, 0, 'linear') .action_({pnd.freezeStpAll}); ButtonView.new( w, Rect.newBy(334, 276, 104, 22), "steps [2,2]", 0, 0, 1, 0, 'linear') .action_({pnd.steps_([2,2])}); ButtonView.new( w, Rect.newBy(333, 249, 104, 22), "steps [1,2]", 0, 0, 1, 0, 'linear') .action_({pnd.steps_([1,2])}); ButtonView.new( w, Rect.newBy(335, 302, 104, 22), "steps [1,1]", 0, 0, 1, 0, 'linear') .action_({pnd.steps_([1,1])}); ButtonView.new( w, Rect.newBy(335, 328, 104, 22), "steps [0,1]", 0, 0, 1, 0, 'linear') .action_({pnd.steps_([1,0])}); ButtonView.new( w, Rect.newBy(335, 354, 104, 22), "steps [1,0]", 0, 0, 1, 0, 'linear') .action_({pnd.steps_([0,1])}); ButtonView.new( w, Rect.newBy(268, 29, 104, 22), "fold", 0, 0, 1, 0, 'linear') .action_({pnd.edges_([\fold,pnd.edges.at(1)]) }); ButtonView.new( w, Rect.newBy(268, 55, 104, 22), "wrap", 0, 0, 1, 0, 'linear') .action_({pnd.edges_([\wrap,pnd.edges.at(1)]) }); ButtonView.new( w, Rect.newBy(335, 380, 104, 22), "cushion steps", 0, 0, 1, 0, 'linear') .action_({pnd.cushStpAll}); ButtonView.new( w, Rect.newBy(335, 406, 104, 22), "boost steps", 0, 0, 1, 0, 'linear') .action_({pnd.boostStpAll}); ButtonView.new( w, Rect.newBy(335, 432, 104, 22), "mirror all", 0, 0, 1, 0, 'linear') .action_({pnd.mirrorStpAll}); playfunc = { arg synth; trig = LFPulse.ar(4); Sequencer.kr({hold.backColor_(Color.white);0},trig); Sequencer.kr({arg n;hold = (stream.next); hold.backColor_(Color.black);0},trig); }; playfunc.play; ) To go to the documentation file for ListPatterns in 1-d, double click on the [ to select the filename and type cmd-H: [Streams-Patterns-Events 3]