DjStiky Posted December 12, 2016 Share Posted December 12, 2016 Hi Guys, Was wondering if anyone could create a script where you could do the following: - Select 1 or many notes from C to B (Would affect said notes on all octaves) - Set a pitch bend value for each of the selected notes - Send the note plus pitch bend value whenever that note(s) is/are played on a keyboard and then reset pitch bend when note is released. If it's simpler, you could also just list all the notes from C to B and then a pitchbend value next to each The reason I'm asking this is so I can have microtuning with legato or portamento instruments in Kontakt. Right now, combining both the built in portamento and microtuning scripts in Kontakt together doesn't work, conflict with each other and sounds weird. Thanks! Quote Link to comment Share on other sites More sharing options...
autodidactic Posted January 7, 2017 Share Posted January 7, 2017 I had making a microtuner on my to do list for a while, so I thought this would be a good opportunity to get it done. I'll be using it for middle eastern style quarter tones. I have the code below. CAVEAT: The only thing that I can't figure out is how to manipulate the time it takes for the bend to complete. Smaller values seem to be usable but the further away the value gets from zero, the longer it takes for the bend to complete. Maybe somebody can chime in and let me know if there is a property some other value to adjust. var pitches = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]; var detuned = [0,0,0,0,0,0,0,0,0,0,0,0] function findPitch(midiNote){ var mod = midiNote % 12; var result = pitches[mod] return result; } var PluginParameters = [ { name:"Bend Value", type:"lin", defaultValue:-1450, minValue:-4000, maxValue:0, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; /* NOTE: Play with the ranges. Valid pitch bend value range is a 14-bit pitch bend value from -8192–8191. A value of 0 is center. BEWARE: The further away you get from center (0), the longer it takes for the bends to complete. I need to find a way to make the bends instant. */ } }, { name:"NOTES TO DETUNE", type:"text", callBack: function(value){ // Do nothing. This is just a label! } }, { name:"C", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[0] = value; } }, { name:"C#", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[1] = value; } }, { name:"D", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[2] = value; } }, { name:"D#", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[3] = value; } }, { name:"E", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[4] = value; } }, { name:"F", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[5] = value; } }, { name:"F#", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[6] = value; } }, { name:"G", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[7] = value; } }, { name:"G#", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[8] = value; } }, { name:"A", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[9] = value; } }, { name:"A#", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[10] = value; } }, { name:"B", type:"menu", valueStrings:["Off", "On"], defaultValue:0, numberOfSteps:2, callBack: function(value){ //Trace("Setting detuned note to " + value); detuned[11] = value; } } ] function ParameterChanged(param,value){ PluginParameters[param].callBack(value); } function HandleMIDI(event) { var bend = new PitchBend(); if(event.status === 144){ var note = findPitch(event.pitch); var index = pitches.indexOf(note); if(detuned[index] === 1){ bend.value = PluginParameters[0].currentValue; // Set in UI bend.inStartFrame = 1; bend.send(); event.send } else { bend.value = 0; bend.inStartFrame = 1; bend.send(); event.send } } event.send(); } Quote Link to comment Share on other sites More sharing options...
Unheardofski Posted March 15, 2017 Share Posted March 15, 2017 Pretty cool solution for the PluginParameter callback. I haven't thought of that! re: pitchbend, I've run into the same thing and gave up. Quote Link to comment Share on other sites More sharing options...
autodidactic Posted April 5, 2017 Share Posted April 5, 2017 Pretty cool solution for the PluginParameter callback. I haven't thought of that! Thanks man! It makes everything neat and tidy when the callback is together with the rest of it. Quote Link to comment Share on other sites More sharing options...
maciejsaw Posted April 20, 2020 Share Posted April 20, 2020 I rewritten your script so that it allows tuning of each note via sliders var pitches = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]; var detuned = [0,0,0,0,0,0,0,0,0,0,0,0] function findPitch(midiNote){ var mod = midiNote % 12; var result = pitches[mod] return result; } var PluginParameters = [ { name:"C", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"C#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"D", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"D#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"E", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"F", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"F#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"G", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"G#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"A", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"A#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"B", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, ] function ParameterChanged(param,value){ PluginParameters[param].callBack(value); } function HandleMIDI(event) { var bend = new PitchBend(); if(event.status === 144){ var note = findPitch(event.pitch); var index = pitches.indexOf(note); Trace(index) bend.value = PluginParameters[index].currentValue; // Set in UI bend.inStartFrame = 1; bend.send(); } event.send(); } Quote Link to comment Share on other sites More sharing options...
Mark R Posted April 21, 2020 Share Posted April 21, 2020 Very useful. Thank you! Quote Link to comment Share on other sites More sharing options...
Pixelpoet1985 Posted June 2, 2022 Share Posted June 2, 2022 (edited) On 4/21/2020 at 1:51 AM, maciejsaw said: I rewritten your script so that it allows tuning of each note via sliders var pitches = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"]; var detuned = [0,0,0,0,0,0,0,0,0,0,0,0] function findPitch(midiNote){ var mod = midiNote % 12; var result = pitches[mod] return result; } var PluginParameters = [ { name:"C", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"C#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"D", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"D#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"E", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"F", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"F#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"G", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"G#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"A", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"A#", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, { name:"B", type:"lin", defaultValue:0, minValue:-4000, maxValue:4000, numberOfSteps:80, currentValue:-1450, callBack: function(value){ this.currentValue = value; } }, ] function ParameterChanged(param,value){ PluginParameters[param].callBack(value); } function HandleMIDI(event) { var bend = new PitchBend(); if(event.status === 144){ var note = findPitch(event.pitch); var index = pitches.indexOf(note); Trace(index) bend.value = PluginParameters[index].currentValue; // Set in UI bend.inStartFrame = 1; bend.send(); } event.send(); } Thanks for the script! I also want to use it for Kontakt legato instruments. I have no experience with the scripter, so I have some questions: What does the values (-4000, 4000) and the steps (80) stand for? Are these values in cent? Is it possible to have all keys of an 88 keyboard shown in the GUI, so that I can manipulate the tuning of each key and not only octaves? Thanks in advance. Edited June 2, 2022 by Pixelpoet1985 Quote Link to comment Share on other sites More sharing options...
airforceguitar Posted December 10, 2022 Share Posted December 10, 2022 I’m trying this out! BTW, I just purchased the Pitch Innovations “Fluid-Pitch” and “Fluid-Chords” plugins The Fluid Pitch plugin does this exactly. 🤘 Quote Link to comment Share on other sites More sharing options...
Musictician Posted April 12, 2023 Share Posted April 12, 2023 This script was incredibly helpful! Quote Link to comment Share on other sites More sharing options...
ToniMazzotti Posted April 27, 2023 Share Posted April 27, 2023 This script is very good, thank you for sharing. But he resends the pitch bend information with each new note played. That is, he can't keep the tuning of the previous note. This is because all the notes are being sent to the same MIDI channel. I wanted to know if anyone knows how to send each new note to a new unoccupied midi channel. From 1 to 6, in loop. Quote Link to comment Share on other sites More sharing options...
Atlas007 Posted April 27, 2023 Share Posted April 27, 2023 Putting them on different tracks or edit each note event’s midi channel perhaps… Quote Link to comment Share on other sites More sharing options...
anp27 Posted May 1, 2023 Share Posted May 1, 2023 This is very cool! 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.