On NoteEvent(m : NoteMessage) // I.e, respond to BOTH Note On and NoteOff
NoteTracker_GotNote (nt, m) // This will now keep track properly
Print(nt) // Printing this object currently just returns the count - it's really only intended for debugging
End
I am trying to capture a 3 or 4 note chord using NoteTracker with Scriptlet, but it isn’t working! Obviously, I would eventually like to do something to the notes captured on the NoteOnEvent but I can’t get the code to distinguish between a played 3 note chord and a played 4 note chord. Any help plz?
I think you started to learn GPScript trying to do things that are still too complicated for you. Could you first try to write a function which creates a string containing the notes of a NoteTracker? It is both a good exercise and something you will need for debugging, as printing this string will display the content of a NoteTracker.
I could easily convert note values to string values by indexing into a parallel string array with a note value.
Isn’t there a function that will put all notes played into an array?
It seems that my program as written only captures one note at a time and I need to capture all the notes played. Otherwise, it detects a 3 note chord before I get to a 4 note chord.
I did find some interesting functions that I intend to use once I get across my basic obstacle:
How exactly would you distinguish these….remember that there is no concept of a chord in the MIDI world….remember that you’re running in real time so you can’t really wait to see if any more notes are coming.
Var
nt : NoteTracker;
notifyChord : Boolean = false;
timelapse : double = TimeSinceStartup();
// adjust this delay if necessary
analysisDelay : double = 10.0;
Initialization
SetTimersRunning(true);
End
Function DS_NoteTracker_GetStringOfNotes(nt : NoteTracker) Returns string
Var
i : Integer;
nt_heldNotes : Integer Array = nt.NoteTracker_GetHeldNotes();
stringOfNotes : string = "";
For i=0; i<nt_heldNotes.Size(); i=i+1 Do
stringOfNotes = stringOfNotes+NoteNumberToNoteName(nt_heldNotes[i])+"("+nt.NoteTracker_GetSpecificNoteOnCount(nt_heldNotes[i])+") - ";
End
result = stringOfNotes;
End
On NoteEvent(m : NoteMessage)
SendNow(m);
nt.NoteTracker_GotNote(m);
Print("Number of different notes played : "+nt.NoteTracker_NoteOnCount() );
Print(nt.DS_NoteTracker_GetStringOfNotes());
Print("");
If nt.NoteTracker_NoteOnCount() >= 3
Then
timelapse = TimeSinceStartup()+analysisDelay;
notifyChord = true;
Else
notifyChord = false;
End
End
On TimerTick(ms : double)
If notifyChord && nt.NoteTracker_NoteOnCount() >= 3 && ms > timelapse
Then
Print("");
Print("*** "+nt.NoteTracker_NoteOnCount()+"-notes chord playing ***");
Print("");
notifyChord = false;
End
End
“RealTime” Exactly! This is my problem!. … but looking further ahead it appears that @David-san may have solved this difficult problem. It really looks pretty good. I will check it out this evening.
Your code looks like it is right on the money - especially by introducing the time element! You may have very well solved one of the seemingly impossible problems! The reason that I was struggling with this effort was because as Dhj had denoted, “MIDI is realtime” … so you have access to only one MIDI event at a time and therefore you don’t see multiple MIDI notes in one single event.
Now, that you may have solved this problem, the sky is the limit for me to code → EG: Here is a list of related projects that I intend to implement using Scriptlets:
1) Change boring closed voiced chords to open piano voiced chords. The is mainly directed to MIDI Accordion players that are currently restricted to the left hand chords they play. Since you have introduced a time element that I will use, I will be able to allow them to play 9th, 11th, 13th and poly chords. I already know the algorithms to detect the root note of a chord, so I can do all kinds of magical tricks. MIDI Accordionists can play to chord notes simultaneously, however if they play for instance a CM and BbM simultaneously, the sound would be very cacaphonous. However, I will be able to catch this scenario in the Sciptlet and adjust the BbM up one octave thus creating a C11th. Voila!
2) Setting up various guitar arpeggios specified by widgets. Piece of cake.
3) Incorporate jazz harmoinc modes triggered again by widgets. Again, I know how to do this based on teachings by Dave Brubeck and Kent Hewitt.
4) Take played notes in a chord and spread them over various MIDI channels EG: Create a more true sounding brass section. Then of course randomize this based on velocity.
5) Trigger notes based on zone and then also on velocity to do various things as specified by widgets
6) Create an ultra-realistic banjo effect and as well as the perfect harp effect. My friend Ray Cavicchio had done this in 1980 with his invention the Cavichord. No one has ever come close to this. I know the algorithms and I will implement them with GPSCript.
Once I get going there will be no stopping me. LOL! Thank you GPscript and the GP community
Phil, please don’t be upset.
I really don’t think, @David-san wanted to offend you in any way - he wrote his line with a and he is a very friendly and helpful guy.
I guess, most probably this phrase “to be afraid of the sky falling on our heads” is a quote from a comics series called “Asterix the Gaul” which is very poular in France (where David comes from) and also in Germany (where i come from). The stories are about a tribe of Gauls which are smart, strong and mostly fearless - except from one thing: the sky could fall on their heads.
…at least this is what first came to my mind when i read it.
Humor can become difficult when there is no common basis for a jestery… and this is even more difficult for internet conversations when you can’t read the face expression of your conversation partner or hear them chuckle.
It was really genius of you introducing the element of time to solve this linear-realtime problem. It really opens up a lot of doors for GPScripters wanting to pursue advanced MIDI-related scripts. Your technique should be added as an intrinsic GPscript function.
Not sure exactly what you want built in? I just tried that scriptlet and as far as I can tell, it’s detecting how many notes are being held down (using the Note Tracker) - I’m not sure what the time checking is supposed to do - for example, if I press a C, wait two seconds, then add an E, wait two seconds and then add a G - it detects that’s a chord — but that isn’t really a chord — those three notes would have all needed to have been played within the threshold time to be recognized as a chord.