oshkoshbagoshh icon

Javascript Scripts for Logic's Scripter

oshkoshbagoshh | PRO | 03/25/21 08:59:49 PM UTC | 0 ⭐ | 1470 👁️ | Never ⏰ | []
JavaScript |

27.6 KB

|

None

|

0 👍

/

0 👎

// Allows users to create a sequence that keeps repeating. Example use case: to test out melodies.
 
var NeedsTimingInfo = true;
var activeNotes = [];
 
function HandleMIDI(event) {
    if (event instanceof NoteOn) {
        // add note to array
        activeNotes.push(event);
    }
    // else if (event instanceof NoteOff) {
    //  // remove note from array
    //  for (i = 0; i < activeNotes.length; i++) {
    //      if (activeNotes[i].pitch == event.pitch) {
    //          activeNotes.splice (i, 1);
    //          break;
    //      }
    //  }
    // }
    // pass non-note events through
    else event.send();
 
    // sort array of active notes
    // activeNotes.sort(sortByPitchAscending);
    // Remove the '//' above to force the note to be in order by pitch
}
 
//-----------------------------------------------------------------------------
function sortByPitchAscending(a,b) {
    if (a.pitch < b.pitch) return -1;
    if (a.pitch > b.pitch) return 1;
    return 0;
}
 
//-----------------------------------------------------------------------------
var wasPlaying = false;
 
function ProcessMIDI() {
    // Get timing information from the host application
    var musicInfo = GetTimingInfo();
 
    // clear activeNotes[] when the transport stops and send any remaining note off events
    if (wasPlaying && !musicInfo.playing){
        for(i=0;i<activeNotes.length;i++) {
            var off = new NoteOff(activeNotes[i]);
            off.send();
        }
    }
 
    wasPlaying = musicInfo.playing;
 
    if (activeNotes.length != 0) {
 
        // get parameters
        var division = GetParameter("Beat Division");
        var noteOrder = GetParameter("Note Order");
        var noteLength = (GetParameter("Note Length") / 100) * (1 / division);
        var randomLength = Math.random() * ((GetParameter("Random Length") / 100) * (1 / division));
        var randomDelay = Math.random() * ((GetParameter("Random Delay") / 100) * (1 / division));
        var randomOctave = Math.floor(Math.random() * GetParameter("Random Octave")) * 12;
 
        // calculate beat to schedule
        var lookAheadEnd = musicInfo.blockEndBeat;
        var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
 
        // when cycling, find the beats that wrap around the last buffer
        if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat) {
            if (lookAheadEnd >= musicInfo.rightCycleBeat) {
                var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
                var cycleEnd = lookAheadEnd - cycleBeats;
            }
        }
 
        var state = GetParameter("Reset");
    if (state == 1) {
      Reset();
    }
 
        // loop through the beats that fall within this buffer
        while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd && state == 0)
        // including beats that wrap around the cycle point
        || (musicInfo.cycling && nextBeat < cycleEnd)) {
            // adjust for cycle
            if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
                nextBeat -= cycleBeats;
 
            // calculate step
            var step = Math.floor(nextBeat / (1 / division) - division);
            var chosenNote = chooseNote(noteOrder, step);
 
            // send events
            var noteOn = new NoteOn(chosenNote);
            noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
            noteOn.sendAtBeat(nextBeat + randomDelay);
            var noteOff = new NoteOff(noteOn);
            noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength)
 
            // advance to next beat
            nextBeat += 0.001;
            nextBeat = Math.ceil(nextBeat * division) / division;
        }
    }
}
 
function Reset() {
  NeedsTimingInfo = true;
  activeNotes = [];
  SetParameter ("Reset", 0);
}
 
//-----------------------------------------------------------------------------
var noteOrders = ["up", "down", "random"];
 
function chooseNote(noteOrder, step) {
    var order = noteOrders[noteOrder];
    var length = activeNotes.length
    if (order == "up") return activeNotes[step % length];
    if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
    if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
    else return 0;
}
 
