{
   "author" : "56228375",
   "name" : "midified arpeggiator/auto-accompaniment using patterns",
   "ancestor_list" : [],
   "description" : "Proof of concept code for a midified arpeggiator/auto-accompaniment system, quickly reacting to chord changes\r\nMidi is received as input, and supercollider's default instrument (I know, I know) is generating the output.\r\nThis code is accompaniment to a blog article at https://technogems.blogspot.com/2020/01/making-arpeggiator-in-supercollider.html\r\nLet me know if you have ideas for improvement! (code-wise or feature-wise)",
   "labels" : [
      "pattern",
      "arpeggio",
      "midi",
      "arpeggiator",
      "autoaccompaniment"
   ],
   "id" : "1-5cr",
   "is_private" : null,
   "code" : "(\r\ns.waitForBoot({\r\n\tvar right, left;\r\n\tvar n0, n1, n2;\r\n\tvar note_getter;\r\n\r\n\tMIDIdef.freeAll;\r\n\tif (~midi_initilized.isNil) {\r\n\t\tMIDIClient.init;\r\n\t\tMIDIIn.connectAll;\r\n\t\t~midi_initialized = 1;\r\n\t};\r\n\r\n\t~note_table = 0!127;\r\n\t~n = nil;\r\n\r\n\tMIDIdef.noteOn(\r\n\t\t\\mynoteonhandler, // just a name for this handler\r\n\t\t{\r\n\t\t\t|val, num, chan, src|\r\n\t\t\t~note_table[num] = 1; // update note table and update ~n\r\n\t\t\t~n = ~note_table.selectIndices({|item, i| item != 0});\r\n\t\t}\r\n\t);\r\n\r\n\tMIDIdef.noteOff(\r\n\t\t\\mynoteoffhandler, // just a name for this handler\r\n\t\t{\r\n\t\t\t|val, num, chan, src|\r\n\t\t\t~note_table[num] = 0; // update note table and update ~n\r\n\t\t\t/*\r\n\t\t\t// only enable the following lines if you want the arpeggio to stop as soon as you release the keys\r\n\t\t\t~n = ~note_table.selectIndices({|item, i| item != 0});\r\n\t\t\tif (~n == []) { ~n = nil; };\r\n\t\t\t*/\r\n\t\t}\r\n\t);\r\n\r\n\tnote_getter = {\r\n\t\t| index |\r\n\t\tPlazy {\r\n\t\t\tif (~n.isNil) {\r\n\t\t\t\tPseq([Rest(1)]);\r\n\t\t\t} {\r\n\t\t\t\t~n[index] ?? (~n[0] ?? Pseq([Rest(1)]));\r\n\t\t\t};\r\n\t\t};\r\n\t};\r\n\r\n\tn0 = note_getter.(0);\r\n\tn1 = note_getter.(1);\r\n\tn2 = note_getter.(2);\r\n\r\n\tright = Pbind(\r\n\t\t\\instrument, \\default,\r\n\t\t\\midinote, Pseq([ n0, n2, n1, n2] ++ (([ n0, n2, n1, n2] + 12)!2).flatten),\r\n\t\t\\dur, Pseq([1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 ].normalizeSum*2)\r\n\t);\r\n\tleft = Pbind(\r\n\t\t\\instrument, \\default,\r\n\t\t\\midinote, Pseq([ n0, n2, n0, n2, n0, n2, n0, n2] - 12),\r\n\t\t\\dur, Pseq([1, 1, 1, 1, 1, 1, 1, 1].normalizeSum*2)\r\n\t);\r\n\tif (~player.notNil) { ~player.stop; };\r\n\t~player = Pn(Ppar([right,left])).play;\r\n});\r\n)"
}
