Jump to content

Play sequential notes based on ms [SOLVED]


Recommended Posts

I am trying to reverse engineer and modify one of the factory presets called "Delayed Notes", and I was able to (almost) achieve the effect I want (see note below the code).

So basically what I would like to achieve is:

 

If the note is C1

Play that note for X amount of ms

Then after X amount of ms, play note C#1, for X amount of ms

Then after X amount of ms, play note D1 for X amount of ms

 

Here's the code I ended up with so far:

// ************************
// Sequential Delayed Notes
// ************************

var pitch1 = 37;
var pitch2 = 38;
var delayTime1 = 2000;
var delayTime2 = 4000;
var sampleLength = 50;
var sampleLength2 = 70;
var sampleLength3 = 90;

function HandleMIDI(event) {
if (event instanceof NoteOn && event.pitch == 36) {
	event.send();
	var off = new NoteOff(event);
	off.sendAfterMilliseconds(sampleLength);
	
	var newPitch1 = new NoteOn;
	newPitch1.pitch = pitch1;
	newPitch1.sendAfterMilliseconds(delayTime1);
	
	//This is where I get stuck....
	var off1 = new NoteOff(newPitch1);
	off1.sendAfterMilliseconds(sampleLength2);
	
	var newPitch2 = new NoteOn;
	newPitch2.pitch = pitch2;
	newPitch2.sendAfterMilliseconds(delayTime2);
	
}
/*else if (event instanceof NoteOff) return;
else event.send();*/
}

 

Right now I can make the first note have the length of 50ms, but notes 2 and 3 won't change, even if I add some code to it for NoteOff.

See the comment where I get stuck...

Any tips?

Danny Wyatt (formerly known as 3ple here on the forum)
Musician, Music Producer, Songwriter, DJ
Official Website: http://www.iamdannywyatt.com  - Join my Discord: https://dwyatt.me/discord

Logic Pro 10.6.3 • M-Audio Fast Track Pro 4x4 • MacBook Pro 13" Mid 2012 || 2.5 GHz Dual-Core Intel Core i5 || 8GB 1600 MHz DDR3 RAM • macOS Catalina 10.15.7

Link to comment
Share on other sites

There are some problems in your script

 

when you defined newPitch1 as a NoteOn event, you did not assign channel nor velocity values to it. This later also affected the off1 event you created and newPitch2

 

Secondly you need to remember that the entire script is happening from a point in time referencing the time the event came into the HandleMIDI function. every delayAfterMilliseconds call should be relative to that original time. So you need to add them up as you go so that each call to that function accumulates enough delay time.

OSX 12.x (Monterey) on OpenCore - Logic Pro 10.7.4, VePro7, Mainstage3 - 5,1 MacPro 3.46ghz x 12 96gb ram

Link to comment
Share on other sites

There are some problems in your script

 

when you defined newPitch1 as a NoteOn event, you did not assign channel nor velocity values to it. This later also affected the off1 event you created and newPitch2

 

Secondly you need to remember that the entire script is happening from a point in time referencing the time the event came into the HandleMIDI function. every delayAfterMilliseconds call should be relative to that original time. So you need to add them up as you go so that each call to that function accumulates enough delay time.

 

 

Thanks. I will have to check what you wrote in depth so I can understand what the issues are so I can avoid them in the future.

Meanwhile, since I wrote this post, I was able to make it work.

I just copied and pasted the original code 2 more times.

It's working now and even if it's not the cleanest thing a developer would see, at least I was able to make it work :)

 

Here:

//************************************************
// Kick Builder by Danny Wyatt
// www.iamdannywyatt.com
//************************************************