//-----------------------------------------------------------------------------
var PluginParameters =
[
        {name:"Reset", type:"menu", valueStrings:["Off", "On"],
        minValue:0, maxValue:1, numberOfSteps: 2, defaultValue:0},
 
        {name:"Beat Division", type:"linear",
        minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
 
        {name:"Note Order", type:"menu", valueStrings:noteOrders,
        minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
 
        {name:"Note Length", unit:"%", type:"linear",
        minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199},
 
        {name:"Random Length", unit:"%", type:"linear",
        minValue:0, maxValue:200, numberOfSteps: 200, defaultValue:0},
 
        {name:"Random Delay", unit:"%", type:"linear",
        minValue:0, maxValue:200, numberOfSteps:200, defaultValue:0},
 
        {name:"Random Octave", type:"linear",
        minValue:1, maxValue:4, defaultValue:1, numberOfSteps:3}
];
 
// ----------------------------------------------------------------------------
// Code from plugin.js
 
// Copy and paste this chunk of code into your script editor to create controls in your plugin
 
// var PluginParameters = [];
 
// Types of Plugin Parameters
const LINEAR_FADER = "lin";
const LOGARITHMIC_FADER = "log";
const MOMENTARY_BUTTON = "momentary";
const MENU = "menu";
const NOT_NEEDED = "";
 
/*
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:
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"]);
*/
 
function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  if (type == MENU) {
    PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  }
  else {
    PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  }
}
 
function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
}
 
function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
}
 
//Parameters for the plugin
 
// Triggers chords derived from played note
 
// Chordtypes
var maj_Chord = [4, 7];
var min_Chord = [3, 7];
var dim_Chord = [3, 6];
var maj7th_Chord = [4, 7, 11];
var min7th_Chord = [3, 7, 10];
var dom7th_Chord = [4, 7, 10];
var dim7th_Chord = [3, 6, 10];
 
var activeNotes = [];
 
