oshkoshbagoshh

Javascript Scripts for Logic's Scripter

Mar 25th, 2021
1,520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Allows users to create a sequence that keeps repeating. Example use case: to test out melodies.
  2.  
  3. var NeedsTimingInfo = true;
  4. var activeNotes = [];
  5.  
  6. function HandleMIDI(event) {
  7.     if (event instanceof NoteOn) {
  8.         // add note to array
  9.         activeNotes.push(event);
  10.     }
  11.     // else if (event instanceof NoteOff) {
  12.     //  // remove note from array
  13.     //  for (i = 0; i < activeNotes.length; i++) {
  14.     //      if (activeNotes[i].pitch == event.pitch) {
  15.     //          activeNotes.splice (i, 1);
  16.     //          break;
  17.     //      }
  18.     //  }
  19.     // }
  20.     // pass non-note events through
  21.     else event.send();
  22.  
  23.     // sort array of active notes
  24.     // activeNotes.sort(sortByPitchAscending);
  25.     // Remove the '//' above to force the note to be in order by pitch
  26. }
  27.  
  28. //-----------------------------------------------------------------------------
  29. function sortByPitchAscending(a,b) {
  30.     if (a.pitch < b.pitch) return -1;
  31.     if (a.pitch > b.pitch) return 1;
  32.     return 0;
  33. }
  34.  
  35. //-----------------------------------------------------------------------------
  36. var wasPlaying = false;
  37.  
  38. function ProcessMIDI() {
  39.     // Get timing information from the host application
  40.     var musicInfo = GetTimingInfo();
  41.  
  42.     // clear activeNotes[] when the transport stops and send any remaining note off events
  43.     if (wasPlaying && !musicInfo.playing){
  44.         for(i=0;i<activeNotes.length;i++) {
  45.             var off = new NoteOff(activeNotes[i]);
  46.             off.send();
  47.         }
  48.     }
  49.  
  50.     wasPlaying = musicInfo.playing;
  51.  
  52.     if (activeNotes.length != 0) {
  53.  
  54.         // get parameters
  55.         var division = GetParameter("Beat Division");
  56.         var noteOrder = GetParameter("Note Order");
  57.         var noteLength = (GetParameter("Note Length") / 100) * (1 / division);
  58.         var randomLength = Math.random() * ((GetParameter("Random Length") / 100) * (1 / division));
  59.         var randomDelay = Math.random() * ((GetParameter("Random Delay") / 100) * (1 / division));
  60.         var randomOctave = Math.floor(Math.random() * GetParameter("Random Octave")) * 12;
  61.  
  62.         // calculate beat to schedule
  63.         var lookAheadEnd = musicInfo.blockEndBeat;
  64.         var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
  65.  
  66.         // when cycling, find the beats that wrap around the last buffer
  67.         if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat) {
  68.             if (lookAheadEnd >= musicInfo.rightCycleBeat) {
  69.                 var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
  70.                 var cycleEnd = lookAheadEnd - cycleBeats;
  71.             }
  72.         }
  73.  
  74.         var state = GetParameter("Reset");
  75.     if (state == 1) {
  76.       Reset();
  77.     }
  78.  
  79.         // loop through the beats that fall within this buffer
  80.         while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd && state == 0)
  81.         // including beats that wrap around the cycle point
  82.         || (musicInfo.cycling && nextBeat < cycleEnd)) {
  83.             // adjust for cycle
  84.             if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
  85.                 nextBeat -= cycleBeats;
  86.  
  87.             // calculate step
  88.             var step = Math.floor(nextBeat / (1 / division) - division);
  89.             var chosenNote = chooseNote(noteOrder, step);
  90.  
  91.             // send events
  92.             var noteOn = new NoteOn(chosenNote);
  93.             noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
  94.             noteOn.sendAtBeat(nextBeat + randomDelay);
  95.             var noteOff = new NoteOff(noteOn);
  96.             noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength)
  97.  
  98.             // advance to next beat
  99.             nextBeat += 0.001;
  100.             nextBeat = Math.ceil(nextBeat * division) / division;
  101.         }
  102.     }
  103. }
  104.  
  105. function Reset() {
  106.   NeedsTimingInfo = true;
  107.   activeNotes = [];
  108.   SetParameter ("Reset", 0);
  109. }
  110.  
  111. //-----------------------------------------------------------------------------
  112. var noteOrders = ["up", "down", "random"];
  113.  
  114. function chooseNote(noteOrder, step) {
  115.     var order = noteOrders[noteOrder];
  116.     var length = activeNotes.length
  117.     if (order == "up") return activeNotes[step % length];
  118.     if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
  119.     if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
  120.     else return 0;
  121. }
  122.  
  123. //-----------------------------------------------------------------------------
  124. var PluginParameters =
  125. [
  126.         {name:"Reset", type:"menu", valueStrings:["Off", "On"],
  127.         minValue:0, maxValue:1, numberOfSteps: 2, defaultValue:0},
  128.  
  129.         {name:"Beat Division", type:"linear",
  130.         minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
  131.  
  132.         {name:"Note Order", type:"menu", valueStrings:noteOrders,
  133.         minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
  134.  
  135.         {name:"Note Length", unit:"%", type:"linear",
  136.         minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199},
  137.  
  138.         {name:"Random Length", unit:"%", type:"linear",
  139.         minValue:0, maxValue:200, numberOfSteps: 200, defaultValue:0},
  140.  
  141.         {name:"Random Delay", unit:"%", type:"linear",
  142.         minValue:0, maxValue:200, numberOfSteps:200, defaultValue:0},
  143.  
  144.         {name:"Random Octave", type:"linear",
  145.         minValue:1, maxValue:4, defaultValue:1, numberOfSteps:3}
  146. ];
  147.  
  148. // ----------------------------------------------------------------------------
  149. // Code from plugin.js
  150.  
  151. // Copy and paste this chunk of code into your script editor to create controls in your plugin
  152.  
  153. // var PluginParameters = [];
  154.  
  155. // Types of Plugin Parameters
  156. const LINEAR_FADER = "lin";
  157. const LOGARITHMIC_FADER = "log";
  158. const MOMENTARY_BUTTON = "momentary";
  159. const MENU = "menu";
  160. const NOT_NEEDED = "";
  161.  
  162. /*
  163. To create a plugin parameter (a fader or knob that changes something is a basic way of desribing it), call the createPluginParameter function as follows:
  164. createPluginParameter("Enter a name in quotes", Enter a type from above in quotes (for example: LINEAR_FADER), Enter a minimum value, Enter a maximum value, Enter a default value, enter the number of steps, "Enter a unit in quotes", "Enter text to create a divider/header in the plug-in", Enter a list of value strings if you are creating a menu as follows: ["something", "something", "something"]);
  165. */
  166.  
  167. function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  168.   if (type == MENU) {
  169.     PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  170.   }
  171.   else {
  172.     PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  173.   }
  174. }
  175.  
  176. function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  177.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
  178. }
  179.  
  180. function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  181.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
  182. }
  183.  
  184. //Parameters for the plugin
  185.  
  186. // Triggers chords derived from played note
  187.  
  188. // Chordtypes
  189. var maj_Chord = [4, 7];
  190. var min_Chord = [3, 7];
  191. var dim_Chord = [3, 6];
  192. var maj7th_Chord = [4, 7, 11];
  193. var min7th_Chord = [3, 7, 10];
  194. var dom7th_Chord = [4, 7, 10];
  195. var dim7th_Chord = [3, 6, 10];
  196.  
  197. var activeNotes = [];
  198.  
  199. function HandleMIDI(event) {
  200.     if (GetParameter("Flavour") == 0) {
  201.         if (GetParameter("Mode") == 0) {
  202.             // MAJOR
  203.             switch (event.pitch % 12) {
  204.                 // I
  205.                 case (GetParameter("Root") % 12):
  206.                     buildChord(event, maj_Chord);
  207.                     break;
  208.                     // ii
  209.                 case ((GetParameter("Root") + 2) % 12):
  210.                     buildChord(event, min_Chord);
  211.                     break;
  212.                     // iii
  213.                 case ((GetParameter("Root") + 4) % 12):
  214.                     buildChord(event, min_Chord);
  215.                     break;
  216.                     // IV
  217.                 case ((GetParameter("Root") + 5) % 12):
  218.                     buildChord(event, maj_Chord);
  219.                     break;
  220.                     // V
  221.                 case ((GetParameter("Root") + 7) % 12):
  222.                     buildChord(event, maj_Chord);
  223.                     break;
  224.                     // vi
  225.                 case ((GetParameter("Root") + 9) % 12):
  226.                     buildChord(event, min_Chord);
  227.                     break;
  228.                     // vii°
  229.                 case ((GetParameter("Root") + 11) % 12):
  230.                     buildChord(event, dim_Chord);
  231.                     break;
  232.                     // Default
  233.                 default:
  234.                     break;
  235.             }
  236.         }
  237.         else if (GetParameter("Mode") == 1) {
  238.             // MINOR
  239.             switch (event.pitch % 12) {
  240.                 // i
  241.                 case (GetParameter("Root") % 12):
  242.                     buildChord(event, min_Chord);
  243.                     break;
  244.                     // ii°
  245.                 case ((GetParameter("Root") + 2) % 12):
  246.                     buildChord(event, dim_Chord);
  247.                     break;
  248.                     // III
  249.                 case ((GetParameter("Root") + 3) % 12):
  250.                     buildChord(event, maj_Chord);
  251.                     break;
  252.                     // iv
  253.                 case ((GetParameter("Root") + 5) % 12):
  254.                     buildChord(event, min_Chord);
  255.                     break;
  256.                     // v
  257.                 case ((GetParameter("Root") + 7) % 12):
  258.                     buildChord(event, min_Chord);
  259.                     break;
  260.                     // VI
  261.                 case ((GetParameter("Root") + 8) % 12):
  262.                     buildChord(event, maj_Chord);
  263.                     break;
  264.                     // VII
  265.                 case ((GetParameter("Root") + 10) % 12):
  266.                     buildChord(event, maj_Chord);
  267.                     break;
  268.                     // Default
  269.                 default:
  270.                     break;
  271.             }
  272.         }
  273.     }
  274.     if (GetParameter("Flavour") == 1) {
  275.         if (GetParameter("Mode") == 0) {
  276.             // MAJOR
  277.             switch (event.pitch % 12) {
  278.                 // I7
  279.                 case (GetParameter("Root") % 12):
  280.                     buildChord(event, maj7th_Chord);
  281.                     break;
  282.                     // ii7
  283.                 case ((GetParameter("Root") + 2) % 12):
  284.                     buildChord(event, min7th_Chord);
  285.                     break;
  286.                     // iii7
  287.                 case ((GetParameter("Root") + 4) % 12):
  288.                     buildChord(event, min7th_Chord);
  289.                     break;
  290.                     // IV7
  291.                 case ((GetParameter("Root") + 5) % 12):
  292.                     buildChord(event, maj7th_Chord);
  293.                     break;
  294.                     // V7
  295.                 case ((GetParameter("Root") + 7) % 12):
  296.                     buildChord(event, dom7th_Chord);
  297.                     break;
  298.                     // vi7
  299.                 case ((GetParameter("Root") + 9) % 12):
  300.                     buildChord(event, min7th_Chord);
  301.                     break;
  302.                     // vii°7
  303.                 case ((GetParameter("Root") + 11) % 12):
  304.                     buildChord(event, dim7th_Chord);
  305.                     break;
  306.                     // Default
  307.                 default:
  308.                     break;
  309.             }
  310.         } else if (GetParameter("Mode") == 1) {
  311.             // MINOR
  312.             switch (event.pitch % 12) {
  313.                 // i7
  314.                 case (GetParameter("Root") % 12):
  315.                     buildChord(event, min7th_Chord);
  316.                     break;
  317.                     // ii°7
  318.                 case ((GetParameter("Root") + 2) % 12):
  319.                     buildChord(event, dim7th_Chord);
  320.                     break;
  321.                     // III7
  322.                 case ((GetParameter("Root") + 3) % 12):
  323.                     buildChord(event, maj7th_Chord);
  324.                     break;
  325.                     // iv7
  326.                 case ((GetParameter("Root") + 5) % 12):
  327.                     buildChord(event, min7th_Chord);
  328.                     break;
  329.                     // v7
  330.                 case ((GetParameter("Root") + 7) % 12):
  331.                     buildChord(event, min7th_Chord);
  332.                     break;
  333.                     // VI7
  334.                 case ((GetParameter("Root") + 8) % 12):
  335.                     buildChord(event, maj7th_Chord);
  336.                     break;
  337.                     // VII7
  338.                 case ((GetParameter("Root") + 10) % 12):
  339.                     buildChord(event, dom7th_Chord);
  340.                     break;
  341.                     // Default
  342.                 default:
  343.                     break;
  344.             }
  345.         }
  346.     }
  347. }
  348.  
  349. function buildChord(root, chordtype) {
  350.     if (root instanceof NoteOn) {
  351.         var originalNote = new NoteOn(root);
  352.         var record = {
  353.             originalPitch: root.pitch,
  354.             events: [originalNote]
  355.         };
  356.         root.send();
  357.         for (var i = 0; i < chordtype.length; i++) {
  358.             var harmony = new NoteOn(root);
  359.             harmony.pitch += chordtype[i];
  360.             record.events.push(harmony);
  361.             harmony.send();
  362.         }
  363.         activeNotes.push(record);
  364.     } else if (root instanceof NoteOff) {
  365.         for (var i in activeNotes) {
  366.             if (activeNotes[i].originalPitch == root.pitch) {
  367.                 for (var j = 0; j < activeNotes[i].events.length; j++) {
  368.                     var noteOff = new NoteOff(activeNotes[i].events[j]);
  369.                     noteOff.send();
  370.                 }
  371.                 activeNotes.splice(i, 1);
  372.                 break;
  373.             }
  374.         }
  375.     }
  376. }
  377.  
  378. ResetParameterDefaults = true;
  379.  
  380. var PluginParameters = [{
  381.     name: "Chords",
  382.     type: "text"
  383. }, {
  384.     name: "Root",
  385.     type: "menu",
  386.     valueStrings: ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
  387.     defaultValue: 0,
  388.     minValue: 0,
  389.     maxValue: 11,
  390.     numberOfSteps: 12
  391. }, {
  392.     name: "Mode",
  393.     type: "menu",
  394.     valueStrings: ["Major", "Minor"],
  395.     defaultValue: 0,
  396.     minValue: 0,
  397.     maxValue: 1,
  398.     numberOfSteps: 2
  399. }, {
  400.     name: "Flavour",
  401.     type: "menu",
  402.     valueStrings: ["Normal", "Jazzy"],
  403.     defaultValue: 0,
  404.     minValue: 0,
  405.     maxValue: 1,
  406.     numberOfSteps: 2
  407. }];
  408.  
  409. // Copy and paste this chunk of code into your script editor to create controls in your plugin
  410.  
  411. var NeedsTimingInfo = true;
  412.  
  413. var PluginParameters = [];
  414.  
  415. // Types of Plugin Parameters
  416. const LINEAR_FADER = "lin";
  417. const LOGARITHMIC_FADER = "log";
  418. const MOMENTARY_BUTTON = "momentary";
  419. const MENU = "menu";
  420. const NOT_NEEDED = "";
  421.  
  422. /*
  423. To create a plugin parameter (a fader or knob that changes something is a basic way of desribing it), call the createPluginParameter function as follows:
  424. createPluginParameter("Enter a name in quotes", Enter a type from above in quotes (for example: LINEAR_FADER), Enter a minimum value, Enter a maximum value, Enter a default value, enter the number of steps, "Enter a unit in quotes", "Enter text to create a divider/header in the plug-in", Enter a list of value strings if you are creating a menu as follows: ["something", "something", "something"]);
  425. */
  426.  
  427. function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  428.   if (type == MENU) {
  429.     PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  430.   }
  431.   else {
  432.     PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  433.   }
  434. }
  435.  
  436. function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  437.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
  438. }
  439.  
  440. function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  441.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
  442. }
  443.  
  444. //Parameters for the plugin
  445.  
  446. // Repeats note that is played with specified beat divisions
  447.  
  448. var NeedsTimingInfo = true;
  449. var activeNotes = [];
  450.  
  451. function HandleMIDI(event) {
  452.     if (event instanceof NoteOn) {
  453.         // add note to array
  454.         activeNotes.push(event);
  455.     }
  456.     else if (event instanceof NoteOff) {
  457.         // remove note from array
  458.         for (i = 0; i < activeNotes.length; i++) {
  459.             if (activeNotes[i].pitch == event.pitch) {
  460.                 activeNotes.splice (i, 1);
  461.                 break;
  462.             }
  463.         }
  464.     }
  465.     // pass non-note events through
  466.     else event.send();
  467.  
  468.     // sort array of active notes
  469.     activeNotes.sort(sortByPitchAscending);
  470. }
  471.  
  472. //-----------------------------------------------------------------------------
  473. function sortByPitchAscending (a, b) {
  474.     if (a.pitch < b.pitch) {
  475.     return -1;
  476.   }
  477.     if (a.pitch > b.pitch) {
  478.     return 1;
  479.   }
  480.     return 0;
  481. }
  482.  
  483. //-----------------------------------------------------------------------------
  484. var wasPlaying = false;
  485.  
  486. function ProcessMIDI() {
  487.     // Get timing information from the host application
  488.     var musicInfo = GetTimingInfo();
  489.  
  490.     // clear activeNotes[] when the transport stops and send any remaining note off events
  491.     if (wasPlaying && !musicInfo.playing) {
  492.         for(i = 0;i < activeNotes.length; i++) {
  493.             var off = new NoteOff(activeNotes[i]);
  494.             off.send();
  495.         }
  496.     }
  497.  
  498.     wasPlaying = musicInfo.playing;
  499.  
  500.     if (activeNotes.length != 0) {
  501.  
  502.         // get parameters
  503.         var division = GetParameter("Beat Division");
  504.         var noteOrder = GetParameter("Note Order");
  505.         var noteLength = (GetParameter("Note Length") / 100) * (1 / division);
  506.         // var randomLength = Math.random() * ((GetParameter("Random Length") / 100) * (1 / division));
  507.         // var randomDelay = Math.random() * ((GetParameter("Random Delay") / 100) * (1 / division));
  508.         // var randomOctave = Math.floor(Math.random() * GetParameter("Random Octave")) * 12;
  509.  
  510.         // calculate beat to schedule
  511.         var lookAheadEnd = musicInfo.blockEndBeat;
  512.         var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
  513.         // var nextBeat = musicInfo.blockStartBeat;
  514.  
  515.         // when cycling, find the beats that wrap around the last buffer
  516.         if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat && lookAheadEnd >= musicInfo.rightCycleBeat) {
  517.       var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
  518.       var cycleEnd = lookAheadEnd - cycleBeats;
  519.         }
  520.  
  521.     var state = GetParameter("Reset");
  522.     if (state == 1) {
  523.       Reset();
  524.     }
  525.  
  526.         // loop through the beats that fall within this buffer
  527.         while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd && state == 0)
  528.         // including beats that wrap around the cycle point
  529.         || (musicInfo.cycling && nextBeat < cycleEnd)) {
  530.  
  531.             // adjust for cycle
  532.             if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
  533.                 nextBeat -= cycleBeats;
  534.  
  535.             // calculate step
  536.             var step = Math.floor(nextBeat / (1 / division) - division);
  537.             var chosenNote = chooseNote(noteOrder, step);
  538.  
  539.             // send events
  540.             var noteOn = new NoteOn(chosenNote);
  541.             // noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
  542.             noteOn.pitch = MIDI.normalizeData(noteOn.pitch);
  543.             // noteOn.sendAtBeat(nextBeat + randomDelay);
  544.             noteOn.sendAtBeat(nextBeat);
  545.             var noteOff = new NoteOff(noteOn);
  546.             // noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength);
  547.             noteOff.sendAtBeat(nextBeat + noteLength);
  548.  
  549.             // advance to next beat
  550.             nextBeat += 0.001;
  551.             nextBeat = Math.ceil(nextBeat * division) / division;
  552.         }
  553.     }
  554. }
  555.  
  556. function Reset() {
  557.   NeedsTimingInfo = true;
  558.   activeNotes = [];
  559.   SetParameter ("Reset", 0);
  560. }
  561.  
  562. //-----------------------------------------------------------------------------
  563. var noteOrders = ["up", "down", "random"];
  564.  
  565. function chooseNote(noteOrder, step) {
  566.     var order = noteOrders[noteOrder];
  567.     var length = activeNotes.length
  568.     if (order == "up") return activeNotes[step % length];
  569.     if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
  570.     if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
  571.     else return 0;
  572. }
  573.  
  574. //-----------------------------------------------------------------------------
  575. // var PluginParameters =
  576. // [
  577. //      {name:"Beat Division", type:"linear",
  578. //      minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
  579. //
  580. //      {name:"Note Order", type:"menu", valueStrings:noteOrders,
  581. //      minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
  582. //
  583. //      {name:"Note Length", unit:"%", type:"linear",
  584. //      minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199},
  585. //
  586. //      {name:"Random Length", unit:"%", type:"linear",
  587. //      minValue:0, maxValue:200, numberOfSteps: 200, defaultValue:0},
  588. //
  589. //      {name:"Random Delay", unit:"%", type:"linear",
  590. //      minValue:0, maxValue:200, numberOfSteps:200, defaultValue:0},
  591. //
  592. //      {name:"Random Octave", type:"linear",
  593. //      minValue:1, maxValue:4, defaultValue:1, numberOfSteps:3}
  594. // ];
  595. var PluginParameters =
  596. [
  597.         {name:"Beat Division", type:"linear",
  598.         minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
  599.  
  600.         {name:"Note Order", type:"menu", valueStrings:noteOrders,
  601.         minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
  602.  
  603.         {name:"Reset", type:"menu", valueStrings:["Off", "On"],
  604.         minValue:0, maxValue:1, numberOfSteps: 2, defaultValue:0},
  605.  
  606.         {name:"Note Length", unit:"%", type:"linear",
  607.         minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199}
  608. ];
  609.  
  610. // ----------------------------------------------------------------------------
  611. // Code from plugin.js
  612.  
  613. // Copy and paste this chunk of code into your script editor to create controls in your plugin
  614.  
  615. // var PluginParameters = [];
  616.  
  617. // Types of Plugin Parameters
  618. const LINEAR_FADER = "lin";
  619. const LOGARITHMIC_FADER = "log";
  620. const MOMENTARY_BUTTON = "momentary";
  621. const MENU = "menu";
  622. const NOT_NEEDED = "";
  623.  
  624. /*
  625. To create a plugin parameter (a fader or knob that changes something is a basic way of desribing it), call the createPluginParameter function as follows:
  626. createPluginParameter("Enter a name in quotes", Enter a type from above in quotes (for example: LINEAR_FADER), Enter a minimum value, Enter a maximum value, Enter a default value, enter the number of steps, "Enter a unit in quotes", "Enter text to create a divider/header in the plug-in", Enter a list of value strings if you are creating a menu as follows: ["something", "something", "something"]);
  627. */
  628.  
  629. function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  630.   if (type == MENU) {
  631.     PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  632.   }
  633.   else {
  634.     PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  635.   }
  636. }
  637.  
  638. function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  639.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
  640. }
  641.  
  642. function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  643.   return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
  644. }
  645.  
  646. //Parameters for the plugin
  647.  
  648. // Constructs a sequence of notes triggered relative to the base note
  649.  
  650. var NeedsTimingInfo = true;
  651. var activeNotes = [];
  652. var sequence = [2, 2, 1, 2, 2, 2, 1]; // Choose your sequence here. Enter integers for ups or downs
  653. /* needed to make beatPos work */
  654. function HandleMIDI(event) {
  655.   if (event instanceof NoteOn) {
  656.     constructSequence(event);
  657.     // activeNotes.push(event);
  658.     // for (var i = 0; i < sequence.length; i++) {
  659.     //   var on = new NoteOn (activeNotes[i]);
  660.     //   var previous  = new NoteOn (activeNotes[i])
  661.     //   on.pitch = MIDI.normalizeData(previous.pitch + sequence[i]);
  662.     //   activeNotes.push (on);
  663.     //   on.sendAtBeat(previous.beatPos + 2);
  664.     // }
  665.   }
  666.  
  667.   else if (event instanceof NoteOff) {
  668.         // remove note from array
  669.     Reset();
  670.         for (i = 0; i < activeNotes.length; i++) {
  671.             if (activeNotes[i].pitch == event.pitch) {
  672.                 activeNotes.splice(i, 1);
  673.                 break;
  674.             }
  675.         }
  676.     }
  677.  
  678.   else {
  679.     event.send();
  680.   }
  681. }
  682.  
  683. function Reset() {
  684.   activeNotes = [];
  685. }
  686.  
  687. // function ProcessMIDI() {
  688. //   for (var i = 0; i < activeNotes.length; i++) {
  689. //     var currentNote = new NoteOn (sequence[i]);
  690. //     currentNote.send();
  691. //   }
  692. // }
  693.  
  694. function constructSequence(event) {
  695.   activeNotes.push (event);
  696.   for (var i = 0; i < sequence.length; i++) {
  697.     var on = new NoteOn;
  698.     on.pitch = MIDI.normalizeData(activeNotes[i].pitch + sequence[i]);
  699.     activeNotes.push (on);
  700.   }
  701. }
  702.  
  703. var wasPlaying = false;
  704.  
  705. function ProcessMIDI() {
  706.     // Get timing information from the host application
  707.     var musicInfo = GetTimingInfo();
  708.  
  709.     // clear activeNotes[] when the transport stops and send any remaining note off events
  710.     if (wasPlaying && !musicInfo.playing){
  711.         for(i=0;i<activeNotes.length;i++) {
  712.             var off = new NoteOff(activeNotes[i]);
  713.             off.send();
  714.         }
  715.     }
  716.  
  717.     wasPlaying = musicInfo.playing;
  718.  
  719.     if (activeNotes.length != 0) {
  720.  
  721.         // get parameters
  722.         // var division = GetParameter("Beat Division");
  723.         var division = 1;
  724.         var noteOrder = 0;
  725.         var noteLength = (100 / 100) * (1 / division);
  726.         var randomLength = 0;
  727.         var randomDelay = 0;
  728.         var randomOctave = 1;
  729.  
  730.         // calculate beat to schedule
  731.         var lookAheadEnd = musicInfo.blockEndBeat;
  732.         var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
  733.  
  734.         // when cycling, find the beats that wrap around the last buffer
  735.         if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat) {
  736.             if (lookAheadEnd >= musicInfo.rightCycleBeat) {
  737.                 var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
  738.                 var cycleEnd = lookAheadEnd - cycleBeats;
  739.             }
  740.         }
  741.  
  742.         // var state = GetParameter("Reset");
  743.     // if (state == 1) {
  744.     //   Reset();
  745.     // }
  746.  
  747.         // loop through the beats that fall within this buffer
  748.         while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd)
  749.         // including beats that wrap around the cycle point
  750.         || (musicInfo.cycling && nextBeat < cycleEnd)) {
  751.             // adjust for cycle
  752.             if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
  753.                 nextBeat -= cycleBeats;
  754.  
  755.             // calculate step
  756.             var step = Math.floor(nextBeat / (1 / division) - division);
  757.             var chosenNote = chooseNote(noteOrder, step);
  758.  
  759.             // send events
  760.             var noteOn = new NoteOn(chosenNote);
  761.             // noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
  762.             noteOn.pitch = (noteOn.pitch + randomOctave);
  763.             noteOn.sendAtBeat(nextBeat + randomDelay);
  764.             var noteOff = new NoteOff(noteOn);
  765.             noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength)
  766.  
  767.             // advance to next beat
  768.             nextBeat += 0.001;
  769.             nextBeat = Math.ceil(nextBeat * division) / division;
  770.         }
  771.     }
  772. }
  773.  
  774. var noteOrders = ["up", "down", "random"];
  775.  
  776. function chooseNote(noteOrder, step) {
  777.     var order = noteOrders[noteOrder];
  778.     var length = activeNotes.length
  779.     if (order == "up") return activeNotes[step % length];
  780.     if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
  781.     if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
  782.     else return 0;
  783. }
  784.  
  785. // function constructSequence(event) {
  786. //   activeNotes.push (event);
  787. //   for (var i = 0; i < sequence.length; i++) {
  788. //     var on = new NoteOn;
  789. //     on.pitch = MIDI.normalizeData(activeNotes[i].pitch + sequence[i]);
  790. //     on.beatPos = activeNotes[i].beatPos + 1;
  791. //     activeNotes.push (on);
  792. //   }
  793. // }
  794.  
Advertisement
Add Comment
Please, Sign In to add comment