// Start
function HandleMIDI(event) {

// Sample Notes Variables
var sampleNote1 = GetParameter ("Sample 1 Note (36 = C1)");
var sampleNote2 = GetParameter ("Sample 2 Note (36 = C1)");
var sampleNote3 = GetParameter ("Sample 3 Note (36 = C1)");

// Crosspoints Variables
var crossPoint1 = GetParameter ("Sample 1 Length (ms)");
var crossPoint2 = crossPoint1 + GetParameter ("Sample 2 Length (ms)");
var endPoint = crossPoint2 + GetParameter ("Sample 3 Length (ms)");

// Velocity Variables
var velocity1 = GetParameter ("Sample 1 Velocity");
var velocity2 = GetParameter ("Sample 2 Velocity");
var velocity3 = GetParameter ("Sample 3 Velocity");

// Sample 1
if (event instanceof NoteOn) {
	event.pitch = sampleNote1;
	event.velocity = velocity1;
	event.send();		
	var off1 = new NoteOff(event);
	off1.sendAfterMilliseconds(crossPoint1);
}
else if (event instanceof NoteOff) return;
else event.send();

// Sample 2
if (event instanceof NoteOn) {
	event.pitch = sampleNote2;
	event.velocity = velocity2;
	event.sendAfterMilliseconds(crossPoint1);		
	var off2 = new NoteOff(event);
	off2.sendAfterMilliseconds(crossPoint2);
}
else if (event instanceof NoteOff) return;
else event.send();

// Sample 3
if (event instanceof NoteOn) {
	event.pitch = sampleNote3;
	event.velocity = velocity3;
	event.sendAfterMilliseconds(crossPoint2);		
	var off3 = new NoteOff(event);
	off3.sendAfterMilliseconds(endPoint);
}
else if (event instanceof NoteOff) return;
else event.send();
}

// Controls
var PluginParameters = [
// Sample 1
{name:'Sample 1 Note (36 = C1)', type:'lin',
minValue:0, maxValue:127, defaultValue:36, numberOfSteps:127},
{name:'Sample 1 Length (ms)', type:'lin', unit:'ms',
minValue:0, maxValue:2000, defaultValue:50, numberOfSteps:2000},
{name:'Sample 1 Velocity', type:'lin',
minValue:0, maxValue:127, defaultValue:127, numberOfSteps:127},

// Sample 2
{name:'Sample 2 Note (36 = C1)', type:'lin',
minValue:0, maxValue:127, defaultValue:37, numberOfSteps:127},
{name:'Sample 2 Length (ms)', type:'lin', unit:'ms',
minValue:0, maxValue:2000, defaultValue:50, numberOfSteps:2000},
{name:'Sample 2 Velocity', type:'lin',
minValue:0, maxValue:127, defaultValue:127, numberOfSteps:127},

// Sample 3
{name:'Sample 3 Note (36 = C1)', type:'lin',
minValue:0, maxValue:127, defaultValue:38, numberOfSteps:127},
{name:'Sample 3 Length (ms)', type:'lin', unit:'ms',
minValue:0, maxValue:2000, defaultValue:100, numberOfSteps:2000},
{name:'Sample 3 Velocity', type:'lin',
minValue:0, maxValue:127, defaultValue:127, numberOfSteps:127}
];

 

 

This is a prototype for something I would like to develop one day as a real plugin, with way more features and all that, but for now it does what is supposed to :)

719005217_ScreenShot2022-02-18at6_14_54PM.png.ca49e1faecd0ea53ecf51840ef9d6c10.png

Danny Wyatt (formerly known as 3ple here on the forum)
Musician, Music Producer, Songwriter, DJ
Official Website: http://www.iamdannywyatt.com  - Join my Discord: https://dwyatt.me/discord

Logic Pro 10.6.3 • M-Audio Fast Track Pro 4x4 • MacBook Pro 13" Mid 2012 || 2.5 GHz Dual-Core Intel Core i5 || 8GB 1600 MHz DDR3 RAM • macOS Catalina 10.15.7

Link to comment
Share on other sites

also one little trick that is good to use, is that you don't need to create so many Event objects. You can reuse the same event object and just change the pitch and send it again, etc.. and even more than that you can also cause a NoteOn to function like a NoteOff by settings its velocity to zero. For example like this:

 

// ************************
// Sequential Delayed Notes
// ************************

var pitch1 = 37;
var pitch2 = 38;
var delayTime1 = 2000;
var delayTime2 = 4000;
var sampleLength = 50;
var sampleLength2 = 70;
var sampleLength3 = 90;

function HandleMIDI(event) {
  if (event instanceof NoteOn && event.pitch == 36) {
     var vel = event.velocity;
     event.send();
     event.velocity = 0;
     event.sendAfterMilliseconds(sampleLength);
     
     event.pitch = pitch1;
     event.velocity = vel;
     event.sendAfterMilliseconds(delayTime1);
     event.velocity = 0;
     event.sendAfterMilliseconds(delayTime1 + sampleLength2);

     event.pitch = pitch2;
     event.velocity = vel;
     event.sendAfterMilliseconds(delayTime2);
     event.velocity = 0;
     event.sendAfterMilliseconds(delayTime2 + sampleLength3);
  }

  }

OSX 12.x (Monterey) on OpenCore - Logic Pro 10.7.4, VePro7, Mainstage3 - 5,1 MacPro 3.46ghz x 12 96gb ram

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...