thomaskyhn Posted December 23, 2015 Share Posted December 23, 2015 I'm a complete newbie as regards JavaScript. I found a basic note delay script, which I'd like to modify to get a random note delay script. function HandleMIDI(event) { event.send(); if (event instanceof Note) { event.sendAfterMilliseconds(delayTime); } } var delayTime; var PluginParameters = [ {name:'Delay Time', type:'lin', unit:'ms', minValue:0, maxValue:1200, defaultValue:1, numberOfSteps:120}, ] function ParameterChanged(param, value) { var timeInMilliseconds = value; if (param == 0) delayTime = timeInMilliseconds; }; I tried out this, but it's not working: function HandleMIDI(event) { event.send(); if (event instanceof Note) { event.sendAfterMilliseconds(delayTime); } } var delayTime; var PluginParameters = [ {name:'Random Delay', type:'lin', unit:'ms', minValue:0, maxValue:12000, defaultValue:1, numberOfSteps:120}, ] function ParameterChanged(param, value) { var delayTime = Math.random() * ((GetParameter("Random Delay")) * 10000); }; Perhaps someone here would be able to point me in the right direction. Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted January 23, 2016 Share Posted January 23, 2016 You need a min value and a max value for Math.random. example: function delayTime(min,max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Here's a fix: function HandleMIDI(event) { event.send(); if (event instanceof Note) { event.sendAfterMilliseconds(randomDelay(0, delayTime)); } } var delayTime = 0; var PluginParameters = [{ name: 'Random Delay', type: 'lin', unit: 'ms', minValue: 0, maxValue: 1200, defaultValue: 1, numberOfSteps: 120 }, ] function ParameterChanged(param, value) { delayTime = value; }; function randomDelay(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 Thanks for your help! If I wanted to leave out the initial note and only have the delay, what part would I need to change? As I understand, the second line – "event.send();" – lets the initial note pass through untouched, but just deleting that part doesn't seem to work. Quote Link to comment Share on other sites More sharing options...
Eric Cardenas Posted January 23, 2016 Share Posted January 23, 2016 Use: event.trace(); Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 Replacing event.send(); with eventTrace(); gives me this output: Exception calling HandleMIDI() function: [JS Exception] TypeError: event.Trace is not a function. (In 'event.Trace()', 'event.Trace' is undefined) line:2 Do I need to put it somewhere else? Quote Link to comment Share on other sites More sharing options...
Eric Cardenas Posted January 23, 2016 Share Posted January 23, 2016 Sorry... I edited my post it's: event.trace(); Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted January 23, 2016 Share Posted January 23, 2016 Actually you should keep track of the generated delay and assign it to the note off as well. Otherwise you can end up sending note off before note on. Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 Sorry... I edited my post it's: event.trace(); Thanks! It works now. Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 Actually you should keep track of the generated delay and assign it to the note off as well. Otherwise you can end up sending note off before note on. That makes sense. Quote Link to comment Share on other sites More sharing options...
Eric Cardenas Posted January 23, 2016 Share Posted January 23, 2016 Actually you should keep track of the generated delay and assign it to the note off as well. Otherwise you can end up sending note off before note on. Thanks Unheardofski. How do you do that exactly. I've wondered about this myself? Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 I tried this, but it doesn't work as intended: function HandleMIDI(event) { event.trace(); if (event instanceof NoteOn) { event.sendAfterMilliseconds(randomDelay(0, delayTime)); } else if (event instanceof NoteOff ) { event.sendAfterMilliseconds(randomDelay(0, delayTime)); } } I assume that rather than apply the same random delay to both events, it randomizes them individually. Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted January 23, 2016 Share Posted January 23, 2016 a bit swamped can't explain right now, this is how I'd do the whole thing from scratch - but there is no ONE correct way var PluginParameters = []; var noteDelay = []; for (var i = 0; i < 128; i++) { noteDelay[i] = 0; } var keep = 0; var maxDelay = 0; createParam('Random delay max ms', 'lin', 0, 0, 1200, 0, 1200, 'ms'); createParam('Keep original note? ', 'menu', ['Off', 'On '],0,1,0); function ParameterChanged(p,v){ p ? keep = v : maxDelay = v; } function HandleMIDI(e){ if(e instanceof Note){ e instanceof NoteOn ? e.delay = randomDelay(0, maxDelay):e.delay = noteDelay[e.pitch]; e instanceof NoteOn ? noteDelay[e.pitch] = e.delay:false; keep ? e.send():false; e.sendAfterMilliseconds([e.delay]); } else e.send(); } function createParam(n, t, vs, miv, mav, def, nos, unit) { PluginParameters.push({ name: n, type: t, valueStrings: vs, minValue: miv, maxValue: mav, defaultValue: def, numberOfSteps: nos, unit: unit }); } function randomDelay(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Quote Link to comment Share on other sites More sharing options...
Eric Cardenas Posted January 23, 2016 Share Posted January 23, 2016 Thank you so much! Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 23, 2016 Author Share Posted January 23, 2016 Thanks!! Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted January 23, 2016 Share Posted January 23, 2016 You'r welcome guys. Here are some comments to help grasp the script We declare our global variables here, noteDelay is an Array which we also initialise by looping with one 'spot' for each midi note. We also add a variable for the option of keeping the original note or not: var PluginParameters = []; var noteDelay = []; for (var i = 0; i < 128; i++) { noteDelay[i] = 0; } var keep = 0; var maxDelay = 0; I've made this simple function instead of having to type out each 'Param push' - function itself is closer to the bottom of the script: createParam('Random delay max ms', 'lin', 0, 0, 1200, 0, 1200, 'ms'); createParam('Keep original note? ', 'menu', ['Off', 'On '],0,1,0); Since we only have two parameters we can use a ternary operator to save space and not have to type a novel. This basically means in plain speak. "p (param) exists? (1 will return true, 0 returns false - so if the function receives parameter 1 this is true, if parameter 0 its false) if yes keep equals the value, if no maxDelay equals the value. function ParameterChanged(p,v){ p ? keep = v : maxDelay = v; } We use a standard if operator to separate note events from non-note events. Then I went with ternary again - note how you can use false if you only want to use it for one outcome. So we first check if its note on or off. If on we get the delay from the random delay function***. If off we get it from the array (note ons send it to the array in the next line) by getting the element that corresponds to the note pitch. ***Here's the neat part; even though a MIDI event normally doesn't have a delay property, we can create it by simply declaring it. Then if we have a note on we store the delay value in the noteDelay array. Next we check the keep variable, if its 1 we send the note unchanged. Finally we send our delayed note regardless if note on or off. The function ends with sending any non note event. function HandleMIDI(e){ if(e instanceof Note){ e instanceof NoteOn ? e.delay = randomDelay(0, maxDelay):e.delay = noteDelay[e.pitch]; e instanceof NoteOn ? noteDelay[e.pitch] = e.delay:false; keep ? e.send():false; //e.sendAfterMilliseconds([e.delay]); //Noticed this looks weird. Should probably be: e.sendAfterMilliseconds(e.delay); } else e.send(); } This is a good link to understand the Math functions: http://www.w3schools.com/jsref/jsref_obj_math.asp function randomDelay(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 31, 2016 Author Share Posted January 31, 2016 Is there a simple way to modify this script in order to get a random note length effect? Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted January 31, 2016 Share Posted January 31, 2016 made some small additions to achieve this. var PluginParameters = []; var noteDelay = []; for (var i = 0; i < 128; i++) { noteDelay[i] = 0; } var keep = 0; var maxDelay = 0; var min_len = 0; var max_len = 0; createParam('Random delay max ms', 'lin', 0, 0, 1200, 0, 1200, 'ms'); createParam('Min note length ms', 'lin', 0, 0, 1200, 0, 1200, 'ms'); createParam('Max note length ms', 'lin', 0, 0, 1200, 0, 1200, 'ms'); createParam('Keep original note? ', 'menu', ['Off', 'On '],0,1,0); function ParameterChanged(p,v){ p == 0 ? maxDelay = v :false; p == 1 ? min_len = v: false; p == 2 ? max_len = v : false; p == 3 ? keep = v : false; } function HandleMIDI(e){ if(e instanceof Note){ e instanceof NoteOn ? e.delay = randomDelay(0, maxDelay):e.delay = noteDelay[e.pitch] + randomDelay(min_len,max_len); e instanceof NoteOn ? noteDelay[e.pitch] = e.delay:false; keep ? e.send():false; e.sendAfterMilliseconds(e.delay); } else e.send(); } function createParam(n, t, vs, miv, mav, def, nos, unit) { PluginParameters.push({ name: n, type: t, valueStrings: vs, minValue: miv, maxValue: mav, defaultValue: def, numberOfSteps: nos, unit: unit }); } function randomDelay(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } Quote Link to comment Share on other sites More sharing options...
thomaskyhn Posted January 31, 2016 Author Share Posted January 31, 2016 made some small additions to achieve this. Thanks so much! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.