Last active
March 2, 2023 04:00
Revisions
-
dmorgan-github revised this gist
Mar 2, 2023 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,6 @@ /* NOTE: There is a Quark for this - https://github.com/dmorgan-github/Pdv Copy to Extensions folder and re-compile Ryhthmically sequences numeric values which can then be used with any event key, e.g. degree or midinote. -
dmorgan-github revised this gist
Nov 6, 2022 . 1 changed file with 74 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,14 +4,16 @@ Copy to Extensions folder and re-compile Ryhthmically sequences numeric values which can then be used with any event key, e.g. degree or midinote. operators: " " - empty space separates beats/values ~ - rest [] - beat sub division <> - alternating values ^n - stretch duration - where n is a float !n - repeat value - where n is an integer $ - shuffle group of values #(nn) - choose from group of values - optionally provide weights as integers 0-9 %n - chance value is chosen vs rest - where n is an integer 0-9 - can be used on value or group note: a key of \g1 is added to the stream at beginning of each cycle which can then be used with Pgate @@ -84,6 +86,30 @@ examples: // sequence with randomly selected value ~p = Pbind(\degree, Pdv.parse("[0 1 2 3]#")) equivalent: Pbind(\degree, Prand([0, 1, 2, 3], inf), \dur, 1) // optionally provide weights to values ~p = Pbind(\degree, Pdv.parse("[0 1 2 3]#(4321)")) equivalent: Pbind(\degree, Pwrand([0, 1, 2, 3], [4, 3, 2, 1].normalizeSum, inf), \dur, 1) // sequence with value or rest chosen by % chance ~p = Pbind(\degree, Pdv.parse("0%4 1%3 2%9 3%0")).asStream; ~p.next(Event.default) ( 'degree': rest, 'dur': Rest(1.0), 'g1': true ) ( 'degree': rest, 'dur': Rest(1.0) ) ( 'degree': 2.0, 'dur': 1.0 ) ( 'degree': rest, 'dur': Rest(1.0) ) ( 'degree': rest, 'dur': Rest(1.0), 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 1.0 ) ( 'degree': rest, 'dur': Rest(1.0) ) // sequence with value or rest chosen by % chance at group level ~p = Pbind(\degree, Pdv.parse("[0 1 2 3]%4")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 0.25, 'g1': true ) ( 'degree': 1.0, 'dur': 0.25 ) ( 'degree': 2.0, 'dur': 0.25 ) ( 'degree': rest, 'dur': Rest(0.25) ) // sequence with alternating values - similar to ppatlace ~p = Pbind(\degree, Pdv.parse("0 <1 2>")).asStream; @@ -155,24 +181,41 @@ Pdv { var parse; parse = {|obj, div=1, stretch=1, chance=9| var val, rep, shuf, choose, weights; var result = (); val = obj['val'].value; stretch = (obj['stretch'] ?? stretch).value.asFloat; chance = (obj['chance'] ?? chance).value.asInteger; rep = (obj['rep'] ?? 1).value.asInteger; choose = obj['choose']; weights = obj['weights']; if (choose == true) { if (val.isSequenceableCollection) { if (weights.notNil) { val = val.wchoose(weights.normalizeSum); }{ val = val.choose; } } }; if (val.isSequenceableCollection) { var size = val.size; val.do({|item| parse.(item, div * size.reciprocal, stretch, chance); }); }{ if (obj['type'] == \value) { if ( (chance/9).coin.not ) { val = \rest; }; if (val.isRest) { div = Rest(div); }; @@ -183,7 +226,7 @@ Pdv { gate = nil }) } { parse.(val, div, stretch, chance) } }; }; @@ -211,22 +254,22 @@ Pdv { var mylist = List.new; mylist = parse.(val, mylist); result.add( // is it necessary to do this here? // or would it be better to move to rout function item['val'] = if (item['shuf'] == true) { { mylist.asArray.scramble } } { mylist }; ); } { if (item['type'] == \alt) { var mylist = List.new; mylist = parse.(val, mylist); result.add( // we need to create the routine here // otherwise we end up creating it each cycle // and it would sequnce properly item['val'] = Routine({ var cnt = 0; inf.do({|i| @@ -265,6 +308,8 @@ Pdv { 'rest', "^\~", 'shuf', "^\\$", 'choose', "^\#", 'chance', "^\%", 'weights', "^\\([0-9]+\\)", '[', "^\\[", ']', "^\\]", '<', "^\<", @@ -296,6 +341,7 @@ Pdv { spec.pairsDo({|k, v| if (result.isNil) { var val = match.(v, str[cursor..]); //[k, v, val].debug("match"); if (val.notNil) { if (k.isNil) { getNext.() @@ -324,6 +370,7 @@ Pdv { var exit = false; while ({ hasMoreTokens.() and: { exit.not } }, { var token = getNextToken.(); //token.debug("token"); switch(token['type'], // entities 'number', { @@ -339,12 +386,21 @@ Pdv { 'rep', { list.last['rep'] = getNextToken.()['val'].asInteger; }, 'chance', { list.last['chance'] = getNextToken.()['val'].asInteger; }, 'shuf', { list.last['shuf'] = true; }, 'choose', { list.last['choose'] = true; }, 'weights', { var weights = token['val']; weights = weights.findRegexp("\\d+")[0][1]; weights = weights.asString.as(Array).collect(_.digit); list.last['weights'] = weights;//.debug("weights"); }, // grouping delimiters '[', { var result; -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,7 @@ /* Copy to Extensions folder and re-compile Ryhthmically sequences numeric values which can then be used with any event key, e.g. degree or midinote. operators: " " - empty space separates beats/values -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -130,7 +130,7 @@ examples: ( 'dur': 1.0, 'midinote': 60.0, 'g1': true ) ( 'dur': 1.0, 'midinote': 67.0 ) // you can further modulate values and durations with regular event keys // e.g. modulate durations with \stretch ~p = Pbind(\degree, Pdv.parse("0 1 [2 3]"), \stretch, 0.5).asStream; ~p.next(Event.default) -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,9 +3,9 @@ Copy to Extensions folder and re-compile operators: " " - empty space separates beats/values ~ - rest [] - beat sub division <> - alternating values ^ - stretch duration ! - repeat value -
dmorgan-github revised this gist
Nov 2, 2022 . No changes.There are no files selected for viewing
-
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ Copy to Extensions folder and re-compile operators: " " - empty space separates beats ~ - rest [] - sub division <> - alternating values ^ - stretch duration ! - repeat value -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,8 +6,8 @@ operators: " " - empty space separates beats ~ - rest [] - group <> - alternating values ^ - stretch duration ! - repeat value $ - shuffle group of values # - choose from group of values -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 11 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,6 +4,7 @@ Copy to Extensions folder and re-compile operators: " " - empty space separates beats ~ - rest [] - group <> - alternating group ^ - stretch durations @@ -16,13 +17,21 @@ note: a key of \g1 is added to the stream at beginning of each cycle which can t examples: // basic sequence ~p = Pbind(\degree, Pdv.parse("0 1 2 3")).asStream; // commas are ignored ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 1.0 ) ( 'degree': 3.0, 'dur': 1.0 ) // sequence with rest ~p = ~p = Pbind(\degree, Pdv.parse("0 1 ~ 2")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': rest, 'dur': Rest(1.0) ) ( 'degree': 2.0, 'dur': 1.0 ) // sequence with sub division ~p = Pbind(\degree, Pdv.parse("0 1 [2 3]")).asStream; ~p.next(Event.default) -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,6 @@ /* Copy to Extensions folder and re-compile operators: " " - empty space separates beats -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ /* operators: " " - empty space separates beats [] - group -
dmorgan-github revised this gist
Nov 2, 2022 . 1 changed file with 121 additions and 21 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,31 +1,131 @@ /* operators: " " - empty space separates beats [] - group <> - alternating group ^ - stretch durations ! - repeat value $ - shuffle group of values # - choose from group of values note: a key of \g1 is added to the stream at beginning of each cycle which can then be used with Pgate examples: // basic sequence ~p = Pbind(\degree, Pdv.parse("0 1 2 3")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 1.0 ) ( 'degree': 3.0, 'dur': 1.0 ) // sequence with sub division ~p = Pbind(\degree, Pdv.parse("0 1 [2 3]")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 0.5 ) ( 'degree': 3.0, 'dur': 0.5 ) // sequence with nested sub divisions ~p = Pbind(\degree, Pdv.parse("0 1 [2 [3 4]]")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 0.5 ) ( 'degree': 3.0, 'dur': 0.25 ) ( 'degree': 4.0, 'dur': 0.25 ) // sequence with irregular sub division ~p = Pbind(\degree, Pdv.parse("0 1 [2 3 4]")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 0.33333333333333 ) ( 'degree': 3.0, 'dur': 0.33333333333333 ) ( 'degree': 4.0, 'dur': 0.33333333333333 ) // sequence with sub division stretched ~p = Pbind(\degree, Pdv.parse("0 1 [2 3 4]^2")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 2.0, 'dur': 0.66666666666667 ) ( 'degree': 3.0, 'dur': 0.66666666666667 ) ( 'degree': 4.0, 'dur': 0.66666666666667 ) // sequence with repeated value ~p = Pbind(\degree, Pdv.parse("0!4 1")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 0.25, 'g1': true ) ( 'degree': 0.0, 'dur': 0.25 ) ( 'degree': 0.0, 'dur': 0.25 ) ( 'degree': 0.0, 'dur': 0.25 ) ( 'degree': 1.0, 'dur': 1.0 ) // sequence with shuffled values each cycle ~p = Pbind(\degree, Pdv.parse("[0 1 2 3]$")) equivalent: Pbind(\degree, Pshuf([ 1, 3, 2, 0 ], inf), \dur, 0.25) // sequence with randomly selected value ~p = Pbind(\degree, Pdv.parse("[0 1 2 3]#")) equivalent: Pbind(\degree, Prand([0, 1, 2, 3], inf), \dur, 1) // sequence with alternating values - similar to ppatlace ~p = Pbind(\degree, Pdv.parse("0 <1 2>")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 2.0, 'dur': 1.0 ) // sequence with alternating values with grouping ~p = Pbind(\degree, Pdv.parse("0 <1 [2 3]>")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0 ) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 2.0, 'dur': 0.5 ) ( 'degree': 3.0, 'dur': 0.5 ) // alternating values with stretched durs ~p = Pbind(\degree, Pdv.parse("0 <1 [2 3]>^2")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 1.0, 'dur': 2.0 ) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 2.0, 'dur': 1.0 ) ( 'degree': 3.0, 'dur': 1.0 ) // combining operators ~p = Pbind(\degree, Pdv.parse("0 <[2 3 4]$ [7 9 10]#>")).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 3.0, 'dur': 0.33333333333333 ) ( 'degree': 4.0, 'dur': 0.33333333333333 ) ( 'degree': 2.0, 'dur': 0.33333333333333 ) ( 'degree': 0.0, 'dur': 1.0, 'g1': true ) ( 'degree': 7.0, 'dur': 1.0 ) // use with midinote ~p = Pbind(\midinote, Pdv.parse("60 <[62 63 64]$ [67 69 70]#>")).asStream ~p.next(Event.default) ( 'dur': 1.0, 'midinote': 60.0, 'g1': true ) ( 'dur': 0.33333333333333, 'midinote': 62.0 ) ( 'dur': 0.33333333333333, 'midinote': 63.0 ) ( 'dur': 0.33333333333333, 'midinote': 64.0 ) ( 'dur': 1.0, 'midinote': 60.0, 'g1': true ) ( 'dur': 1.0, 'midinote': 67.0 ) // you can further modulate values and durations with event keys // e.g. modulate durations with \stretch ~p = Pbind(\degree, Pdv.parse("0 1 [2 3]"), \stretch, 0.5).asStream; ~p.next(Event.default) ( 'degree': 0.0, 'dur': 1.0, 'stretch': 0.5, 'g1': true ) ( 'degree': 1.0, 'dur': 1.0, 'stretch': 0.5 ) ( 'degree': 2.0, 'dur': 0.5, 'stretch': 0.5 ) ( 'degree': 3.0, 'dur': 0.5, 'stretch': 0.5 ) */ -
dmorgan-github created this gist
Nov 2, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,271 @@ /* Pbind(\degree, Pdv.parse("0 1 2 3")) -> Pbind(\degree, Pseq([0 1 2 3], inf), \dur, 1) Pbind(\degree, Pdv.parse("0 1 [2 3]")) -> Pbind(\degree, Pseq([0 1 2 3], inf), \dur, Pseq([1, 1, 0.5, 0.5], inf)) Pbind(\degree, Pdv.parse("0 1 [2 [3, 4]]")) -> Pbind(\degree, Pseq([0 1 2 3, 4], inf), \dur, Pseq([1, 1, 0.5, 0.25, 0.25], inf)) Pbind(\degree, Pdv.parse("0 1 [2 3, 4]")) -> Pbind(\degree, Pseq([0 1 2 3, 4], inf), \dur, Pseq([1, 1, 1/3, 1/3, 1/3], inf)) Pbind(\degree, Pdv.parse("0 1 [2 3, 4]^2")) -> Pbind(\degree, Pseq([0 1 2 3, 4], inf), \dur, Pseq([1, 1, 1/1.5, 1/1.5, 1/1.5], inf)) Pbind(\degree, Pdv.parse("0!4 1")) -> Pbind(\degree, Pseq([0, 0, 0, 0, 1], inf), \dur, Pseq([0.25, 0.25, 0.25, 0.25, 1], inf)) // shuffle Pbind(\degree, Pdv.parse("[0 1 2 3]$")) -> Pbind(\degree, Pshuf([ 1, 3, 2, 0 ], inf), \dur, 0.25) // choose Pbind(\degree, Pdv.parse("[0 1 2 3]#")) -> Pbind(\degree, Prand([0, 1, 2, 3], inf), \dur, 1) */ Pdv { *new { } *rout {|list| var gate = nil; ^Prout({|inval| var parse; parse = {|obj, div=1, stretch=1| var val, rep, shuf; var result = (); val = obj['val'].value; stretch = (obj['stretch'] ?? stretch).value.asFloat; rep = (obj['rep'] ?? 1).value.asInteger; if (val.isSequenceableCollection) { var size = val.size; val.do({|item| parse.(item, div * size.reciprocal, stretch); }); }{ if (obj['type'] == \value) { if (val.isRest) { div = Rest(div); }; rep.do({|i| inval[\g1] = gate; inval['dur'] = div * rep.reciprocal * stretch; inval = val.embedInStream(inval); gate = nil }) } { parse.(val, div, stretch) } }; }; inf.do({ gate = true; list.asArray.do({|val| parse.(val); }); }); inval; }); } *sequence {|list| var parse; parse = {|list, result| list.do({|item| var val = item['val']; if (item['type'] == \group) { var mylist = List.new; mylist = parse.(val, mylist); result.add( item['val'] = if (item['shuf'] == true) { { mylist.asArray.scramble } } { if (item['choose'] == true) { { mylist.asArray.choose } } { mylist } }; ); } { if (item['type'] == \alt) { var mylist = List.new; mylist = parse.(val, mylist); result.add( item['val'] = Routine({ var cnt = 0; inf.do({|i| if (item['shuf'] == true) { mylist = mylist.asArray.scramble; }; mylist.wrapAt(i).yield; cnt = cnt + 1; }); }) ); }{ result.add( item ) } } }); result; }; ^parse.(list, List.new); } *tokenize {|str| var exec, match; var getNextToken; var hasMoreTokens; var spec; var cursor = 0; // as pairs spec = [ 'number', "^[+-]?([0-9]*[.])?[0-9]+", 'stretch', "^\\^", 'rep', "^\!", 'rest', "^\~", 'shuf', "^\\$", 'choose', "^\#", '[', "^\\[", ']', "^\\]", '<', "^\<", '>', "^\>", nil, "^\\s+", nil, "^\,", ]; hasMoreTokens = { cursor < str.size; }; match = {|regex, str| var val = nil; var m = str.findRegexp(regex); if (m.size > 0) { val = m[0][1]; cursor = cursor + val.size; }; val; }; getNextToken = { var getNext; var result = nil; getNext = { if (hasMoreTokens.()) { spec.pairsDo({|k, v| if (result.isNil) { var val = match.(v, str[cursor..]); if (val.notNil) { if (k.isNil) { getNext.() }{ result = ( type: k, val: val ); } } } }); }; }; getNext.(); if (result.isNil) { "unexpected token %".format(str[cursor]).throw }; result; }; exec = {|list| var exit = false; while ({ hasMoreTokens.() and: { exit.not } }, { var token = getNextToken.(); switch(token['type'], // entities 'number', { list.add( (val:token['val'].asFloat, type:\value) ) }, 'rest', { list.add( (val:\rest, type:\value) ) }, // modifiers 'stretch', { list.last['stretch'] = getNextToken.()['val'].asFloat }, 'rep', { list.last['rep'] = getNextToken.()['val'].asInteger; }, 'shuf', { list.last['shuf'] = true; }, 'choose', { list.last['choose'] = true; }, // grouping delimiters '[', { var result; list.add( () ); result = exec.(List.new); list.last['val'] = result; list.last['type'] = 'group' }, ']', { exit = true }, '<', { var result; list.add( () ); result = exec.(List.new); list.last['val'] = result; list.last['type'] = 'alt' }, '>', { exit = true } ); }); list; }; ^exec.(List.new); } *parse {|str| var list, seq; list = Pdv.tokenize(str); seq = Pdv.sequence(list) ^Pdv.rout(seq); } }