function HandleMIDI(event) {
    if (GetParameter("Flavour") == 0) {
        if (GetParameter("Mode") == 0) {
            // MAJOR
            switch (event.pitch % 12) {
                // I
                case (GetParameter("Root") % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // ii
                case ((GetParameter("Root") + 2) % 12):
                    buildChord(event, min_Chord);
                    break;
                    // iii
                case ((GetParameter("Root") + 4) % 12):
                    buildChord(event, min_Chord);
                    break;
                    // IV
                case ((GetParameter("Root") + 5) % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // V
                case ((GetParameter("Root") + 7) % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // vi
                case ((GetParameter("Root") + 9) % 12):
                    buildChord(event, min_Chord);
                    break;
                    // vii°
                case ((GetParameter("Root") + 11) % 12):
                    buildChord(event, dim_Chord);
                    break;
                    // Default
                default:
                    break;
            }
        }
        else if (GetParameter("Mode") == 1) {
            // MINOR
            switch (event.pitch % 12) {
                // i
                case (GetParameter("Root") % 12):
                    buildChord(event, min_Chord);
                    break;
                    // ii°
                case ((GetParameter("Root") + 2) % 12):
                    buildChord(event, dim_Chord);
                    break;
                    // III
                case ((GetParameter("Root") + 3) % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // iv
                case ((GetParameter("Root") + 5) % 12):
                    buildChord(event, min_Chord);
                    break;
                    // v
                case ((GetParameter("Root") + 7) % 12):
                    buildChord(event, min_Chord);
                    break;
                    // VI
                case ((GetParameter("Root") + 8) % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // VII
                case ((GetParameter("Root") + 10) % 12):
                    buildChord(event, maj_Chord);
                    break;
                    // Default
                default:
                    break;
            }
        }
    }
    if (GetParameter("Flavour") == 1) {
        if (GetParameter("Mode") == 0) {
            // MAJOR
            switch (event.pitch % 12) {
                // I7
                case (GetParameter("Root") % 12):
                    buildChord(event, maj7th_Chord);
                    break;
                    // ii7
                case ((GetParameter("Root") + 2) % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // iii7
                case ((GetParameter("Root") + 4) % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // IV7
                case ((GetParameter("Root") + 5) % 12):
                    buildChord(event, maj7th_Chord);
                    break;
                    // V7
                case ((GetParameter("Root") + 7) % 12):
                    buildChord(event, dom7th_Chord);
                    break;
                    // vi7
                case ((GetParameter("Root") + 9) % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // vii°7
                case ((GetParameter("Root") + 11) % 12):
                    buildChord(event, dim7th_Chord);
                    break;
                    // Default
                default:
                    break;
            }
        } else if (GetParameter("Mode") == 1) {
            // MINOR
            switch (event.pitch % 12) {
                // i7
                case (GetParameter("Root") % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // ii°7
                case ((GetParameter("Root") + 2) % 12):
                    buildChord(event, dim7th_Chord);
                    break;
                    // III7
                case ((GetParameter("Root") + 3) % 12):
                    buildChord(event, maj7th_Chord);
                    break;
                    // iv7
                case ((GetParameter("Root") + 5) % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // v7
                case ((GetParameter("Root") + 7) % 12):
                    buildChord(event, min7th_Chord);
                    break;
                    // VI7
                case ((GetParameter("Root") + 8) % 12):
                    buildChord(event, maj7th_Chord);
                    break;
                    // VII7
                case ((GetParameter("Root") + 10) % 12):
                    buildChord(event, dom7th_Chord);
                    break;
                    // Default
                default:
                    break;
            }
        }
    }
}
 
function buildChord(root, chordtype) {
    if (root instanceof NoteOn) {
        var originalNote = new NoteOn(root);
        var record = {
            originalPitch: root.pitch,
            events: [originalNote]
        };
        root.send();
        for (var i = 0; i < chordtype.length; i++) {
            var harmony = new NoteOn(root);
            harmony.pitch += chordtype[i];
            record.events.push(harmony);
            harmony.send();
        }
        activeNotes.push(record);
    } else if (root instanceof NoteOff) {
        for (var i in activeNotes) {
            if (activeNotes[i].originalPitch == root.pitch) {
                for (var j = 0; j < activeNotes[i].events.length; j++) {
                    var noteOff = new NoteOff(activeNotes[i].events[j]);
                    noteOff.send();
                }
                activeNotes.splice(i, 1);
                break;
            }
        }
    }
}
 
ResetParameterDefaults = true;
 
var PluginParameters = [{
    name: "Chords",
    type: "text"
}, {
    name: "Root",
    type: "menu",
    valueStrings: ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
    defaultValue: 0,
    minValue: 0,
    maxValue: 11,
    numberOfSteps: 12
}, {
    name: "Mode",
    type: "menu",
    valueStrings: ["Major", "Minor"],
    defaultValue: 0,
    minValue: 0,
    maxValue: 1,
    numberOfSteps: 2
}, {
    name: "Flavour",
    type: "menu",
    valueStrings: ["Normal", "Jazzy"],
    defaultValue: 0,
    minValue: 0,
    maxValue: 1,
    numberOfSteps: 2
}];
 
// Copy and paste this chunk of code into your script editor to create controls in your plugin
 
var NeedsTimingInfo = true;
 
var PluginParameters = [];
 
// Types of Plugin Parameters
const LINEAR_FADER = "lin";
const LOGARITHMIC_FADER = "log";
const MOMENTARY_BUTTON = "momentary";
const MENU = "menu";
const NOT_NEEDED = "";
 
/*
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:
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"]);
*/
 
function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  if (type == MENU) {
    PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  }
  else {
    PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  }
}
 
function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
}
 
function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
}
 
//Parameters for the plugin
 
// Repeats note that is played with specified beat divisions
 
var NeedsTimingInfo = true;
var activeNotes = [];
 
function HandleMIDI(event) {
    if (event instanceof NoteOn) {
        // add note to array
        activeNotes.push(event);
    }
    else if (event instanceof NoteOff) {
        // remove note from array
        for (i = 0; i < activeNotes.length; i++) {
            if (activeNotes[i].pitch == event.pitch) {
                activeNotes.splice (i, 1);
                break;
            }
        }
    }
    // pass non-note events through
    else event.send();
 
    // sort array of active notes
    activeNotes.sort(sortByPitchAscending);
}
 
//-----------------------------------------------------------------------------
function sortByPitchAscending (a, b) {
    if (a.pitch < b.pitch) {
    return -1;
  }
    if (a.pitch > b.pitch) {
    return 1;
  }
    return 0;
}
 
//-----------------------------------------------------------------------------
var wasPlaying = false;
 
function ProcessMIDI() {
    // Get timing information from the host application
    var musicInfo = GetTimingInfo();
 
    // clear activeNotes[] when the transport stops and send any remaining note off events
    if (wasPlaying && !musicInfo.playing) {
        for(i = 0;i < activeNotes.length; i++) {
            var off = new NoteOff(activeNotes[i]);
            off.send();
        }
    }
 
    wasPlaying = musicInfo.playing;
 
    if (activeNotes.length != 0) {
 
        // get parameters
        var division = GetParameter("Beat Division");
        var noteOrder = GetParameter("Note Order");
        var noteLength = (GetParameter("Note Length") / 100) * (1 / division);
        // var randomLength = Math.random() * ((GetParameter("Random Length") / 100) * (1 / division));
        // var randomDelay = Math.random() * ((GetParameter("Random Delay") / 100) * (1 / division));
        // var randomOctave = Math.floor(Math.random() * GetParameter("Random Octave")) * 12;
 
        // calculate beat to schedule
        var lookAheadEnd = musicInfo.blockEndBeat;
        var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
        // var nextBeat = musicInfo.blockStartBeat;
 
        // when cycling, find the beats that wrap around the last buffer
        if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat && lookAheadEnd >= musicInfo.rightCycleBeat) {
      var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
      var cycleEnd = lookAheadEnd - cycleBeats;
        }
 
    var state = GetParameter("Reset");
    if (state == 1) {
      Reset();
    }
 
        // loop through the beats that fall within this buffer
        while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd && state == 0)
        // including beats that wrap around the cycle point
        || (musicInfo.cycling && nextBeat < cycleEnd)) {
 
            // adjust for cycle
            if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
                nextBeat -= cycleBeats;
 
            // calculate step
            var step = Math.floor(nextBeat / (1 / division) - division);
            var chosenNote = chooseNote(noteOrder, step);
 
            // send events
            var noteOn = new NoteOn(chosenNote);
            // noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
            noteOn.pitch = MIDI.normalizeData(noteOn.pitch);
            // noteOn.sendAtBeat(nextBeat + randomDelay);
            noteOn.sendAtBeat(nextBeat);
            var noteOff = new NoteOff(noteOn);
            // noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength);
            noteOff.sendAtBeat(nextBeat + noteLength);
 
            // advance to next beat
            nextBeat += 0.001;
            nextBeat = Math.ceil(nextBeat * division) / division;
        }
    }
}
 
function Reset() {
  NeedsTimingInfo = true;
  activeNotes = [];
  SetParameter ("Reset", 0);
}
 
//-----------------------------------------------------------------------------
var noteOrders = ["up", "down", "random"];
 
function chooseNote(noteOrder, step) {
    var order = noteOrders[noteOrder];
    var length = activeNotes.length
    if (order == "up") return activeNotes[step % length];
    if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
    if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
    else return 0;
}
 
//-----------------------------------------------------------------------------
// var PluginParameters =
// [
//      {name:"Beat Division", type:"linear",
//      minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
//
//      {name:"Note Order", type:"menu", valueStrings:noteOrders,
//      minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
//
//      {name:"Note Length", unit:"%", type:"linear",
//      minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199},
//
//      {name:"Random Length", unit:"%", type:"linear",
//      minValue:0, maxValue:200, numberOfSteps: 200, defaultValue:0},
//
//      {name:"Random Delay", unit:"%", type:"linear",
//      minValue:0, maxValue:200, numberOfSteps:200, defaultValue:0},
//
//      {name:"Random Octave", type:"linear",
//      minValue:1, maxValue:4, defaultValue:1, numberOfSteps:3}
// ];
var PluginParameters =
[
        {name:"Beat Division", type:"linear",
        minValue:1, maxValue:16, numberOfSteps:15, defaultValue:1},
 
        {name:"Note Order", type:"menu", valueStrings:noteOrders,
        minValue:0, maxValue:2, numberOfSteps: 3, defaultValue:0},
 
        {name:"Reset", type:"menu", valueStrings:["Off", "On"],
        minValue:0, maxValue:1, numberOfSteps: 2, defaultValue:0},
 
        {name:"Note Length", unit:"%", type:"linear",
        minValue:1, maxValue:200, defaultValue:100.0, numberOfSteps:199}
];
 
// ----------------------------------------------------------------------------
// Code from plugin.js
 
// Copy and paste this chunk of code into your script editor to create controls in your plugin
 
// var PluginParameters = [];
 
// Types of Plugin Parameters
const LINEAR_FADER = "lin";
const LOGARITHMIC_FADER = "log";
const MOMENTARY_BUTTON = "momentary";
const MENU = "menu";
const NOT_NEEDED = "";
 
/*
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:
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"]);
*/
 
function createPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  if (type == MENU) {
    PluginParameters.push (createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings));
  }
  else {
    PluginParameters.push (createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text));
  }
}
 
function createBasicPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text};
}
 
