Jump to content

Modifying 'delay note until next beat' to choose from array


Recommended Posts

Like the title says, I'd like to modify this script to randomly choose different rhythmic values from an array.

Not sure why it's not working...

 


var NeedsTimingInfo = true;

var beatArray = ['1','3','1.5'];
var randomBeat = beatArray[Math.floor(Math.random() * beatArray.length)];

function HandleMIDI(e) {

var info = GetTimingInfo();

if (e instanceof NoteOn)
{
     randomBeat = beatArray[Math.floor(Math.random() * beatArray.length)];
     e.sendAtBeat(Math.ceil(info.blockStartBeat) + randomBeat);
}
	
else if (e instanceof NoteOff)
	e.sendAtBeat(Math.ceil(info.blockStartBeat) + randomBeat);
else
	e.send();
	
}

Link to comment
Share on other sites

First problem I see is that you are defining your array of beat offsets, as strings rather then as numbers. So later on when you add the random beat offset to blockStartBeat, a string concatenation occurs, resulting in very large beat offsets. The + operator in javascript concatenates strings if there are any strings on either side of it, and it will convert numbers to strings on the fly if it has to... So for example, if you had a midi note at beat 1 and run it through your script, let's say the random value selected for it is '3', then the resulting operation would result in beat 13, not 4, because 1+'3' = 13.

 

So for starters...

 

var beatArray = [1,3,1.5];

 

Beyond that I see a few potential problems with what you're doing, so just want to comment about that a little bit. Not entirely sure exactly what you're trying to accomplish. But anyway, I just want to point out you can use the event.beatPos attribute of the event object to determine the exact time location of the incoming beat you're wanting to move. Basing your math off the start of the processing block is a little odd, the processing block has no bearing on the meter whatsoever. Also, since you're rounding it off, and sometimes downwards, you could be rounding it so far down, that its too late to schedule the resulting number you plan to use for the AtBeat function. The number passed into AtBeat needs to be at least as big as info.blockStartBeat. If you pass something smaller, you won't hear it.

 

Next, your Noteoff's have the potential to get confused by making the randomly produced note off occur before the actual NoteOn that was meant to turn off. Keeping track of note on's that require note off's kind of has to be done at the global level and can get complicated.

Link to comment
Share on other sites

  • 2 weeks later...

in HandleMIDI do this:

 

function HandleMIDI(event) {
  if(event instanceof NoteOff) {
      return;
  }
}

 

the above will ignore NoteOff events...

 

Then you need code to send NoteOff's so something like this:

 

function HandleMIDI(event) {
  event.sendAtBeat(A);
  event.velocity = 0;
  event.sendAtBeat(A+.5);
}

 

Setting velocity to zero is same as sending noteoff. so for each of your notes you send, just send it, add some amount of time (in the above its half a beat) and then send the same event with velocity zero.

Link to comment
Share on other sites

Not really sure why, but I was able to make this work based on your suggestion:

 

ResetParameterDefaults = true;
var NeedsTimingInfo = true;

var beatArray = [1,1.5,2,2.3,3];
var cutArray = [.5,2.3,3.3,3.6,4.3,4.6];

var randomBeat = beatArray[Math.floor(Math.random() * beatArray.length)];
var randomCut = cutArray[Math.floor(Math.random() * cutArray.length)];

function HandleMIDI(e) {
  
   var info = GetTimingInfo();
   var Pos = e.beatPos;
 

  if (e instanceof NoteOn)
  {
     randomBeat = beatArray[Math.floor(Math.random() * beatArray.length)];
     e.sendAtBeat(Math.ceil(Pos) + randomBeat);
  
  }
     else if (e instanceof NoteOff)
     e.sendAtBeat(Math.ceil(Pos) + randomBeat + randomCut);
     
}

Trace("Random Beat: " + randomBeat);

Trace("Random Cuttoff: " + randomCut);

 

Maybe because the NoteOff message coming in tells the script to hold that and send it out later?

 

In any event, thanks for the help :)

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.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  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.

×
×
  • Create New...