Jump to content

When hitting one note, first play X note then next time Y note [SOLVED]


Danny Wyatt

Recommended Posts

It's called Round Robin, and frankly, I'd just use the facilities that are already built into Sampler, any sampler and any drum plugin worth its salt. Logic's DrumKit Designer has RR with many more samples than just two, so just use that and you're set.

 

Round Robin is not what I need in this case...

DKD has 2 kinds of rimshot sounds. One using E1 and another one using G#0.

If you play fast notes both on E1 or G#0, even if Round Robin is being used for those 2 notes (which to my hears, probably not, because it sounds like a machine gun), it doesn't sound natural at all.

So my goal is to have those 2 being triggered one after another, when I play above a certain velocity, for example 120 or so.

As much as it doesn't sound as natural as an acoustic snare, it sounds way more natural than playing the same note.

 

So using the Scripter, what kind of "function" or "condition" (or whatever the name is... haha) should I research to achieve this?

I'm assuming it would need some kind of memory (buffer, I guess) where it would know which note played before so it can trigger the second one, then the first one again, right?

Any ideas? :)

Link to comment
Share on other sites

The raw concept is this:

 

If a Rimshot NoteOn comes in, you check if Round (which you initially defined as False) is still False. If that's the case, you change Round to True (this is the switch which causes the next hit to get diverted), else it must be True, which means event.pitch needs to be changed to D#0, but wait, you just changed a NoteOn to something else, so its trailing NoteOff which is still looking for E1 will not catch it. You could try to chase that down and change the NoteOff it properly, but you won't know when it comes, and many notes could have been in between, including a legit E1 NoteOff. It's better to just create a new, proper D#0 NoteOff, wait a little and send it off, and then reset Round to False.

 

More formally:

 

var Round = false  // you prepare the trap, it's not armed yet 

HandleMIDI(event) // fetch the next MIDI event
(
   if its a NoteOn @E1 ( // it's a rimshot !
       if Round is false ( // trap is not armed
           Round = true // trap is armed now!
       else // trap was already armed and is triggered!
           event.pitch = G#0 // change the event to the other note
           create a new NoteOff @G#0 and wait a few milliseconds before sending it  // since the original Note Off is still looking for E1
           Round = false // disarm the trap
       )
   )
   send // play the event
   trace // display the event in the console
)

You can turn that into proper code.

Link to comment
Share on other sites

The main point @fuzzfilth is demonstrating above is to use a global variable (Round), to track which note to fire. You declare that global outside of the HandleMIDI function. That way its current value is maintained over time, in between the calls to HandleMIDI. Each time HandleMIDI is called, it will have that globally maintained value available, and you are essentially just switching it back and forth.
Link to comment
Share on other sites

The main point @fuzzfilth is demonstrating above is to use a global variable (Round), to track which note to fire. You declare that global outside of the HandleMIDI function. That way its current value is maintained over time, in between the calls to HandleMIDI. Each time HandleMIDI is called, it will have that globally maintained value available, and you are essentially just switching it back and forth.

 

So I'm guessing that there's some kind of "buffer"/memory that knows that a certain variable is in a certain state or not (in this case True or False), correct?

The Scripter will know what was the last state of that variable (even if I played it 2 minutes ago) and then when it goes to the HandleMIDI section, it will execute one action or the other. Is this what's happening?

Link to comment
Share on other sites

there is no running midi buffer you can look at. The HandleMIDI function can only see the current event passed in to it. If you need to keep track of what has been played in the past you have to track that yourself.

 

@fuzzfilth is just trying to keep it simple in this case, a good idea, instead of trying to keep track of the previous notes played, he is jus keeping a variable as a toggle to keep track of which one was the last one...its either true or false (one or the other), and your code inside HandleMIDI has to be in charge of flipping that toggle back and forth and doing the correct thing each time depending on its current value.

Link to comment
Share on other sites

there is no running midi buffer you can look at. The HandleMIDI function can only see the current event passed in to it. If you need to keep track of what has been played in the past you have to track that yourself.

 

@fuzzfilth is just trying to keep it simple in this case, a good idea, instead of trying to keep track of the previous notes played, he is jus keeping a variable as a toggle to keep track of which one was the last one...its either true or false (one or the other), and your code inside HandleMIDI has to be in charge of flipping that toggle back and forth and doing the correct thing each time depending on its current value.

 

What I meant is that the Scripter had the "buffer" (or some kind of memory) built in, otherwise how would it know if the variable was true or false if I play one note now and the other one 30 seconds later? On the first passage it checks the variable, and runs action A. The next time I hit that same note, the Scripter's "buffer/memory" will know that the variable is no longer what it was when I first played it, so now it runs action B. Right?

I'm just trying to understand what's happening with the script so I can understand the steps.

 

Would it be this, then?

Running the script, I get no errors and I followed the instructions on fuzzfilth's raw "code"

var Round = false  // you prepare the trap, it's not armed yet 

function HandleMIDI(event) // fetch the next MIDI event
{
   if (event instanceof Note == 40) { // it's a rimshot !
       if (Round == false) { // trap is not armed
           Round = true
           }
       } // trap is armed now!
       
       else { // trap was already armed and is triggered!
           event.pitch = 32 // change the event to the other note
           new NoteOff (32); //and wait a few milliseconds before sending it  // since the original Note Off is still looking for E1
           Round = false // disarm the trap
       }

   event.send(); // play the event
   event.trace(); // display the event in the console
}

Link to comment
Share on other sites

something like this is how I would do it....

 

var toggle = false;
var pitch1 = MIDI.noteNumber("E1");
var pitch2 = MIDI.noteNumber("G#0");

function HandleMIDI(event) {

   if(event instanceof NoteOn && event.pitch == pitch1) {
       event.pitch = getPitch(event);
   }
   else if (event instanceof NoteOff && event.pitch == pitch1) {
       event.send();
       event.pitch = pitch2;
   }

   event.send();
}

function getPitch(event) {
   if(toggle == true) {
       toggle = false;
       return pitch2;
   }
   else {
       toggle = true;
       return pitch1;
   }
}
Link to comment
Share on other sites

something like this is how I would do it....

 

var toggle = false;
var pitch1 = MIDI.noteNumber("E1");
var pitch2 = MIDI.noteNumber("G#0");

function HandleMIDI(event) {

   if(event instanceof NoteOn && event.pitch == pitch1) {
       event.pitch = getPitch(event);
   }
   else if (event instanceof NoteOff && event.pitch == pitch1) {
       event.send();
       event.pitch = pitch2;
   }

   event.send();
}

function getPitch(event) {
   if(toggle == true) {
       toggle = false;
       return pitch2;
   }
   else {
       toggle = true;
       return pitch1;
   }
}

 

 

Oh wow, that's waaayyyy different from what I had in mind and way more complex for my super basic skills...

I will look a it and see if I understand the logic behind it.

I will also save this script as a way to maybe learn a few more things I haven't learned yet.

 

Thank you so much for the code. I tried it and it's working. I will see if I can merge with the other code I already have. :)

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...