function createMenuPluginParameter (name, type, minValue, maxValue, defaultValue, numberOfSteps, unit, text, valueStrings) {
  return {name: name, type: type, minValue: minValue, maxValue: maxValue, numberOfSteps: numberOfSteps, unit: unit, text: text, valueStrings: valueStrings};
}
 
//Parameters for the plugin
 
// Constructs a sequence of notes triggered relative to the base note
 
var NeedsTimingInfo = true;
var activeNotes = [];
var sequence = [2, 2, 1, 2, 2, 2, 1]; // Choose your sequence here. Enter integers for ups or downs
/* needed to make beatPos work */
function HandleMIDI(event) {
  if (event instanceof NoteOn) {
    constructSequence(event);
    // activeNotes.push(event);
    // for (var i = 0; i < sequence.length; i++) {
    //   var on = new NoteOn (activeNotes[i]);
    //   var previous  = new NoteOn (activeNotes[i])
    //   on.pitch = MIDI.normalizeData(previous.pitch + sequence[i]);
    //   activeNotes.push (on);
    //   on.sendAtBeat(previous.beatPos + 2);
    // }
  }
 
  else if (event instanceof NoteOff) {
        // remove note from array
    Reset();
        for (i = 0; i < activeNotes.length; i++) {
            if (activeNotes[i].pitch == event.pitch) {
                activeNotes.splice(i, 1);
                break;
            }
        }
    }
 
  else {
    event.send();
  }
}
 
