Danny Wyatt Posted February 17, 2022 Share Posted February 17, 2022 UPDATE: Solution is here: viewtopic.php?f=45&t=162733#p853970 --- What should I be looking into if I want to have a note, for example E1, trigger E1 first and then the second time it triggers G#0, then third time goes back to E1, then G#0 and so on. Quote Link to comment Share on other sites More sharing options...
fuzzfilth Posted February 17, 2022 Share Posted February 17, 2022 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. Quote Link to comment Share on other sites More sharing options...
Danny Wyatt Posted February 17, 2022 Author Share Posted February 17, 2022 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? Quote Link to comment Share on other sites More sharing options...
fuzzfilth Posted February 17, 2022 Share Posted February 17, 2022 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. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted February 17, 2022 Share Posted February 17, 2022 Probably in this case, its easier and ok to just send both NoteOff's every time. Its a percussion instrument without any sustains. Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted February 17, 2022 Share Posted February 17, 2022 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. Quote Link to comment Share on other sites More sharing options...
Danny Wyatt Posted February 17, 2022 Author Share Posted February 17, 2022 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? Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted February 17, 2022 Share Posted February 17, 2022 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. Quote Link to comment Share on other sites More sharing options...
Danny Wyatt Posted February 17, 2022 Author Share Posted February 17, 2022 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 } Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted February 17, 2022 Share Posted February 17, 2022 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; } } Quote Link to comment Share on other sites More sharing options...
Danny Wyatt Posted February 17, 2022 Author Share Posted February 17, 2022 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. 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.