function Reset() {
  activeNotes = [];
}
 
// function ProcessMIDI() {
//   for (var i = 0; i < activeNotes.length; i++) {
//     var currentNote = new NoteOn (sequence[i]);
//     currentNote.send();
//   }
// }
 
function constructSequence(event) {
  activeNotes.push (event);
  for (var i = 0; i < sequence.length; i++) {
    var on = new NoteOn;
    on.pitch = MIDI.normalizeData(activeNotes[i].pitch + sequence[i]);
    activeNotes.push (on);
  }
}
 
var wasPlaying = false;
 
function ProcessMIDI() {
    // Get timing information from the host application
    var musicInfo = GetTimingInfo();
 
    // clear activeNotes[] when the transport stops and send any remaining note off events
    if (wasPlaying && !musicInfo.playing){
        for(i=0;i<activeNotes.length;i++) {
            var off = new NoteOff(activeNotes[i]);
            off.send();
        }
    }
 
    wasPlaying = musicInfo.playing;
 
    if (activeNotes.length != 0) {
 
        // get parameters
        // var division = GetParameter("Beat Division");
        var division = 1;
        var noteOrder = 0;
        var noteLength = (100 / 100) * (1 / division);
        var randomLength = 0;
        var randomDelay = 0;
        var randomOctave = 1;
 
        // calculate beat to schedule
        var lookAheadEnd = musicInfo.blockEndBeat;
        var nextBeat = Math.ceil(musicInfo.blockStartBeat * division) / division;
 
        // when cycling, find the beats that wrap around the last buffer
        if (musicInfo.cycling && lookAheadEnd >= musicInfo.rightCycleBeat) {
            if (lookAheadEnd >= musicInfo.rightCycleBeat) {
                var cycleBeats = musicInfo.rightCycleBeat - musicInfo.leftCycleBeat;
                var cycleEnd = lookAheadEnd - cycleBeats;
            }
        }
 
        // var state = GetParameter("Reset");
    // if (state == 1) {
    //   Reset();
    // }
 
        // loop through the beats that fall within this buffer
        while ((nextBeat >= musicInfo.blockStartBeat && nextBeat < lookAheadEnd)
        // including beats that wrap around the cycle point
        || (musicInfo.cycling && nextBeat < cycleEnd)) {
            // adjust for cycle
            if (musicInfo.cycling && nextBeat >= musicInfo.rightCycleBeat)
                nextBeat -= cycleBeats;
 
            // calculate step
            var step = Math.floor(nextBeat / (1 / division) - division);
            var chosenNote = chooseNote(noteOrder, step);
 
            // send events
            var noteOn = new NoteOn(chosenNote);
            // noteOn.pitch = MIDI.normalizeData(noteOn.pitch + randomOctave);
            noteOn.pitch = (noteOn.pitch + randomOctave);
            noteOn.sendAtBeat(nextBeat + randomDelay);
            var noteOff = new NoteOff(noteOn);
            noteOff.sendAtBeat(nextBeat + randomDelay + noteLength + randomLength)
 
            // advance to next beat
            nextBeat += 0.001;
            nextBeat = Math.ceil(nextBeat * division) / division;
        }
    }
}
 
var noteOrders = ["up", "down", "random"];
 
function chooseNote(noteOrder, step) {
    var order = noteOrders[noteOrder];
    var length = activeNotes.length
    if (order == "up") return activeNotes[step % length];
    if (order == "down") return activeNotes[Math.abs(step % length - (length - 1))];
    if (order == "random") return activeNotes[Math.floor(Math.random() * length)];
    else return 0;
}
 
// function constructSequence(event) {
//   activeNotes.push (event);
//   for (var i = 0; i < sequence.length; i++) {
//     var on = new NoteOn;
//     on.pitch = MIDI.normalizeData(activeNotes[i].pitch + sequence[i]);
//     on.beatPos = activeNotes[i].beatPos + 1;
//     activeNotes.push (on);
//   }
// }
 

Comments